mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
platform/chrome: fix double-free in chromeos_laptop_prepare()
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: 5020cd29d8
("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
This commit is contained in:
parent
1a8912caba
commit
6ad4194d6a
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user