[parted-devel] [PATCH] libparted: reallocate buf after _disk_analyse_block_size call
Jim Meyering
jim at meyering.net
Tue Sep 11 17:01:02 UTC 2012
Jim Meyering wrote:
> Jim Meyering wrote:
> ...
>> Thanks for the added detail.
>> Would you please include something like that to the commit log
>> for your patch?
>>
>> Re testing, would it be enough to use parted to create a MAC partition
>> table with "mklabel mac", add at least one partition, and then use dd or
>
> BTW, I realized that we can probably reproduce it with no partition at all.
>
>> perl to poke a new, larger number into its 16-bit big-endian
>> raw_disk->block_size field ?
>
> I've gone ahead and adjusted your patch.
> Can you confirm that this still solves your problem
> and sign off on the modifications?
> I've also removed an unnecessary cast.
>
> I'll look at creating a test case tomorrow.
>
...
> + MacRawDisk *raw_disk = buf;
>
> if (!_check_signature (raw_disk))
> goto error;
>
> + /* Record the original sector size; this function may change it. */
> + PedSector ss0 = disk->dev->sector_size;
> if (!_disk_analyse_block_size (disk, raw_disk))
> goto error;
> + /* If _disk_analyse_block_size has increased the sector_size,
> + reallocate this buffer, so we can still read a sector into it. */
> + if (ss0 < disk->dev->sector_size) {
> + free (buf);
> + buf = ped_malloc (disk->dev->sector_size);
> + if (buf == NULL)
> + goto error;
> + }
In testing the above, I realized that the way I changed your
patch (in hoisting the reallocation) was invalid, since there
are uses of raw_disk (aliased to "buf") after the point where
my hoisted code freed buf. This one works better:
FTR, here's the basis for the test I'm using:
dev=dev-file
dd if=/dev/null of=$dev bs=1 seek=2MB
parted -s -- $dev mklabel mac
# Poke a big-endian 1024 into the 2-byte block_size slot.
perl -e 'print pack("S>", 1024)'|dd of=$dev bs=1 seek=2 count=2 conv=notrunc
parted $dev u s p
# Respond "i" (for ignore) to the first prompt.
# That would trigger the buffer overrun.
>From f77b6b002c92f62c8c0e8d502404bfd94983a81e Mon Sep 17 00:00:00 2001
From: "Brian C. Lane" <bcl at redhat.com>
Date: Tue, 4 Sep 2012 16:42:34 -0700
Subject: [PATCH] mac: don't let larger partition-specified block size evoke
UB
For example, in reading a MAC partition table on a 512-byte sector-size
disk, _disk_analyse_block_size could find reason to ask if it's ok to
increase that to e.g., 2048. Upon a positive reply, we would read 2048
bytes into a 512-byte buffer.
* libparted/labels/mac.c (mac_read): If needed, reallocate "buf"
to accommodate a new, larger sector size.
* NEWS (Bug fixes): Mention it.
---
NEWS | 7 +++++++
libparted/labels/mac.c | 14 +++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index f929b99..bab3afb 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,13 @@ GNU parted NEWS -*- outline -*-
** Bug Fixes
+ libparted: mac: a MAC partition table could have a block_size larger
+ than the one the kernel told us about. Upon reading that partition
+ table, libparted would ask if it's ok to use the larger block size.
+ If you were to respond in the affirmative, libparted would read the
+ larger number of bytes into a buffer of the shorter length,
+ overrunning it.
+
libparted: gpt: fix gpt_get_max_supported_partition_count to work
also on little-endian systems.
diff --git a/libparted/labels/mac.c b/libparted/labels/mac.c
index 1f59a1a..2485187 100644
--- a/libparted/labels/mac.c
+++ b/libparted/labels/mac.c
@@ -738,13 +738,16 @@ mac_read (PedDisk* disk)
if (!ptt_read_sector (disk->dev, 0, &buf))
return 0;
- MacRawDisk *raw_disk = (MacRawDisk *) buf;
+ MacRawDisk *raw_disk = buf;
if (!_check_signature (raw_disk))
goto error;
+ /* Record the original sector size; this function may change it. */
+ PedSector ss0 = disk->dev->sector_size;
if (!_disk_analyse_block_size (disk, raw_disk))
goto error;
+
if (!_disk_analyse_ghost_size (disk))
goto error;
ghost_size = mac_disk_data->ghost_size;
@@ -759,6 +762,15 @@ mac_read (PedDisk* disk)
mac_disk_data->block_size = raw_disk->block_size;
}
+ /* If _disk_analyse_block_size has increased the sector_size,
+ reallocate this buffer, so we can still read a sector into it. */
+ if (ss0 < disk->dev->sector_size) {
+ free (buf);
+ buf = ped_malloc (disk->dev->sector_size);
+ if (buf == NULL)
+ goto error;
+ }
+
for (num=1; num==1 || num <= last_part_entry_num; num++) {
void *raw_part = buf;
if (!ped_device_read (disk->dev, raw_part,
--
1.7.12.289.g0ce9864
More information about the parted-devel
mailing list