forked from Minki/linux
power: supply: max14656: fix potential use-after-free
Explicitly cancel/sync the irq_work delayed work, otherwise there's a chance that it will run after the device is removed, which would result in a use-after-free. Note that cancel/sync should happen: - after irq's have been disabled, as the isr re-schedules the work - before the power supply is unregistered, because the work func uses the power supply handle. Cc: Alexander Kurz <akurz@blala.de> Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This commit is contained in:
parent
0cd0e49711
commit
252fbeb86c
@ -240,6 +240,14 @@ static enum power_supply_property max14656_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
};
|
||||
|
||||
static void stop_irq_work(void *data)
|
||||
{
|
||||
struct max14656_chip *chip = data;
|
||||
|
||||
cancel_delayed_work_sync(&chip->irq_work);
|
||||
}
|
||||
|
||||
|
||||
static int max14656_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@ -278,8 +286,6 @@ static int max14656_probe(struct i2c_client *client,
|
||||
if (ret)
|
||||
return -ENODEV;
|
||||
|
||||
INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);
|
||||
|
||||
chip->detect_psy = devm_power_supply_register(dev,
|
||||
&chip->psy_desc, &psy_cfg);
|
||||
if (IS_ERR(chip->detect_psy)) {
|
||||
@ -287,6 +293,13 @@ static int max14656_probe(struct i2c_client *client,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);
|
||||
ret = devm_add_action(dev, stop_irq_work, chip);
|
||||
if (ret) {
|
||||
dev_err(dev, "devm_add_action %d failed\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, chip->irq, max14656_irq,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
MAX14656_NAME, chip);
|
||||
|
Loading…
Reference in New Issue
Block a user