mirror of https://github.com/wolfSSL/wolfBoot.git
F-4714: compute GPT header offset in 64 bits to prevent uint32_t overflow
The protective-MBR lba_first field (attacker-controlled uint32_t, no range check) was multiplied by GPT_SECTOR_SIZE (int 512) in disk_open. C's usual arithmetic conversions made the product a 32-bit unsigned, which wraps for gpt_lba >= 0x800000 (512 * 0x800001 -> 0x200), silently redirecting the GPT header read back to LBA 1 instead of the out-of-range LBA named. Cast the constant to uint64_t so the byte offset is computed in 64 bits. Add a unit test that points lba_first at an overflowing LBA and confirms disk_open now rejects it.pull/792/head
parent
e0f271bfd5
commit
93a8fe8d5a
|
|
@ -149,7 +149,8 @@ int disk_open(int drv)
|
|||
wolfBoot_printf("Found GPT PTE at sector %u\r\n", gpt_lba);
|
||||
|
||||
/* Read GPT header */
|
||||
r = disk_read(drv, GPT_SECTOR_SIZE * gpt_lba, GPT_SECTOR_SIZE, sector);
|
||||
r = disk_read(drv, (uint64_t)GPT_SECTOR_SIZE * gpt_lba, GPT_SECTOR_SIZE,
|
||||
sector);
|
||||
if (r < 0) {
|
||||
wolfBoot_printf("Disk read failed\r\n");
|
||||
Drives[drv].is_open = 0;
|
||||
|
|
|
|||
|
|
@ -653,6 +653,31 @@ START_TEST(test_disk_open_gpt_rejects_huge_part_array)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_disk_open_gpt_lba_no_overflow)
|
||||
{
|
||||
/* The protective-MBR lba_first is an attacker-controlled uint32_t. The
|
||||
* GPT-header byte offset must be computed in 64 bits. If it is computed
|
||||
* as the 32-bit product GPT_SECTOR_SIZE * gpt_lba, it wraps for
|
||||
* gpt_lba >= 0x800000: 512 * 0x800001 wraps to 0x200, silently
|
||||
* redirecting the read back to LBA 1 (the real GPT header) instead of
|
||||
* the out-of-range LBA the field actually names. */
|
||||
struct gpt_mbr_part_entry *mbr_entry;
|
||||
|
||||
build_gpt_disk();
|
||||
|
||||
/* Point the protective entry at an LBA whose 512* product overflows a
|
||||
* 32-bit unsigned back to 0x200 (LBA 1). */
|
||||
mbr_entry = (struct gpt_mbr_part_entry *)(fake_disk + GPT_MBR_ENTRY_START);
|
||||
mbr_entry->lba_first = 0x800001;
|
||||
|
||||
/* With correct 64-bit arithmetic the header read targets byte
|
||||
* 0x100000200, far past the fake disk, so disk_open must fail rather
|
||||
* than wrap to LBA 1 and accept the table. */
|
||||
ck_assert_int_eq(disk_open(0), -1);
|
||||
ck_assert_int_eq(Drives[0].is_open, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_disk_open_gpt_empty_entry_mid_table)
|
||||
{
|
||||
/* GPT header says 3 partitions but entry[1] has zeroed type GUID.
|
||||
|
|
@ -990,6 +1015,7 @@ Suite *wolfboot_suite(void)
|
|||
tcase_add_test(tc_cov, test_disk_open_gpt_excess_partitions);
|
||||
tcase_add_test(tc_cov, test_disk_open_gpt_large_array_sz);
|
||||
tcase_add_test(tc_cov, test_disk_open_gpt_rejects_huge_part_array);
|
||||
tcase_add_test(tc_cov, test_disk_open_gpt_lba_no_overflow);
|
||||
tcase_add_test(tc_cov, test_disk_open_gpt_empty_entry_mid_table);
|
||||
tcase_add_test(tc_cov, test_disk_open_mbr_zero_lba_entry);
|
||||
tcase_add_test(tc_cov, test_open_part_invalid_drive);
|
||||
|
|
|
|||
Loading…
Reference in New Issue