diff options
author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2015-05-19 16:13:02 +0900 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2015-05-21 15:41:09 +0200 |
commit | 7f1a57fdd6cb6e7be2ed31878a34655df38e1861 (patch) | |
tree | 20413d06df4c75d7fbdb2aafab6b801808418555 /include | |
parent | 8e59c7f23410d5ca6b350a178b861a3d68c49edf (diff) |
power_supply: Fix possible NULL pointer dereference on early uevent
Don't call the power_supply_changed() from power_supply_register() when
parent is still probing because it may lead to accessing parent too
early.
In bq27x00_battery this caused NULL pointer exception because uevent of
power_supply_changed called back the the get_property() method provided
by the driver. The get_property() method accessed pointer which should
be returned by power_supply_register().
Starting from bq27x00_battery_probe():
di->bat = power_supply_register()
power_supply_changed()
kobject_uevent()
power_supply_uevent()
power_supply_show_property()
power_supply_get_property()
bq27x00_battery_get_property()
dereference of di->bat which is NULL here
The dereference of di->bat (value returned by power_supply_register())
is the currently visible problem. However calling back the methods
provided by driver before ending the probe may lead to accessing other
driver-related data which is not yet initialized.
The call to power_supply_changed() is postponed till probing ends -
mutex of parent device is released.
Reported-by: H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Fixes: 297d716f6260 ("power_supply: Change ownership from driver to core")
Tested-By: Dr. H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/power_supply.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 75a1dd8dc56e..a80f1fd01ddb 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -237,6 +237,7 @@ struct power_supply { /* private */ struct device dev; struct work_struct changed_work; + struct delayed_work deferred_register_work; spinlock_t changed_lock; bool changed; atomic_t use_cnt; |