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.