]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: fix use of on-disk sizeof_partition_entry in GPT
authorKarel Zak <kzak@redhat.com>
Tue, 26 May 2026 14:16:03 +0000 (16:16 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 26 May 2026 14:16:03 +0000 (16:16 +0200)
The GPT code hardcodes sizeof(struct gpt_entry) (128 bytes) in
several places instead of using the on-disk sizeof_partition_entry
field from the GPT header. The UEFI specification allows entry sizes
larger than 128 bytes.

 - reject GPT headers where sizeof_partition_entry is smaller than
   sizeof(struct gpt_entry) to prevent out-of-bounds reads when
   accessing entry array elements

 - use the on-disk entry size as the qsort element stride in
   gpt_reorder() to avoid corrupting entries when sizeof_partition_entry
   differs from 128

 - use the on-disk entry size in gpt_copy_header() when calculating
   the backup partition entry array LBA

Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/src/gpt.c

index ee6e206c35d0cd66d1535ceaeadd30be3036aa19..b985f087a640d514f68135358a89f85adc28091e 100644 (file)
@@ -710,7 +710,8 @@ static struct gpt_header *gpt_copy_header(struct fdisk_context *cxt,
        if (res->my_lba == GPT_PRIMARY_PARTITION_TABLE_LBA)
                res->partition_entry_lba = cpu_to_le64(2ULL);
        else {
-               uint64_t esz = (uint64_t) le32_to_cpu(src->npartition_entries) * sizeof(struct gpt_entry);
+               uint64_t esz = (uint64_t) le32_to_cpu(src->npartition_entries)
+                               * le32_to_cpu(src->sizeof_partition_entry);
                uint64_t esects = (esz + cxt->sector_size - 1) / cxt->sector_size;
 
                res->partition_entry_lba = cpu_to_le64(cxt->total_sectors - 1ULL - esects);
@@ -1197,6 +1198,10 @@ static struct gpt_header *gpt_read_header(struct fdisk_context *cxt,
        if (!gpt_check_header_crc(header, NULL))
                goto invalid;
 
+       /* entry size must be large enough to hold struct gpt_entry */
+       if (le32_to_cpu(header->sizeof_partition_entry) < sizeof(struct gpt_entry))
+               goto invalid;
+
        /* read and verify entries */
        ents = gpt_read_entries(cxt, header);
        if (!ents)
@@ -3187,7 +3192,8 @@ static int gpt_reorder(struct fdisk_context *cxt)
        if (!mess)
                return 1;
 
-       qsort(gpt->ents, nparts, sizeof(struct gpt_entry),
+       qsort(gpt->ents, nparts,
+                       le32_to_cpu(gpt->pheader->sizeof_partition_entry),
                        gpt_entry_cmp_start);
 
        gpt_recompute_crc(gpt->pheader, gpt->ents);