lkml.org 
[lkml]   [2021]   [Jan]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 12/76] ACPI: scan: Harden acpi_device_add() against device ID overflows
    Date
    From: Dexuan Cui <decui@microsoft.com>

    commit a58015d638cd4e4555297b04bec9b49028369075 upstream.

    Linux VM on Hyper-V crashes with the latest mainline:

    [ 4.069624] detected buffer overflow in strcpy
    [ 4.077733] kernel BUG at lib/string.c:1149!
    ..
    [ 4.085819] RIP: 0010:fortify_panic+0xf/0x11
    ...
    [ 4.085819] Call Trace:
    [ 4.085819] acpi_device_add.cold.15+0xf2/0xfb
    [ 4.085819] acpi_add_single_object+0x2a6/0x690
    [ 4.085819] acpi_bus_check_add+0xc6/0x280
    [ 4.085819] acpi_ns_walk_namespace+0xda/0x1aa
    [ 4.085819] acpi_walk_namespace+0x9a/0xc2
    [ 4.085819] acpi_bus_scan+0x78/0x90
    [ 4.085819] acpi_scan_init+0xfa/0x248
    [ 4.085819] acpi_init+0x2c1/0x321
    [ 4.085819] do_one_initcall+0x44/0x1d0
    [ 4.085819] kernel_init_freeable+0x1ab/0x1f4

    This is because of the recent buffer overflow detection in the
    commit 6a39e62abbaf ("lib: string.h: detect intra-object overflow in
    fortified string functions")

    Here acpi_device_bus_id->bus_id can only hold 14 characters, while the
    the acpi_device_hid(device) returns a 22-char string
    "HYPER_V_GEN_COUNTER_V1".

    Per ACPI Spec v6.2, Section 6.1.5 _HID (Hardware ID), if the ID is a
    string, it must be of the form AAA#### or NNNN####, i.e. 7 chars or 8
    chars.

    The field bus_id in struct acpi_device_bus_id was originally defined as
    char bus_id[9], and later was enlarged to char bus_id[15] in 2007 in the
    commit bb0958544f3c ("ACPI: use more understandable bus_id for ACPI
    devices")

    Fix the issue by changing the field bus_id to const char *, and use
    kstrdup_const() to initialize it.

    Signed-off-by: Dexuan Cui <decui@microsoft.com>
    Tested-By: Jethro Beekman <jethro@fortanix.com>
    [ rjw: Subject change, whitespace adjustment ]
    Cc: All applicable <stable@vger.kernel.org>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/acpi/internal.h | 2 +-
    drivers/acpi/scan.c | 15 ++++++++++++++-
    2 files changed, 15 insertions(+), 2 deletions(-)

    --- a/drivers/acpi/internal.h
    +++ b/drivers/acpi/internal.h
    @@ -97,7 +97,7 @@ void acpi_scan_table_handler(u32 event,
    extern struct list_head acpi_bus_id_list;

    struct acpi_device_bus_id {
    - char bus_id[15];
    + const char *bus_id;
    unsigned int instance_no;
    struct list_head node;
    };
    --- a/drivers/acpi/scan.c
    +++ b/drivers/acpi/scan.c
    @@ -487,6 +487,7 @@ static void acpi_device_del(struct acpi_
    acpi_device_bus_id->instance_no--;
    else {
    list_del(&acpi_device_bus_id->node);
    + kfree_const(acpi_device_bus_id->bus_id);
    kfree(acpi_device_bus_id);
    }
    break;
    @@ -675,7 +676,14 @@ int acpi_device_add(struct acpi_device *
    }
    if (!found) {
    acpi_device_bus_id = new_bus_id;
    - strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device));
    + acpi_device_bus_id->bus_id =
    + kstrdup_const(acpi_device_hid(device), GFP_KERNEL);
    + if (!acpi_device_bus_id->bus_id) {
    + pr_err(PREFIX "Memory allocation error for bus id\n");
    + result = -ENOMEM;
    + goto err_free_new_bus_id;
    + }
    +
    acpi_device_bus_id->instance_no = 0;
    list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
    }
    @@ -710,6 +718,11 @@ int acpi_device_add(struct acpi_device *
    if (device->parent)
    list_del(&device->node);
    list_del(&device->wakeup_list);
    +
    + err_free_new_bus_id:
    + if (!found)
    + kfree(new_bus_id);
    +
    mutex_unlock(&acpi_device_lock);

    err_detach:

    \
     
     \ /
      Last update: 2021-01-18 20:23    [W:3.690 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site