* [PATCH] rtc: atcrtc100: cancel alarm work on remove
@ 2026-09-09 15:26 Fan Wu
2026-09-09 15:37 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Fan Wu @ 2026-09-09 15:26 UTC (permalink / raw)
To: alexandre.belloni, cl634; +Cc: linux-rtc, linux-kernel, Fan Wu, stable, Song Li
The alarm interrupt handler atcrtc_alarm_isr() queues rtc_work on the
system workqueue to clear the alarm. The handler atcrtc_alarm_clear()
dereferences the devm-managed atcrtc_dev through container_of(), takes
rtc_lock() on the RTC device and writes the regmap.
The driver has no remove callback, and the devres cleanup only frees
the interrupt before the remaining resources. free_irq() waits for the
interrupt handler, but it does not cancel work the handler already
queued. A pending atcrtc_alarm_clear() can therefore run after the
regmap, the I/O mapping and finally the device structure have been
released, and dereference freed memory.
Add a remove callback that frees the interrupt first, so no new work
can be queued, and then cancels the alarm work, following the same
pattern as rtc-ds1374 and rtc-ds1305.
It also clears the wake IRQ and disables the wakeup source configured
in probe. These are not devres-managed, and the driver core only
releases them when the device itself is removed, not on unbind.
Without this cleanup, a later bind would fail probe with -EEXIST:
device_wakeup_attach() rejects a second wakeup source for the same
device, and the leftover wake IRQ would make dev_pm_set_wake_irq()
fail with -EEXIST and a WARN as well.
This issue was found by an in-house static analysis tool.
Fixes: 7adca706fe16 ("rtc: atcrtc100: Add ATCRTC100 RTC driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
---
drivers/rtc/rtc-atcrtc100.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/rtc/rtc-atcrtc100.c b/drivers/rtc/rtc-atcrtc100.c
index 9808fc2c5a49..3c7313218da5 100644
--- a/drivers/rtc/rtc-atcrtc100.c
+++ b/drivers/rtc/rtc-atcrtc100.c
@@ -337,6 +337,16 @@ static int atcrtc_probe(struct platform_device *pdev)
return devm_rtc_register_device(atcrtc_dev->rtc_dev);
}
+static void atcrtc_remove(struct platform_device *pdev)
+{
+ struct atcrtc_dev *atcrtc_dev = platform_get_drvdata(pdev);
+
+ dev_pm_clear_wake_irq(&pdev->dev);
+ device_init_wakeup(&pdev->dev, false);
+ devm_free_irq(&pdev->dev, atcrtc_dev->alarm_irq, atcrtc_dev);
+ cancel_work_sync(&atcrtc_dev->rtc_work);
+}
+
static int atcrtc_resume(struct device *dev)
{
struct atcrtc_dev *rtc = dev_get_drvdata(dev);
@@ -372,6 +382,7 @@ static struct platform_driver atcrtc_platform_driver = {
.pm = pm_sleep_ptr(&atcrtc_pm_ops),
},
.probe = atcrtc_probe,
+ .remove = atcrtc_remove,
};
module_platform_driver(atcrtc_platform_driver);
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] rtc: atcrtc100: cancel alarm work on remove
2026-09-09 15:26 [PATCH] rtc: atcrtc100: cancel alarm work on remove Fan Wu
@ 2026-09-09 15:37 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-09-09 15:37 UTC (permalink / raw)
To: Fan Wu; +Cc: Alexandre Belloni, linux-rtc
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] CRASH: NULL pointer dereference and uninitialized memory execution. The alarm IRQ is requested prematurely in probe before the required structures are initialized.
- [High] LEAK AND UAF: The probe function's error path for devm_rtc_register_device() fails to clean up newly configured wake capabilities and the workqueue.
--
commit 913e1e349945d1e573a4b95047a974a86f29a566
Author: Fan Wu <fanwu01@zju.edu.cn>
rtc: atcrtc100: cancel alarm work on remove
This commit adds a remove callback to the atcrtc100 RTC driver to properly
clean up resources. It clears the wake IRQ, disables wakeup, frees the
interrupt, and cancels the alarm work to prevent use-after-free and -EEXIST
issues on rebinding.
> diff --git a/drivers/rtc/rtc-atcrtc100.c b/drivers/rtc/rtc-atcrtc100.c
> index 9808fc2c5a492..3c7313218da51 100644
> --- a/drivers/rtc/rtc-atcrtc100.c
> +++ b/drivers/rtc/rtc-atcrtc100.c
> @@ -337,6 +337,16 @@ static int atcrtc_probe(struct platform_device *pdev)
> return devm_rtc_register_device(atcrtc_dev->rtc_dev);
[Severity: High]
This isn't a bug introduced by this patch, but does this error path leak
resources or risk a use-after-free?
If devm_rtc_register_device() fails in atcrtc_probe(), it returns the error
immediately:
atcrtc_probe() {
...
return devm_rtc_register_device(atcrtc_dev->rtc_dev);
}
However, earlier in atcrtc_probe(), device_init_wakeup() and
dev_pm_set_wake_irq() are called, which are not devres-managed. Do these wake
configurations leak on this error path?
Also, if the alarm IRQ fired and scheduled rtc_work, wouldn't returning without
cancel_work_sync() leave the work pending? Once devres frees atcrtc_dev,
couldn't this lead to a use-after-free when the system workqueue eventually
executes the uncancelled work?
[Severity: High]
This is also a pre-existing issue, but is there a race condition when the alarm
IRQ is requested earlier in atcrtc_probe()?
The IRQ is requested via devm_request_irq() before atcrtc_dev->rtc_dev is
allocated and before INIT_WORK() initializes rtc_work:
atcrtc_probe() {
...
ret = devm_request_irq(&pdev->dev, atcrtc_dev->alarm_irq, ...);
...
atcrtc_dev->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
...
INIT_WORK(&atcrtc_dev->rtc_work, atcrtc_alarm_clear);
}
If the hardware interrupt fires immediately after devm_request_irq(), the
handler atcrtc_alarm_isr() will execute:
atcrtc_alarm_isr() {
...
schedule_work(&rtc->rtc_work);
rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
...
}
Will this cause schedule_work() to operate on uninitialized memory and
rtc_update_irq() to dereference a NULL pointer? Should the IRQ request be moved
until after these structures are fully initialized?
> }
>
> +static void atcrtc_remove(struct platform_device *pdev)
> +{
> + struct atcrtc_dev *atcrtc_dev = platform_get_drvdata(pdev);
> +
> + dev_pm_clear_wake_irq(&pdev->dev);
> + device_init_wakeup(&pdev->dev, false);
> + devm_free_irq(&pdev->dev, atcrtc_dev->alarm_irq, atcrtc_dev);
> + cancel_work_sync(&atcrtc_dev->rtc_work);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909152651.712614-1-fanwu01@zju.edu.cn?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-09 15:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 15:26 [PATCH] rtc: atcrtc100: cancel alarm work on remove Fan Wu
2026-09-09 15:37 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.