* FAILED: patch "[PATCH] power: supply: lp8788-charger: fix use-after-free on remove" failed to apply to 6.6-stable tree
@ 2026-09-03 14:38 gregkh
2026-09-09 10:55 ` [PATCH 6.6.y 1/3] power: supply: lp8788-charger: Convert to platform remove callback returning void Sasha Levin
0 siblings, 1 reply; 4+ messages in thread
From: gregkh @ 2026-09-03 14:38 UTC (permalink / raw)
To: fanwu01, sebastian.reichel; +Cc: stable
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 831c29a12d560f8a3225f43050b3fbb5dfd79c66
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090352-math-comrade-6046@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 831c29a12d560f8a3225f43050b3fbb5dfd79c66 Mon Sep 17 00:00:00 2001
From: Fan Wu <fanwu01@zju.edu.cn>
Date: Sun, 2 Aug 2026 03:54:42 +0000
Subject: [PATCH] power: supply: lp8788-charger: fix use-after-free on remove
lp8788_charger_remove() flushes charger_work before unregistering the
IRQs. An IRQ thread can queue charger_work after flush_work() has
returned. The work can then run after devres frees pchg and dereference
it in lp8788_charger_event().
Unregister the IRQs first. free_irq() waits for any running threaded
handler, so no handler can queue more work afterwards. Then use
cancel_work_sync() to cancel pending work or wait for running work to
finish.
This issue was found by an in-house static analysis tool.
Fixes: 98a276649358 ("power_supply: Add new lp8788 charger driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260802035442.421697-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index f0a680c155c4..1bc2c150fb91 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -710,8 +710,8 @@ static void lp8788_charger_remove(struct platform_device *pdev)
{
struct lp8788_charger *pchg = platform_get_drvdata(pdev);
- flush_work(&pchg->charger_work);
lp8788_irq_unregister(pdev, pchg);
+ cancel_work_sync(&pchg->charger_work);
}
static struct platform_driver lp8788_charger_driver = {
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 6.6.y 1/3] power: supply: lp8788-charger: Convert to platform remove callback returning void
2026-09-03 14:38 FAILED: patch "[PATCH] power: supply: lp8788-charger: fix use-after-free on remove" failed to apply to 6.6-stable tree gregkh
@ 2026-09-09 10:55 ` Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 2/3] power: supply: lp8788: Use devm_power_supply_register() helper Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 3/3] power: supply: lp8788-charger: fix use-after-free on remove Sasha Levin
0 siblings, 2 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-09 10:55 UTC (permalink / raw)
To: stable; +Cc: Uwe Kleine-König, Sebastian Reichel, Sasha Levin
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
[ Upstream commit 7810ba3c5110ce66652ec6bd2abb92da5d726c3b ]
The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new() which already returns void. Eventually after all drivers
are converted, .remove_new() is renamed to .remove().
Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20230918133700.1254499-17-u.kleine-koenig@pengutronix.de
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 831c29a12d56 ("power: supply: lp8788-charger: fix use-after-free on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/lp8788-charger.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index 755b6a4379b85..2c81be82a41a4 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -714,20 +714,18 @@ static int lp8788_charger_probe(struct platform_device *pdev)
return 0;
}
-static int lp8788_charger_remove(struct platform_device *pdev)
+static void lp8788_charger_remove(struct platform_device *pdev)
{
struct lp8788_charger *pchg = platform_get_drvdata(pdev);
flush_work(&pchg->charger_work);
lp8788_irq_unregister(pdev, pchg);
lp8788_psy_unregister(pchg);
-
- return 0;
}
static struct platform_driver lp8788_charger_driver = {
.probe = lp8788_charger_probe,
- .remove = lp8788_charger_remove,
+ .remove_new = lp8788_charger_remove,
.driver = {
.name = LP8788_DEV_CHARGER,
},
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 6.6.y 2/3] power: supply: lp8788: Use devm_power_supply_register() helper
2026-09-09 10:55 ` [PATCH 6.6.y 1/3] power: supply: lp8788-charger: Convert to platform remove callback returning void Sasha Levin
@ 2026-09-09 10:55 ` Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 3/3] power: supply: lp8788-charger: fix use-after-free on remove Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-09 10:55 UTC (permalink / raw)
To: stable; +Cc: Andrew Davis, Sebastian Reichel, Sasha Levin
From: Andrew Davis <afd@ti.com>
[ Upstream commit 2abb571143c39f581df9951d263948726db42d86 ]
Use the device lifecycle managed register function. This helps prevent
mistakes like unregistering out of order in cleanup functions and
forgetting to unregister on error paths.
Signed-off-by: Andrew Davis <afd@ti.com>
Link: https://lore.kernel.org/r/20240123163653.384385-7-afd@ti.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 831c29a12d56 ("power: supply: lp8788-charger: fix use-after-free on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/lp8788-charger.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index 2c81be82a41a4..72b170b4ac46a 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -406,12 +406,6 @@ static const struct power_supply_desc lp8788_psy_battery_desc = {
.get_property = lp8788_battery_get_property,
};
-static void lp8788_psy_unregister(struct lp8788_charger *pchg)
-{
- power_supply_unregister(pchg->battery);
- power_supply_unregister(pchg->charger);
-}
-
static void lp8788_charger_event(struct work_struct *work)
{
struct lp8788_charger *pchg =
@@ -666,18 +660,16 @@ static int lp8788_psy_register(struct platform_device *pdev,
charger_cfg.supplied_to = battery_supplied_to;
charger_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to);
- pchg->charger = power_supply_register(&pdev->dev,
- &lp8788_psy_charger_desc,
- &charger_cfg);
+ pchg->charger = devm_power_supply_register(&pdev->dev,
+ &lp8788_psy_charger_desc,
+ &charger_cfg);
if (IS_ERR(pchg->charger))
return -EPERM;
- pchg->battery = power_supply_register(&pdev->dev,
- &lp8788_psy_battery_desc, NULL);
- if (IS_ERR(pchg->battery)) {
- power_supply_unregister(pchg->charger);
+ pchg->battery = devm_power_supply_register(&pdev->dev,
+ &lp8788_psy_battery_desc, NULL);
+ if (IS_ERR(pchg->battery))
return -EPERM;
- }
return 0;
}
@@ -720,7 +712,6 @@ static void lp8788_charger_remove(struct platform_device *pdev)
flush_work(&pchg->charger_work);
lp8788_irq_unregister(pdev, pchg);
- lp8788_psy_unregister(pchg);
}
static struct platform_driver lp8788_charger_driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 6.6.y 3/3] power: supply: lp8788-charger: fix use-after-free on remove
2026-09-09 10:55 ` [PATCH 6.6.y 1/3] power: supply: lp8788-charger: Convert to platform remove callback returning void Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 2/3] power: supply: lp8788: Use devm_power_supply_register() helper Sasha Levin
@ 2026-09-09 10:55 ` Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-09 10:55 UTC (permalink / raw)
To: stable; +Cc: Fan Wu, Sebastian Reichel, Sasha Levin
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 831c29a12d560f8a3225f43050b3fbb5dfd79c66 ]
lp8788_charger_remove() flushes charger_work before unregistering the
IRQs. An IRQ thread can queue charger_work after flush_work() has
returned. The work can then run after devres frees pchg and dereference
it in lp8788_charger_event().
Unregister the IRQs first. free_irq() waits for any running threaded
handler, so no handler can queue more work afterwards. Then use
cancel_work_sync() to cancel pending work or wait for running work to
finish.
This issue was found by an in-house static analysis tool.
Fixes: 98a276649358 ("power_supply: Add new lp8788 charger driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260802035442.421697-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/lp8788-charger.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index 72b170b4ac46a..8d9a60d2f7da3 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -710,8 +710,8 @@ static void lp8788_charger_remove(struct platform_device *pdev)
{
struct lp8788_charger *pchg = platform_get_drvdata(pdev);
- flush_work(&pchg->charger_work);
lp8788_irq_unregister(pdev, pchg);
+ cancel_work_sync(&pchg->charger_work);
}
static struct platform_driver lp8788_charger_driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-09 10:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 14:38 FAILED: patch "[PATCH] power: supply: lp8788-charger: fix use-after-free on remove" failed to apply to 6.6-stable tree gregkh
2026-09-09 10:55 ` [PATCH 6.6.y 1/3] power: supply: lp8788-charger: Convert to platform remove callback returning void Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 2/3] power: supply: lp8788: Use devm_power_supply_register() helper Sasha Levin
2026-09-09 10:55 ` [PATCH 6.6.y 3/3] power: supply: lp8788-charger: fix use-after-free on remove Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox