diff options
| author | Hans de Goede <hdegoede@redhat.com> | 2023-04-15 18:07:29 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-06-21 15:38:57 +0200 |
| commit | 05f7d8238bd86932b3c71d7b0b62b150130e787c (patch) | |
| tree | 932093ee23a76c4cba72540bedb675df297659c4 /drivers | |
| parent | cd01d6ce01bc4d0b181c751258649bee66de9c56 (diff) | |
| download | linux-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.c | 6 | ||||
| -rw-r--r-- | drivers/power/supply/ab8500_fg.c | 6 |
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); } /** |
