]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
alarmtimer: Access timerqueue node under lock in suspend
authorZhan Xusheng <zhanxusheng1024@gmail.com>
Tue, 7 Apr 2026 14:36:27 +0000 (22:36 +0800)
committerThomas Gleixner <tglx@kernel.org>
Tue, 7 Apr 2026 17:14:26 +0000 (19:14 +0200)
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
kernel/time/alarmtimer.c

index 069d93bfb0c75cf50602359504c3a4d162e057c7..7c07737bb5fff93ed8ebc591f9d02f98b11a6d43 100644 (file)
@@ -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;
                }