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 <meyer...@redhat.com> 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 <meyer...@redhat.com> 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 _______________________________________________ bug-parted mailing list bug-parted@gnu.org http://lists.gnu.org/mailman/listinfo/bug-parted