diff options
author | Hans de Goede <hdegoede@redhat.com> | 2023-04-15 19:07:29 +0300 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2023-05-08 16:03:50 +0300 |
commit | a5299ce4e96f3e8930e9c051b28d8093ada87b08 (patch) | |
tree | 9944dc2e44c6bc2f97b68b585e6bc2ba33c28f1d /drivers/power/supply/ab8500_fg.c | |
parent | ac9a78681b921877518763ba0e89202254349d1b (diff) | |
download | linux-a5299ce4e96f3e8930e9c051b28d8093ada87b08.tar.xz |
power: supply: ab8500: Fix external_power_changed race
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>
Diffstat (limited to 'drivers/power/supply/ab8500_fg.c')
-rw-r--r-- | drivers/power/supply/ab8500_fg.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 41a7bff9ac37..53560fbb6dcd 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -2407,10 +2407,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); } /** |