Package: libfdisk1
Version: 2.41-5
Control: affects -1 fdisk

Dear maintainer,

In libfdisk/src/gpt.c, gpt_calculate_first_lba() and gpt_calculate_last_lba() do not use the actual partition entry LBA from the primary and backup GPT headers). Instead, they assume the default locations. They are called by fdisk_gpt_set_npartitions() which is called by fdisk when the user selects "change table length" in expert commands.

As a consequence, changing the GPT partition table length when the primary and/or backup partition entries are not at the default locations results in wrong first and last usable LBAs being written to the GPT header.

I also observed that fdisk does not check if the first and last usable LBA are after the primary partition entries and before the backup partition entries and allows to create partitions which overlap with them, causing possible data loss.

Steps to reproduce:

1) Create a standard GPT partition table with any tool.
2) Move the primary and backup partition tables with sgdisk (from package gdisk):

# sgdisk -j 1000 -k 41942000 /dev/vdb

3) Check the partition table layout:

# fdisk -x /dev/vdb
Disk /dev/vdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 8F5B80CB-02BF-4F48-A7B8-C30A2DE3B68A
First usable LBA: 1032
Last usable LBA: 41941999
Alternative LBA: 41943039
Partition entries starting LBA: 1000
Allocated partition entries: 128
Partition entries ending LBA: 1031

We can see that the first and last usable LBAs have been moved along with the partition tables, as expected.

4) Change the table length with fdisk:
# fdisk /dev/vdb
x
l
100
r
w

5) Check the partition table layout:
# fdisk -x /dev/vdb
Disk /dev/vdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 8F5B80CB-02BF-4F48-A7B8-C30A2DE3B68A
First usable LBA: 27
Last usable LBA: 41943013
Alternative LBA: 41943039
Partition entries starting LBA: 1000
Allocated partition entries: 100
Partition entries ending LBA: 1024

We can see that the first and last usable LBAs have unexpectedly been "reset" as if the partition entries were at the default locations and fdisk did not complain when reading the inconsistent GPT header.

6) Create a partition using the entire "available" space:
# fdisk -x /dev/vdb
n
Partition number (1-100, default 1): 1
First sector (27-41943013, default 2048): 27
Last sector (27-41943013, default 41940991): 41943013
w

7) Check the partition table layout:
# fdisk -x /dev/vdb
Disk /dev/vdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 8F5B80CB-02BF-4F48-A7B8-C30A2DE3B68A
First usable LBA: 27
Last usable LBA: 41943013
Alternative LBA: 41943039
Partition entries starting LBA: 1000
Allocated partition entries: 100
Partition entries ending LBA: 1024

Device     Start      End  Sectors Type-UUID   UUID        Name Attrs
/dev/vdb1     27 41943013 41942987 0FC63DAF... 1650489F...

We can see that fdisk allowed to create a partition overlapping the partition tables.

Reply via email to