]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: Space before first partition may not be aligned
authorEvan Green <evangreen86@gmail.com>
Tue, 12 Nov 2019 22:17:37 +0000 (14:17 -0800)
committerEvan Green <evangreen86@gmail.com>
Tue, 12 Nov 2019 22:38:26 +0000 (14:38 -0800)
libfdisk chooses a grain of 1MB fairly arbitrarily, and this granule
may not be honored by other utilities. GPT disks formatted elsewhere
may have space before the first partition, AND a partition that exists
solely below 1MB. If this occurs, cfdisk ends up adding a free space
region where end < start, resulting in a 16 Exabyte free region.

That's too many exabytes.

This happens because the start gets rounded up to the granule size in
new_freespace() but the end is left alone. The logs show it best:

23274: libfdisk:      CXT: [0x572d878]: initialized:  last=34, grain=2048
23274: libfdisk:      CXT: [0x572d878]: partno=10, start=64
23274: libfdisk:      CXT: [0x572d878]: freespace analyze: partno=10, start=64, end=64
23274: libfdisk:      CXT: [0x572d878]: LBA           34 aligned-up           2048 [grain=2048s]
23274: libfdisk:      CXT: [0x572d878]: LBA           63 aligned-down            0 [grain=2048s]
23274: libfdisk:      CXT: [0x572d878]: LBA           34 aligned-near            0 [grain=2048s]
23274: libfdisk:      CXT: [0x572d878]: 0 in range <2048..0> aligned to 2048
23274: libfdisk:     PART: [0x574bb98]: alloc
23274: libfdisk:      TAB: [0x5749d58]: adding freespace
23274: libfdisk:      TAB: [0x5749d58]: insert entry 0x574bb98 pre=0x574a820 [start=2048, end=63, size=18446744073709549632, freespace  ]

Avoid this by aligning the last value like new_freespace() does.

Signed-off-by: Evan Green <evangreen86@gmail.com>
libfdisk/src/table.c

index e78ecc4372756450728a4e9fc54867e1cf574fd2..b814a1f4cb3b4d4c6f9074158c87752790109ce7 100644 (file)
@@ -624,10 +624,12 @@ int fdisk_get_freespaces(struct fdisk_context *cxt, struct fdisk_table **tb)
                                        (uintmax_t) fdisk_partition_get_end(pa)));
 
                /* We ignore small free spaces (smaller than grain) to keep partitions
-                * aligned, the exception is space before the first partition where
-                * we assume that cxt->first_lba is aligned. */
+                * aligned, the exception is space before the first partition when
+                * cxt->first_lba is aligned. */
                if (last + grain < pa->start
-                   || (last < pa->start && nparts == 0)) {
+                   || (nparts == 0 &&
+                       (fdisk_align_lba(cxt, last, FDISK_ALIGN_UP) <
+                        pa->start))) {
                        rc = table_add_freespace(cxt, *tb,
                                last + (nparts == 0 ? 0 : 1),
                                pa->start - 1, NULL);