[parted-devel] fix another memory overrun bug (this time in
linux_write)
Jim Meyering
jim at meyering.net
Thu Mar 15 23:42:06 CET 2007
Here's an untested fix for libparted/arch/linux.c's linux_write.
The problem arises when writing with a logical sector size larger
than 512 (PED_SECTOR_SIZE_DEFAULT). It would allocate space
for count * PED_SECTOR_SIZE_DEFAULT bytes, and copy that many
bytes into the just-allocated buffer, but writing
"count * dev->sector_size" bytes from the same buffer would
use 1.5KB of uninitialized memory when sector_size is 2048.
Another problem: if there were ever to be a partial write,
the while(1) loop termination test would never become true.
Finally, to be a little cleaner, use ssize_t as the type
of the variable getting the write return val.
From: Jim Meyering <jim at meyering.net>
---
libparted/arch/linux.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 312cc8c..8769dd6 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -1533,9 +1533,7 @@ linux_write (PedDevice* dev, const void* buffer, PedSector start,
PedSector count)
{
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
- int status;
PedExceptionOption ex_status;
- size_t write_length = count * dev->sector_size;
void* diobuf;
void* diobuf_start;
@@ -1593,15 +1591,15 @@ linux_write (PedDevice* dev, const void* buffer, PedSector start,
printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
dev->path, buffer, (int) start, (int) count);
#else
+ size_t write_length = count * dev->sector_size;
dev->dirty = 1;
- if (posix_memalign(&diobuf, PED_SECTOR_SIZE_DEFAULT,
- count * PED_SECTOR_SIZE_DEFAULT) != 0)
+ if (posix_memalign(&diobuf, dev->sector_size, write_length) != 0)
return 0;
- memcpy(diobuf, buffer, count * PED_SECTOR_SIZE_DEFAULT);
+ memcpy(diobuf, buffer, write_length);
diobuf_start = diobuf;
while (1) {
- status = write (arch_specific->fd, diobuf, write_length);
- if (status == count * dev->sector_size) break;
+ ssize_t status = write (arch_specific->fd, diobuf, write_length);
+ if (status == write_length) break;
if (status > 0) {
write_length -= status;
diobuf = (char *) diobuf + status;
More information about the parted-devel
mailing list