summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Van Asbroeck <thesven73@gmail.com>2019-02-12 11:21:49 -0500
committerSebastian Reichel <sebastian.reichel@collabora.com>2019-02-12 23:27:16 +0100
commit74f0aaba7c7161f2f777015f6c2e6d8c2c44aa8f (patch)
treed71595d6627201036a1825bd4cee72dcd3724701
parentf83a6ece6997fe64ce9b02e8169c3fb43c68ea55 (diff)
downloadlinux-74f0aaba7c7161f2f777015f6c2e6d8c2c44aa8f.tar.bz2
power: supply: ds2782: fix possible use-after-free on remove
In remove(), use cancel_delayed_work_sync() to cancel the delayed work. Otherwise there's a chance that this work will continue to run until after the device has been removed. While we're here, fix the deallocation order in remove(), to correspond to the inverse of the probe() allocation order. This guarantees that any remaining work can run to completion with all driver structures still intact. This issue was detected with the help of Coccinelle. Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-rw-r--r--drivers/power/supply/ds2782_battery.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/power/supply/ds2782_battery.c b/drivers/power/supply/ds2782_battery.c
index 019c58493e3d..04b0fe7d7d62 100644
--- a/drivers/power/supply/ds2782_battery.c
+++ b/drivers/power/supply/ds2782_battery.c
@@ -319,17 +319,17 @@ static void ds278x_power_supply_init(struct power_supply_desc *battery)
static int ds278x_battery_remove(struct i2c_client *client)
{
struct ds278x_info *info = i2c_get_clientdata(client);
+ int id = info->id;
power_supply_unregister(info->battery);
+ cancel_delayed_work_sync(&info->bat_work);
kfree(info->battery_desc.name);
+ kfree(info);
mutex_lock(&battery_lock);
- idr_remove(&battery_id, info->id);
+ idr_remove(&battery_id, id);
mutex_unlock(&battery_lock);
- cancel_delayed_work(&info->bat_work);
-
- kfree(info);
return 0;
}