From 6c7932b90a9d078ffaf8ec9482b272c67d75a01d Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Tue, 4 Sep 2012 16:42:34 -0700 Subject: [PATCH 27/89] mac: don't let larger partition-table-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.8.5.3