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>
This commit is contained in:
parent
1e668f4e79
commit
c5082b70ad
|
@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state,
|
||||||
if (!gpt)
|
if (!gpt)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
count = le32_to_cpu(gpt->num_partition_entries) *
|
count = (size_t)le32_to_cpu(gpt->num_partition_entries) *
|
||||||
le32_to_cpu(gpt->sizeof_partition_entry);
|
le32_to_cpu(gpt->sizeof_partition_entry);
|
||||||
if (!count)
|
if (!count)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
|
||||||
gpt_header **gpt, gpt_entry **ptes)
|
gpt_header **gpt, gpt_entry **ptes)
|
||||||
{
|
{
|
||||||
u32 crc, origcrc;
|
u32 crc, origcrc;
|
||||||
u64 lastlba;
|
u64 lastlba, pt_size;
|
||||||
|
|
||||||
if (!ptes)
|
if (!ptes)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sanity check partition table size */
|
||||||
|
pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) *
|
||||||
|
le32_to_cpu((*gpt)->sizeof_partition_entry);
|
||||||
|
if (pt_size > KMALLOC_MAX_SIZE) {
|
||||||
|
pr_debug("GUID Partition Table is too large: %llu > %lu bytes\n",
|
||||||
|
(unsigned long long)pt_size, KMALLOC_MAX_SIZE);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
|
if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Check the GUID Partition Entry Array CRC */
|
/* Check the GUID Partition Entry Array CRC */
|
||||||
crc = efi_crc32((const unsigned char *) (*ptes),
|
crc = efi_crc32((const unsigned char *) (*ptes), pt_size);
|
||||||
le32_to_cpu((*gpt)->num_partition_entries) *
|
|
||||||
le32_to_cpu((*gpt)->sizeof_partition_entry));
|
|
||||||
|
|
||||||
if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
|
if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
|
||||||
pr_debug("GUID Partition Entry Array CRC check failed.\n");
|
pr_debug("GUID Partition Entry Array CRC check failed.\n");
|
||||||
|
|
Loading…
Reference in New Issue