bug-parted
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] pc98: avoid segfault with simulated large sectors


From: Jim Meyering
Subject: [PATCH 2/2] pc98: avoid segfault with simulated large sectors
Date: Mon, 07 Dec 2009 21:13:16 +0100

While exercising a new interface, a known problem
(the pc98 partition table type not >512-byte-sector ready)
caused a new test to fail, so I've fixed one of the failing
parts of pc98 support:

>From 1e8c1c6cf8b4b2616405b7ee42d036a30126387a Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Mon, 7 Dec 2009 20:27:21 +0100
Subject: [PATCH 1/2] libparted: ptt_read_sectors: new function

* libparted/labels/pt-tools.c (ptt_read_sectors): New function.
(ptt_read_sector): Rewrite to use it.
* libparted/labels/pt-tools.h: Declare it.
---
 libparted/labels/pt-tools.c |   23 +++++++++++++++++------
 libparted/labels/pt-tools.h |    2 ++
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/libparted/labels/pt-tools.c b/libparted/labels/pt-tools.c
index 8afec77..7325f65 100644
--- a/libparted/labels/pt-tools.c
+++ b/libparted/labels/pt-tools.c
@@ -56,15 +56,17 @@ ptt_write_sector (PedDisk const *disk, void const *buf, 
size_t buflen)
   return write_ok;
 }

-/* Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
-   storage.  If the read fails, free the memory and return zero without
-   modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
+/* Read N sectors, starting with sector SECTOR_NUM (which has length
+   DEV->sector_size) into malloc'd storage.  If the read fails, free
+   the memory and return zero without modifying *BUF.  Otherwise, set
+   *BUF to the new buffer and return 1.  */
 int
-ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf)
+ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
+                 PedSector n_sectors, void **buf)
 {
-  char *b = ped_malloc (dev->sector_size);
+  char *b = ped_malloc (n_sectors * dev->sector_size);
   PED_ASSERT (b != NULL, return 0);
-  if (!ped_device_read (dev, b, sector_num, 1)) {
+  if (!ped_device_read (dev, b, start_sector, n_sectors)) {
     free (b);
     return 0;
   }
@@ -72,6 +74,15 @@ ptt_read_sector (PedDevice const *dev, PedSector sector_num, 
void **buf)
   return 1;
 }

+/* Read sector, SECTOR_NUM (which has length DEV->sector_size) into malloc'd
+   storage.  If the read fails, free the memory and return zero without
+   modifying *BUF.  Otherwise, set *BUF to the new buffer and return 1.  */
+int
+ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf)
+{
+  return ptt_read_sectors (dev, sector_num, 1, buf);
+}
+
 /* Zero N sectors of DEV, starting with START.
    Return nonzero to indicate success, zero otherwise.  */
 int
diff --git a/libparted/labels/pt-tools.h b/libparted/labels/pt-tools.h
index 2987135..3f275d0 100644
--- a/libparted/labels/pt-tools.h
+++ b/libparted/labels/pt-tools.h
@@ -19,6 +19,8 @@

 int ptt_write_sector (PedDisk const *disk, void const *buf, size_t buflen);
 int ptt_read_sector (PedDevice const *dev, PedSector sector_num, void **buf);
+int ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
+                     PedSector n_sectors, void **buf);
 int ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector count);
 int ptt_partition_max_start_len (char const *label_type,
                 const PedPartition *part);
--
1.6.6.rc0.285.g73651


>From 0b2cc7d394e4e55aa64fdb640acb743a446fe202 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Mon, 7 Dec 2009 19:10:41 +0100
Subject: [PATCH 2/2] pc98: avoid segfault with simulated large sectors

The pc98 partition table is by no means ready for >512-byte sectors,
but at least it now gets past mklabel.  E.g., this usage no longer
provokes double-free and read-uninitialized errors:
dd if=/dev/zero of=F bs=512 count=1 seek=10000
PARTED_SECTOR_SIZE=4096 valgrind ../parted/parted -s F mklabel pc98
* libparted/labels/pc98.c (pc98_write): Rewrite to avoid
invalid access with >512-byte sectors.
---
 libparted/labels/pc98.c |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/libparted/labels/pc98.c b/libparted/labels/pc98.c
index 4a8bcd4..51f1b11 100644
--- a/libparted/labels/pc98.c
+++ b/libparted/labels/pc98.c
@@ -501,34 +501,37 @@ fill_raw_part (PC98RawPartition* raw_part, const 
PedPartition* part)
 static int
 pc98_write (const PedDisk* disk)
 {
-       PC98RawTable            table;
        PedPartition*           part;
        int                     i;

        PED_ASSERT (disk != NULL, return 0);
        PED_ASSERT (disk->dev != NULL, return 0);

-       if (!ped_device_read (disk->dev, &table, 0, 2))
+       void *s0;
+       if (!ptt_read_sectors (disk->dev, 0, 2, &s0))
                return 0;
+       PC98RawTable *table = s0;

-       if (!pc98_check_ipl_signature (&table)) {
-               memset (table.boot_code, 0, sizeof(table.boot_code));
-               memcpy (table.boot_code, MBR_BOOT_CODE, sizeof(MBR_BOOT_CODE));
+       if (!pc98_check_ipl_signature (table)) {
+               memset (table->boot_code, 0, sizeof(table->boot_code));
+               memcpy (table->boot_code, MBR_BOOT_CODE, sizeof(MBR_BOOT_CODE));
        }

-       memset (table.partitions, 0, sizeof (table.partitions));
-       table.magic = PED_CPU_TO_LE16(PC9800_EXTFMT_MAGIC);
+       memset (table->partitions, 0, sizeof (table->partitions));
+       table->magic = PED_CPU_TO_LE16(PC9800_EXTFMT_MAGIC);

        for (i = 1; i <= MAX_PART_COUNT; i++) {
                part = ped_disk_get_partition (disk, i);
                if (!part)
                        continue;

-               if (!fill_raw_part (&table.partitions [i - 1], part))
+               if (!fill_raw_part (&table->partitions [i - 1], part))
                        return 0;
        }

-       if (!ped_device_write (disk->dev, (void*) &table, 0, 2))
+       int write_ok = ped_device_write (disk->dev, table, 0, 2);
+       free (s0);
+       if (!write_ok)
                return 0;
        return ped_device_sync (disk->dev);
 }
--
1.6.6.rc0.285.g73651




reply via email to

[Prev in Thread] Current Thread [Next in Thread]