summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaqar Hameed <waqar.hameed@axis.com>2025-12-20 23:36:00 +0100
committerSasha Levin <sashal@kernel.org>2026-03-04 07:19:47 -0500
commit33751e28842bf5aee5ef7b2b8d5e456a069095cb (patch)
tree9a754c846c86a55e5009c18ddcb427bde5af633b
parent2ce2334be155bd8bad6377e99984246ce4dbd08c (diff)
power: supply: goldfish: Fix use-after-free in power_supply_changed()
[ Upstream commit b2ce982e2e0c888dc55c888ad0e20ea04daf2e6b ] Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 84d7b7687489 ("power: Add battery driver for goldfish emulator") Signed-off-by: Waqar Hameed <waqar.hameed@axis.com> Link: https://patch.msgid.link/500a606bb6fb6f2bb8d797e19a00cea9dd7b03c1.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/power/supply/goldfish_battery.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/power/supply/goldfish_battery.c b/drivers/power/supply/goldfish_battery.c
index a58d713d75ce..4d204f0e1853 100644
--- a/drivers/power/supply/goldfish_battery.c
+++ b/drivers/power/supply/goldfish_battery.c
@@ -224,12 +224,6 @@ static int goldfish_battery_probe(struct platform_device *pdev)
if (data->irq < 0)
return -ENODEV;
- ret = devm_request_irq(&pdev->dev, data->irq,
- goldfish_battery_interrupt,
- IRQF_SHARED, pdev->name, data);
- if (ret)
- return ret;
-
psy_cfg.drv_data = data;
data->ac = power_supply_register(&pdev->dev, &ac_desc, &psy_cfg);
@@ -245,6 +239,12 @@ static int goldfish_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
+ ret = devm_request_irq(&pdev->dev, data->irq,
+ goldfish_battery_interrupt,
+ IRQF_SHARED, pdev->name, data);
+ if (ret)
+ return ret;
+
GOLDFISH_BATTERY_WRITE(data, BATTERY_INT_ENABLE, BATTERY_INT_MASK);
return 0;
}