FYI, testing with valgrind yesterday, I found a minor problem. Definitely minor, since first few people use GPT with other than the default of a 128-PTE array. Second, of those few who do, even fewer run parted on an image for which the backup header is not in its expected location at the end of the device.
Here's the fix: >From 905811b14ae10a0d292b9da58469ff788e1cdd73 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Mon, 6 Feb 2012 15:00:53 +0100 Subject: [PATCH 1/2] libparted: gpt: avoid heap-read-overrun when rewriting 9-PTE table Now that parted can rewrite a corrupt-or-misaligned 9-PTE table, we have to be careful to allocate space for slightly more data when the byte-count required for a PTE table is smaller than the whole number of sectors would imply. I.e., when the PTE table size is not a multiple of the sector size, there is a fraction of that final sector for which we do not read data, but we do write. Ensure we have space for the buffer we'll write and that it is initialized (to 0's). * libparted/labels/gpt.c (gpt_write): Allocate the right amount of space. Use calloc, not malloc+memset. --- libparted/labels/gpt.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c index 4a5d357..84bdc12 100644 --- a/libparted/labels/gpt.c +++ b/libparted/labels/gpt.c @@ -1219,10 +1219,13 @@ gpt_write (const PedDisk *disk) size_t ptes_bytes = (gpt_disk_data->entry_count * sizeof (GuidPartitionEntry_t)); - GuidPartitionEntry_t *ptes = malloc (ptes_bytes); + size_t ss = disk->dev->sector_size; + PedSector ptes_sectors = (ptes_bytes + ss - 1) / ss; + /* Note that we allocate a little more than ptes_bytes, + when that number is not a multiple of sector size. */ + GuidPartitionEntry_t *ptes = calloc (ptes_sectors, ss); if (!ptes) goto error; - memset (ptes, 0, ptes_bytes); for (part = ped_disk_next_partition (disk, NULL); part; part = ped_disk_next_partition (disk, part)) { @@ -1249,8 +1252,6 @@ gpt_write (const PedDisk *disk) free (pth_raw); if (!write_ok) goto error_free_ptes; - size_t ss = disk->dev->sector_size; - PedSector ptes_sectors = (ptes_bytes + ss - 1) / ss; if (!ped_device_write (disk->dev, ptes, 2, ptes_sectors)) goto error_free_ptes; -- 1.7.9.112.gb85f2 >From 4fa3a6b22cece434126953cb8d686359a9416cef Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Mon, 6 Feb 2012 15:02:12 +0100 Subject: [PATCH 2/2] tests: set PARTED_TEST_NAME, for valgrind * tests/Makefile.am (PARTED_TEST_NAME): Define. * tests/t0211-gpt-rewrite-header.sh: Clarify a comment. --- tests/Makefile.am | 1 + tests/t0211-gpt-rewrite-header.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index a7a1633..917ebe7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -107,6 +107,7 @@ TESTS_ENVIRONMENT = \ PACKAGE_VERSION=$(PACKAGE_VERSION) \ CONFIG_HEADER='$(abs_top_builddir)/lib/config.h' \ ENABLE_DEVICE_MAPPER=$(ENABLE_DEVICE_MAPPER) \ + PARTED_TEST_NAME=`basename '$(abs_srcdir)'`,`echo $$tst|sed 's,^\./,,;s,/,-,g'`\ PERL='$(PERL)' \ PREFERABLY_POSIX_SHELL='$(PREFERABLY_POSIX_SHELL)' \ REPLACE_GETCWD=$(REPLACE_GETCWD) \ diff --git a/tests/t0211-gpt-rewrite-header.sh b/tests/t0211-gpt-rewrite-header.sh index cfc9de6..85fe5a2 100644 --- a/tests/t0211-gpt-rewrite-header.sh +++ b/tests/t0211-gpt-rewrite-header.sh @@ -31,7 +31,7 @@ dev=loop-file # create a file large enough to hold a GPT partition table dd if=/dev/null of=$dev bs=$ss seek=$ns || framework_failure -# create a GPT partition table with 9 PTEs. +# create a GPT partition table with 9 partitions in a standard 128-entry table. parted -a min -s $dev mklabel gpt \ mkpart p1 34s 34s \ mkpart p2 35s 35s \ -- 1.7.9.112.gb85f2