summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlden Tondettar <alden.tondettar@gmail.com>2017-01-15 17:31:56 -0500
committerJens Axboe <axboe@fb.com>2017-01-17 11:02:31 -0500
commitc5082b70adfe8e1ea1cf4a8eff92c9f260e364d2 (patch)
tree2cc8bab578b10b57837d87d9ec274aa19af7b2a3
parent1e668f4e7921e8c82838cf5f95ff4a2d5c852efc (diff)
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 <alden.tondettar@gmail.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/partitions/efi.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index bcd86e5cd546..39f70d968754 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state,
293 if (!gpt) 293 if (!gpt)
294 return NULL; 294 return NULL;
295 295
296 count = le32_to_cpu(gpt->num_partition_entries) * 296 count = (size_t)le32_to_cpu(gpt->num_partition_entries) *
297 le32_to_cpu(gpt->sizeof_partition_entry); 297 le32_to_cpu(gpt->sizeof_partition_entry);
298 if (!count) 298 if (!count)
299 return NULL; 299 return NULL;
@@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
352 gpt_header **gpt, gpt_entry **ptes) 352 gpt_header **gpt, gpt_entry **ptes)
353{ 353{
354 u32 crc, origcrc; 354 u32 crc, origcrc;
355 u64 lastlba; 355 u64 lastlba, pt_size;
356 356
357 if (!ptes) 357 if (!ptes)
358 return 0; 358 return 0;
@@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
434 goto fail; 434 goto fail;
435 } 435 }
436 436
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
437 if (!(*ptes = alloc_read_gpt_entries(state, *gpt))) 446 if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
438 goto fail; 447 goto fail;
439 448
440 /* Check the GUID Partition Entry Array CRC */ 449 /* Check the GUID Partition Entry Array CRC */
441 crc = efi_crc32((const unsigned char *) (*ptes), 450 crc = efi_crc32((const unsigned char *) (*ptes), pt_size);
442 le32_to_cpu((*gpt)->num_partition_entries) *
443 le32_to_cpu((*gpt)->sizeof_partition_entry));
444 451
445 if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) { 452 if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
446 pr_debug("GUID Partition Entry Array CRC check failed.\n"); 453 pr_debug("GUID Partition Entry Array CRC check failed.\n");