Skip to content

Commit

Permalink
power: supply: ab8500: Fix external_power_changed race
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Hans de Goede authored and Sebastian Reichel committed May 8, 2023
1 parent ac9a786 commit a5299ce
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 8 deletions.
6 changes: 2 additions & 4 deletions drivers/power/supply/ab8500_btemp.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,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 */
Expand Down
6 changes: 2 additions & 4 deletions drivers/power/supply/ab8500_fg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2407,10 +2407,8 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
*/
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);
}

/**
Expand Down

0 comments on commit a5299ce

Please sign in to comment.