[PATCH] block: partitions: reject GPT entries with starting_lba > ending_lba

From: Zizhi Wo

Date: Mon Nov 02 2026 - 03:17:11 EST


From: Zizhi Wo <wozizhi@xxxxxxxxxx>

A GPT entry whose starting_lba is greater than its ending_lba is accepted,
and the kernel creates a partition with a bogus size. The bogus sector
count defeats the end-of-device check, so I/O through that partition is not
confined to it and can access sectors outside the partition on the same
disk.

is_pte_valid() only rejects an entry when its type is NULL or when
starting_lba or ending_lba is greater than lastlba; it never checks that
starting_lba <= ending_lba. For a reversed entry both field checks still
pass, but efi_partition() computes size = ending_lba - starting_lba + 1 in
u64, which underflows to a huge value. That value also wraps in the
end-of-device check in blk_add_partition() (from + size) and does not fit
the signed i_size, which turns negative.

Reject entries with starting_lba > ending_lba in is_pte_valid(), matching
the head-level check against last_usable_lba < first_usable_lba.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Zizhi Wo <wozizhi@xxxxxxxxxx>
---
block/partitions/efi.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 9865d59093fa..b31227a13db0 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -458,10 +458,11 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
*/
static inline int
is_pte_valid(const gpt_entry *pte, const u64 lastlba)
{
if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
+ le64_to_cpu(pte->starting_lba) > le64_to_cpu(pte->ending_lba) ||
le64_to_cpu(pte->starting_lba) > lastlba ||
le64_to_cpu(pte->ending_lba) > lastlba)
return 0;
return 1;
}
--
2.52.0