summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhan Xusheng <zhanxusheng1024@gmail.com>2026-04-07 17:36:27 +0300
committerThomas Gleixner <tglx@kernel.org>2026-04-07 20:14:26 +0300
commit09c04714cb455debc1dcc3535b6becb52c5b01e0 (patch)
tree90661505dce3e5d22210b9ea849b53172c81a290
parentc5283a1ffdd5a877120279d164e9d5761e8455af (diff)
downloadlinux-09c04714cb455debc1dcc3535b6becb52c5b01e0.tar.xz
alarmtimer: Access timerqueue node under lock in suspend
In alarmtimer_suspend(), timerqueue_getnext() is called under base->lock, but next->expires is read after the lock is released. This is safe because suspend freezes all relevant task contexts, but reading the node while holding the lock makes the code easier to reason about and not worry about a theoretical UAF. Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260407143627.19405-1-zhanxusheng@xiaomi.com
-rw-r--r--kernel/time/alarmtimer.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 069d93bfb0c7..7c07737bb5ff 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -234,19 +234,23 @@ static int alarmtimer_suspend(struct device *dev)
if (!rtc)
return 0;
- /* Find the soonest timer to expire*/
+ /* Find the soonest timer to expire */
for (i = 0; i < ALARM_NUMTYPE; i++) {
struct alarm_base *base = &alarm_bases[i];
struct timerqueue_node *next;
+ ktime_t next_expires;
ktime_t delta;
- scoped_guard(spinlock_irqsave, &base->lock)
+ scoped_guard(spinlock_irqsave, &base->lock) {
next = timerqueue_getnext(&base->timerqueue);
+ if (next)
+ next_expires = next->expires;
+ }
if (!next)
continue;
- delta = ktime_sub(next->expires, base->get_ktime());
+ delta = ktime_sub(next_expires, base->get_ktime());
if (!min || (delta < min)) {
- expires = next->expires;
+ expires = next_expires;
min = delta;
type = i;
}