]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
locking/rwsem: Fix logic error in rwsem_del_waiter()
authorAndrei Vagin <avagin@google.com>
Sat, 14 Mar 2026 18:26:07 +0000 (18:26 +0000)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 16 Mar 2026 12:16:48 +0000 (13:16 +0100)
Commit 1ea4b473504b ("locking/rwsem: Remove the list_head from struct
rw_semaphore") introduced a logic error in rwsem_del_waiter().

The root cause of this issue is an inconsistency in the return values of
__rwsem_del_waiter() and rwsem_del_waiter(). Specifically,
__rwsem_del_waiter() returns true when the wait list becomes empty,
whereas rwsem_del_waiter() is supposed to return true if the wait list
is NOT empty.

This caused a null pointer dereference in rwsem_mark_wake() because it
was being called when sem->first_waiter was NULL.

Fixes: 1ea4b473504b ("locking/rwsem: Remove the list_head from struct rw_semaphore")
Reported-by: syzbot+3d2ff92c67127d337463@syzkaller.appspotmail.com
Signed-off-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: syzbot+3d2ff92c67127d337463@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20260314182607.3343346-1-avagin@google.com
kernel/locking/rwsem.c

index ba4cb74de06449d91a632dd820c1edb7bbfdcc07..bf647097369cbf6eaef31097a855105f3bfc19d1 100644 (file)
@@ -370,7 +370,7 @@ bool __rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
 {
        if (list_empty(&waiter->list)) {
                sem->first_waiter = NULL;
-               return true;
+               return false;
        }
 
        if (sem->first_waiter == waiter) {
@@ -379,7 +379,7 @@ bool __rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
        }
        list_del(&waiter->list);
 
-       return false;
+       return true;
 }
 
 /*