aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2015-05-19 03:13:02 -0400
committerSebastian Reichel <sre@kernel.org>2015-05-21 09:41:09 -0400
commit7f1a57fdd6cb6e7be2ed31878a34655df38e1861 (patch)
tree20413d06df4c75d7fbdb2aafab6b801808418555 /drivers/power
parent8e59c7f23410d5ca6b350a178b861a3d68c49edf (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 'drivers/power')
-rw-r--r--drivers/power/power_supply_core.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 15da277e0e8d..4bc0c7f459a5 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(power_supply_notifier);
30 30
31static struct device_type power_supply_dev_type; 31static struct device_type power_supply_dev_type;
32 32
33#define POWER_SUPPLY_DEFERRED_REGISTER_TIME msecs_to_jiffies(10)
34
33static bool __power_supply_is_supplied_by(struct power_supply *supplier, 35static bool __power_supply_is_supplied_by(struct power_supply *supplier,
34 struct power_supply *supply) 36 struct power_supply *supply)
35{ 37{
@@ -121,6 +123,30 @@ void power_supply_changed(struct power_supply *psy)
121} 123}
122EXPORT_SYMBOL_GPL(power_supply_changed); 124EXPORT_SYMBOL_GPL(power_supply_changed);
123 125
126/*
127 * Notify that power supply was registered after parent finished the probing.
128 *
129 * Often power supply is registered from driver's probe function. However
130 * calling power_supply_changed() directly from power_supply_register()
131 * would lead to execution of get_property() function provided by the driver
132 * too early - before the probe ends.
133 *
134 * Avoid that by waiting on parent's mutex.
135 */
136static void power_supply_deferred_register_work(struct work_struct *work)
137{
138 struct power_supply *psy = container_of(work, struct power_supply,
139 deferred_register_work.work);
140
141 if (psy->dev.parent)
142 mutex_lock(&psy->dev.parent->mutex);
143
144 power_supply_changed(psy);
145
146 if (psy->dev.parent)
147 mutex_unlock(&psy->dev.parent->mutex);
148}
149
124#ifdef CONFIG_OF 150#ifdef CONFIG_OF
125#include <linux/of.h> 151#include <linux/of.h>
126 152
@@ -645,6 +671,10 @@ __power_supply_register(struct device *parent,
645 struct power_supply *psy; 671 struct power_supply *psy;
646 int rc; 672 int rc;
647 673
674 if (!parent)
675 pr_warn("%s: Expected proper parent device for '%s'\n",
676 __func__, desc->name);
677
648 psy = kzalloc(sizeof(*psy), GFP_KERNEL); 678 psy = kzalloc(sizeof(*psy), GFP_KERNEL);
649 if (!psy) 679 if (!psy)
650 return ERR_PTR(-ENOMEM); 680 return ERR_PTR(-ENOMEM);
@@ -671,6 +701,8 @@ __power_supply_register(struct device *parent,
671 goto dev_set_name_failed; 701 goto dev_set_name_failed;
672 702
673 INIT_WORK(&psy->changed_work, power_supply_changed_work); 703 INIT_WORK(&psy->changed_work, power_supply_changed_work);
704 INIT_DELAYED_WORK(&psy->deferred_register_work,
705 power_supply_deferred_register_work);
674 706
675 rc = power_supply_check_supplies(psy); 707 rc = power_supply_check_supplies(psy);
676 if (rc) { 708 if (rc) {
@@ -709,7 +741,10 @@ __power_supply_register(struct device *parent,
709 * after calling power_supply_register()). 741 * after calling power_supply_register()).
710 */ 742 */
711 atomic_inc(&psy->use_cnt); 743 atomic_inc(&psy->use_cnt);
712 power_supply_changed(psy); 744
745 queue_delayed_work(system_power_efficient_wq,
746 &psy->deferred_register_work,
747 POWER_SUPPLY_DEFERRED_REGISTER_TIME);
713 748
714 return psy; 749 return psy;
715 750
@@ -729,7 +764,8 @@ dev_set_name_failed:
729 764
730/** 765/**
731 * power_supply_register() - Register new power supply 766 * power_supply_register() - Register new power supply
732 * @parent: Device to be a parent of power supply's device 767 * @parent: Device to be a parent of power supply's device, usually
768 * the device which probe function calls this
733 * @desc: Description of power supply, must be valid through whole 769 * @desc: Description of power supply, must be valid through whole
734 * lifetime of this power supply 770 * lifetime of this power supply
735 * @cfg: Run-time specific configuration accessed during registering, 771 * @cfg: Run-time specific configuration accessed during registering,
@@ -750,7 +786,8 @@ EXPORT_SYMBOL_GPL(power_supply_register);
750 786
751/** 787/**
752 * power_supply_register() - Register new non-waking-source power supply 788 * power_supply_register() - Register new non-waking-source power supply
753 * @parent: Device to be a parent of power supply's device 789 * @parent: Device to be a parent of power supply's device, usually
790 * the device which probe function calls this
754 * @desc: Description of power supply, must be valid through whole 791 * @desc: Description of power supply, must be valid through whole
755 * lifetime of this power supply 792 * lifetime of this power supply
756 * @cfg: Run-time specific configuration accessed during registering, 793 * @cfg: Run-time specific configuration accessed during registering,
@@ -779,7 +816,8 @@ static void devm_power_supply_release(struct device *dev, void *res)
779 816
780/** 817/**
781 * power_supply_register() - Register managed power supply 818 * power_supply_register() - Register managed power supply
782 * @parent: Device to be a parent of power supply's device 819 * @parent: Device to be a parent of power supply's device, usually
820 * the device which probe function calls this
783 * @desc: Description of power supply, must be valid through whole 821 * @desc: Description of power supply, must be valid through whole
784 * lifetime of this power supply 822 * lifetime of this power supply
785 * @cfg: Run-time specific configuration accessed during registering, 823 * @cfg: Run-time specific configuration accessed during registering,
@@ -814,7 +852,8 @@ EXPORT_SYMBOL_GPL(devm_power_supply_register);
814 852
815/** 853/**
816 * power_supply_register() - Register managed non-waking-source power supply 854 * power_supply_register() - Register managed non-waking-source power supply
817 * @parent: Device to be a parent of power supply's device 855 * @parent: Device to be a parent of power supply's device, usually
856 * the device which probe function calls this
818 * @desc: Description of power supply, must be valid through whole 857 * @desc: Description of power supply, must be valid through whole
819 * lifetime of this power supply 858 * lifetime of this power supply
820 * @cfg: Run-time specific configuration accessed during registering, 859 * @cfg: Run-time specific configuration accessed during registering,
@@ -858,6 +897,7 @@ void power_supply_unregister(struct power_supply *psy)
858{ 897{
859 WARN_ON(atomic_dec_return(&psy->use_cnt)); 898 WARN_ON(atomic_dec_return(&psy->use_cnt));
860 cancel_work_sync(&psy->changed_work); 899 cancel_work_sync(&psy->changed_work);
900 cancel_delayed_work_sync(&psy->deferred_register_work);
861 sysfs_remove_link(&psy->dev.kobj, "powers"); 901 sysfs_remove_link(&psy->dev.kobj, "powers");
862 power_supply_remove_triggers(psy); 902 power_supply_remove_triggers(psy);
863 psy_unregister_cooler(psy); 903 psy_unregister_cooler(psy);