Skip to content

Commit 3dc0bab

Browse files
committed
power: supply: core: fix use after free in uevent
power_supply_uevent() which is called to emit a udev event on device deletion attempts to use the power_supply_battery_info structure, which is device-managed and has been freed before this point. Fix this by not generating all battery/charger properties when the device is about to be removed. This also avoids generating errors when trying to access the hardware in hot-unplug scenarios. ================================================================== BUG: KASAN: slab-use-after-free in power_supply_battery_info_has_prop (power_supply_core.c:872) Read of size 4 at addr 0000000062e59028 by task python3/27 Call Trace: power_supply_battery_info_has_prop (power_supply_core.c:872) power_supply_uevent (power_supply_sysfs.c:504) dev_uevent (drivers/base/core.c:2590) kobject_uevent_env (lib/kobject_uevent.c:558) kobject_uevent (lib/kobject_uevent.c:643) device_del (drivers/base/core.c:3266 drivers/base/core.c:3831) device_unregister (drivers/base/core.c:3730 drivers/base/core.c:3854) power_supply_unregister (power_supply_core.c:1608) devm_power_supply_release (power_supply_core.c:1515) release_nodes (drivers/base/devres.c:506) devres_release_group (drivers/base/devres.c:669) i2c_device_remove (drivers/i2c/i2c-core-base.c:629) device_remove (drivers/base/dd.c:570) device_release_driver_internal (drivers/base/dd.c:1274 drivers/base/dd.c:1295) device_driver_detach (drivers/base/dd.c:1332) unbind_store (drivers/base/bus.c:247) ... Allocated by task 27: devm_kmalloc (drivers/base/devres.c:119 drivers/base/devres.c:829) power_supply_get_battery_info (include/linux/device.h:316 power_supply_core.c:626) __power_supply_register (power_supply_core.c:1408) devm_power_supply_register (power_supply_core.c:1544) bq256xx_probe (bq256xx_charger.c:1539 bq256xx_charger.c:1727) bq256xx_charger i2c_device_probe (drivers/i2c/i2c-core-base.c:584) really_probe (drivers/base/dd.c:579 drivers/base/dd.c:658) __driver_probe_device (drivers/base/dd.c:800) device_driver_attach (drivers/base/dd.c:1128) bind_store (drivers/base/bus.c:273) ... Freed by task 27: kfree (mm/slab_common.c:1073) release_nodes (drivers/base/devres.c:503) devres_release_all (drivers/base/devres.c:536) device_del (drivers/base/core.c:3829) device_unregister (drivers/base/core.c:3730 drivers/base/core.c:3854) power_supply_unregister (power_supply_core.c:1608) devm_power_supply_release (power_supply_core.c:1515) release_nodes (drivers/base/devres.c:506) devres_release_group (drivers/base/devres.c:669) i2c_device_remove (drivers/i2c/i2c-core-base.c:629) device_remove (drivers/base/dd.c:570) device_release_driver_internal (drivers/base/dd.c:1274 drivers/base/dd.c:1295) device_driver_detach (drivers/base/dd.c:1332) unbind_store (drivers/base/bus.c:247) ... ================================================================== Reported-by: Vincent Whitchurch <[email protected]> Fixes: 27a2195 ("power: supply: core: auto-exposure of simple-battery data") Tested-by: Vincent Whitchurch <[email protected]> Signed-off-by: Sebastian Reichel <[email protected]>
1 parent cba3204 commit 3dc0bab

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

drivers/power/supply/power_supply_sysfs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,13 @@ int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env)
482482
if (ret)
483483
return ret;
484484

485+
/*
486+
* Kernel generates KOBJ_REMOVE uevent in device removal path, after
487+
* resources have been freed. Exit early to avoid use-after-free.
488+
*/
489+
if (psy->removing)
490+
return 0;
491+
485492
prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
486493
if (!prop_buf)
487494
return -ENOMEM;

0 commit comments

Comments
 (0)