Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b6901f3 authored by Sven Van Asbroeck's avatar Sven Van Asbroeck Committed by Greg Kroah-Hartman
Browse files

power: supply: max14656: fix potential use-after-free



[ Upstream commit 252fbeb86ceffa549af9842cefca2412d53a7653 ]

Explicitly cancel/sync the irq_work delayed work, otherwise
there's a chance that it will run after the device is removed,
which would result in a use-after-free.

Note that cancel/sync should happen:
- after irq's have been disabled, as the isr re-schedules the work
- before the power supply is unregistered, because the work func
    uses the power supply handle.

Cc: Alexander Kurz <akurz@blala.de>
Signed-off-by: default avatarSven Van Asbroeck <TheSven73@gmail.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a0d8a590
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -240,6 +240,14 @@ static enum power_supply_property max14656_battery_props[] = {
	POWER_SUPPLY_PROP_MANUFACTURER,
};

static void stop_irq_work(void *data)
{
	struct max14656_chip *chip = data;

	cancel_delayed_work_sync(&chip->irq_work);
}


static int max14656_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
@@ -278,8 +286,6 @@ static int max14656_probe(struct i2c_client *client,
	if (ret)
		return -ENODEV;

	INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);

	chip->detect_psy = devm_power_supply_register(dev,
		       &chip->psy_desc, &psy_cfg);
	if (IS_ERR(chip->detect_psy)) {
@@ -287,6 +293,13 @@ static int max14656_probe(struct i2c_client *client,
		return -EINVAL;
	}

	INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);
	ret = devm_add_action(dev, stop_irq_work, chip);
	if (ret) {
		dev_err(dev, "devm_add_action %d failed\n", ret);
		return ret;
	}

	ret = devm_request_irq(dev, chip->irq, max14656_irq,
			       IRQF_TRIGGER_FALLING,
			       MAX14656_NAME, chip);