lkml.org 
[lkml]   [2022]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6.0 363/862] platform/chrome: fix double-free in chromeos_laptop_prepare()
    Date
    From: Rustam Subkhankulov <subkhankulov@ispras.ru>

    [ Upstream commit 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 ]

    If chromeos_laptop_prepare_i2c_peripherals() fails after allocating memory
    for 'cros_laptop->i2c_peripherals', this memory is freed at 'err_out' label
    and nonzero value is returned. Then chromeos_laptop_destroy() is called,
    resulting in double-free error.

    Found by Linux Verification Center (linuxtesting.org) with SVACE.

    Signed-off-by: Rustam Subkhankulov <subkhankulov@ispras.ru>
    Fixes: 5020cd29d8bf ("platform/chrome: chromeos_laptop - supply properties for ACPI devices")
    Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
    Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
    Link: https://lore.kernel.org/r/20220813220843.2373004-1-subkhankulov@ispras.ru
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/platform/chrome/chromeos_laptop.c | 24 ++++++++++++-----------
    1 file changed, 13 insertions(+), 11 deletions(-)

    diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
    index 4e14b4d6635d..a2cdbfbaeae6 100644
    --- a/drivers/platform/chrome/chromeos_laptop.c
    +++ b/drivers/platform/chrome/chromeos_laptop.c
    @@ -740,6 +740,7 @@ static int __init
    chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
    const struct chromeos_laptop *src)
    {
    + struct i2c_peripheral *i2c_peripherals;
    struct i2c_peripheral *i2c_dev;
    struct i2c_board_info *info;
    int i;
    @@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
    if (!src->num_i2c_peripherals)
    return 0;

    - cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals,
    - src->num_i2c_peripherals *
    - sizeof(*src->i2c_peripherals),
    - GFP_KERNEL);
    - if (!cros_laptop->i2c_peripherals)
    + i2c_peripherals = kmemdup(src->i2c_peripherals,
    + src->num_i2c_peripherals *
    + sizeof(*src->i2c_peripherals),
    + GFP_KERNEL);
    + if (!i2c_peripherals)
    return -ENOMEM;

    - cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
    -
    - for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) {
    - i2c_dev = &cros_laptop->i2c_peripherals[i];
    + for (i = 0; i < src->num_i2c_peripherals; i++) {
    + i2c_dev = &i2c_peripherals[i];
    info = &i2c_dev->board_info;

    error = chromeos_laptop_setup_irq(i2c_dev);
    @@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
    }
    }

    + cros_laptop->i2c_peripherals = i2c_peripherals;
    + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
    +
    return 0;

    err_out:
    while (--i >= 0) {
    - i2c_dev = &cros_laptop->i2c_peripherals[i];
    + i2c_dev = &i2c_peripherals[i];
    info = &i2c_dev->board_info;
    if (!IS_ERR_OR_NULL(info->fwnode))
    fwnode_remove_software_node(info->fwnode);
    }
    - kfree(cros_laptop->i2c_peripherals);
    + kfree(i2c_peripherals);
    return error;
    }

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-10-19 12:45    [W:4.157 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site