diff options
author | Sven Van Asbroeck <thesven73@gmail.com> | 2019-02-16 00:43:02 +0300 |
---|---|---|
committer | Sebastian Reichel <sebastian.reichel@collabora.com> | 2019-04-05 19:01:38 +0300 |
commit | 0cd0e49711556d2331a06b1117b68dd786cb54d2 (patch) | |
tree | 96039b9bd4b451eb2e13739b8fa6321d2242e7f9 /drivers/power | |
parent | ec4628effbb7cf1f5241b41936540d986715f3bb (diff) | |
download | linux-0cd0e49711556d2331a06b1117b68dd786cb54d2.tar.xz |
power: supply: max14656: fix potential use-before-alloc
Call order on probe():
- max14656_hw_init() enables interrupts on the chip
- devm_request_irq() starts processing interrupts, isr
could be called immediately
- isr: schedules delayed work (irq_work)
- irq_work: calls power_supply_changed()
- devm_power_supply_register() registers the power supply
Depending on timing, it's possible that power_supply_changed()
is called on an unregistered power supply structure.
Fix by registering the power supply before requesting the irq.
Cc: Alexander Kurz <akurz@blala.de>
Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/supply/max14656_charger_detector.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/power/supply/max14656_charger_detector.c b/drivers/power/supply/max14656_charger_detector.c index b91b1d2999dc..d19307f791c6 100644 --- a/drivers/power/supply/max14656_charger_detector.c +++ b/drivers/power/supply/max14656_charger_detector.c @@ -280,6 +280,13 @@ static int max14656_probe(struct i2c_client *client, 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)) { + dev_err(dev, "power_supply_register failed\n"); + return -EINVAL; + } + ret = devm_request_irq(dev, chip->irq, max14656_irq, IRQF_TRIGGER_FALLING, MAX14656_NAME, chip); @@ -289,13 +296,6 @@ static int max14656_probe(struct i2c_client *client, } enable_irq_wake(chip->irq); - chip->detect_psy = devm_power_supply_register(dev, - &chip->psy_desc, &psy_cfg); - if (IS_ERR(chip->detect_psy)) { - dev_err(dev, "power_supply_register failed\n"); - return -EINVAL; - } - schedule_delayed_work(&chip->irq_work, msecs_to_jiffies(2000)); return 0; |