mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 19:46:55 +07:00
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,
|
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,
|
static int max14656_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
@ -278,8 +286,6 @@ static int max14656_probe(struct i2c_client *client,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);
|
|
||||||
|
|
||||||
chip->detect_psy = devm_power_supply_register(dev,
|
chip->detect_psy = devm_power_supply_register(dev,
|
||||||
&chip->psy_desc, &psy_cfg);
|
&chip->psy_desc, &psy_cfg);
|
||||||
if (IS_ERR(chip->detect_psy)) {
|
if (IS_ERR(chip->detect_psy)) {
|
||||||
@ -287,6 +293,13 @@ static int max14656_probe(struct i2c_client *client,
|
|||||||
return -EINVAL;
|
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,
|
ret = devm_request_irq(dev, chip->irq, max14656_irq,
|
||||||
IRQF_TRIGGER_FALLING,
|
IRQF_TRIGGER_FALLING,
|
||||||
MAX14656_NAME, chip);
|
MAX14656_NAME, chip);
|
||||||
|
Loading…
Reference in New Issue
Block a user