summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2023-04-15 18:07:29 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-06-21 15:38:57 +0200
commit05f7d8238bd86932b3c71d7b0b62b150130e787c (patch)
tree932093ee23a76c4cba72540bedb675df297659c4 /drivers
parentcd01d6ce01bc4d0b181c751258649bee66de9c56 (diff)
downloadlinux-05f7d8238bd86932b3c71d7b0b62b150130e787c.tar.gz
linux-05f7d8238bd86932b3c71d7b0b62b150130e787c.tar.bz2
linux-05f7d8238bd86932b3c71d7b0b62b150130e787c.zip
power: supply: ab8500: Fix external_power_changed race
[ Upstream commit a5299ce4e96f3e8930e9c051b28d8093ada87b08 ] ab8500_btemp_external_power_changed() dereferences di->btemp_psy, which gets sets in ab8500_btemp_probe() like this: di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, &psy_cfg); As soon as devm_power_supply_register() has called device_add() the external_power_changed callback can get called. So there is a window where ab8500_btemp_external_power_changed() may get called while di->btemp_psy has not been set yet leading to a NULL pointer dereference. Fixing this is easy. The external_power_changed callback gets passed the power_supply which will eventually get stored in di->btemp_psy, so ab8500_btemp_external_power_changed() can simply directly use the passed in psy argument which is always valid. And the same applies to ab8500_fg_external_power_changed(). Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/supply/ab8500_btemp.c6
-rw-r--r--drivers/power/supply/ab8500_fg.c6
2 files changed, 4 insertions, 8 deletions
diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
index 97423a04fc0f..c58644a3345c 100644
--- a/drivers/power/supply/ab8500_btemp.c
+++ b/drivers/power/supply/ab8500_btemp.c
@@ -976,10 +976,8 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
*/
static void ab8500_btemp_external_power_changed(struct power_supply *psy)
{
- struct ab8500_btemp *di = power_supply_get_drvdata(psy);
-
- class_for_each_device(power_supply_class, NULL,
- di->btemp_psy, ab8500_btemp_get_ext_psy_data);
+ class_for_each_device(power_supply_class, NULL, psy,
+ ab8500_btemp_get_ext_psy_data);
}
/* ab8500 btemp driver interrupts and their respective isr */
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index b00844103a07..f99e248f6aed 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -2384,10 +2384,8 @@ out:
*/
static void ab8500_fg_external_power_changed(struct power_supply *psy)
{
- struct ab8500_fg *di = power_supply_get_drvdata(psy);
-
- class_for_each_device(power_supply_class, NULL,
- di->fg_psy, ab8500_fg_get_ext_psy_data);
+ class_for_each_device(power_supply_class, NULL, psy,
+ ab8500_fg_get_ext_psy_data);
}
/**