[tip: timers/clocksource] clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path
"tip-bot2 for WenTao Liang" <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <178695587251.1542179.70229304547225165.tip-bot2@tip-bot2> |
The following commit has been merged into the timers/clocksource branch of tip: Commit-ID: 05520e035f8332c8e33f3011b5ca016fde61793d Gitweb: https://git.kernel.org/tip/05520e035f8332c8e33f3011b5ca016fde61793d Author: WenTao Liang <[email protected]> AuthorDate: Sun, 28 Jun 2026 21:07:00 +08:00 Committer: Daniel Lezcano <[email protected]> CommitterDate: Thu, 13 Aug 2026 18:13:01 +02:00 clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path When cpuhp_setup_state fails after pit_clockevent_per_cpu_init has successfully called request_irq, the error handling jumps directly to out_pit_clocksource_unregister without freeing the registered IRQ. This leaks the IRQ line and, since kfree(pit) follows, leaves a dangling pointer registered as the interrupt handler's dev_id, potentially leading to a use-after-free if the IRQ fires afterwards. Fix it by calling pit_clockevent_per_cpu_exit to properly release the IRQ before falling through to the existing cleanup chain. Suggested-by: Greg KH <[email protected]> Fixes: bee33f22d7c3 ("clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support") Cc: [email protected] Signed-off-by: WenTao Liang <[email protected]> Signed-off-by: Daniel Lezcano <[email protected]> Link: https://patch.msgid.link/[email protected] --- drivers/clocksource/timer-nxp-pit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-nxp-pit.c b/drivers/clocksource/timer-nxp-pit.c index bc5157e..2f70d1d 100644 --- a/drivers/clocksource/timer-nxp-pit.c +++ b/drivers/clocksource/timer-nxp-pit.c @@ -328,8 +328,10 @@ static int pit_timer_init(struct device_node *np) if (pit_instances == max_pit_instances) { ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "PIT timer:starting", pit_clockevent_starting_cpu, NULL); - if (ret < 0) + if (ret < 0) { + pit_clockevent_per_cpu_exit(pit, pit_instances); goto out_pit_clocksource_unregister; + } } return 0;