lkml.org 
[lkml]   [2017]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 23/50] partitions/efi: Fix integer overflow in GPT size calculation
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alden Tondettar <alden.tondettar@gmail.com>


    [ Upstream commit c5082b70adfe8e1ea1cf4a8eff92c9f260e364d2 ]

    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>
    Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    block/partitions/efi.c | 17 ++++++++++++-----
    1 file changed, 12 insertions(+), 5 deletions(-)

    --- a/block/partitions/efi.c
    +++ b/block/partitions/efi.c
    @@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries
    if (!gpt)
    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);
    if (!count)
    return NULL;
    @@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_pa
    gpt_header **gpt, gpt_entry **ptes)
    {
    u32 crc, origcrc;
    - u64 lastlba;
    + u64 lastlba, pt_size;

    if (!ptes)
    return 0;
    @@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_pa
    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)))
    goto fail;

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

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

    \
     
     \ /
      Last update: 2017-10-06 11:07    [W:4.293 / U:0.152 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site