Skip to content

Commit c5082b7

Browse files
Alden Tondettaraxboe
authored andcommitted
partitions/efi: Fix integer overflow in GPT size calculation
If a GUID Partition Table claims to have more than 2**25 entries, the calculation of the partition table size in alloc_read_gpt_entries() will overflow a 32-bit integer and not enough space will be allocated for the table. Nothing seems to get written out of bounds, but later efi_partition() will read up to 32768 bytes from a 128 byte buffer, possibly OOPSing or exposing information to /proc/partitions and uevents. The problem exists on both 64-bit and 32-bit platforms. Fix the overflow and also print a meaningful debug message if the table size is too large. Signed-off-by: Alden Tondettar <[email protected]> Acked-by: Ard Biesheuvel <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 1e668f4 commit c5082b7

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

block/partitions/efi.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state,
293293
if (!gpt)
294294
return NULL;
295295

296-
count = le32_to_cpu(gpt->num_partition_entries) *
296+
count = (size_t)le32_to_cpu(gpt->num_partition_entries) *
297297
le32_to_cpu(gpt->sizeof_partition_entry);
298298
if (!count)
299299
return NULL;
@@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
352352
gpt_header **gpt, gpt_entry **ptes)
353353
{
354354
u32 crc, origcrc;
355-
u64 lastlba;
355+
u64 lastlba, pt_size;
356356

357357
if (!ptes)
358358
return 0;
@@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
434434
goto fail;
435435
}
436436

437+
/* Sanity check partition table size */
438+
pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) *
439+
le32_to_cpu((*gpt)->sizeof_partition_entry);
440+
if (pt_size > KMALLOC_MAX_SIZE) {
441+
pr_debug("GUID Partition Table is too large: %llu > %lu bytes\n",
442+
(unsigned long long)pt_size, KMALLOC_MAX_SIZE);
443+
goto fail;
444+
}
445+
437446
if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
438447
goto fail;
439448

440449
/* Check the GUID Partition Entry Array CRC */
441-
crc = efi_crc32((const unsigned char *) (*ptes),
442-
le32_to_cpu((*gpt)->num_partition_entries) *
443-
le32_to_cpu((*gpt)->sizeof_partition_entry));
450+
crc = efi_crc32((const unsigned char *) (*ptes), pt_size);
444451

445452
if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
446453
pr_debug("GUID Partition Entry Array CRC check failed.\n");

0 commit comments

Comments
 (0)