]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
futex/requeue: Prevent NULL pointer dereference in remove_waiter() on self-deadlock
authorJi'an Zhou <eilaimemedsnaimel@gmail.com>
Tue, 2 Jun 2026 09:12:04 +0000 (09:12 +0000)
committerThomas Gleixner <tglx@kernel.org>
Tue, 2 Jun 2026 20:27:04 +0000 (22:27 +0200)
When FUTEX_CMP_REQUEUE_PI requeues a non-top waiter that already owns the
target PI futex, task_blocks_on_rt_mutex() returns -EDEADLK before setting
waiter->task.

The subsequent remove_waiter() in rt_mutex_start_proxy_lock() dereferences
the NULL waiter->task, causing a kernel crash.

Add a self-deadlock check for non-top waiters before calling
rt_mutex_start_proxy_lock(), analogous to the top-waiter check in
futex_lock_pi_atomic().

Fixes: 3bfdc63936dd4773109b7b8c280c0f3b5ae7d349 ("rtmutex: Use waiter::task instead of current in remove_waiter()")
Signed-off-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
kernel/futex/requeue.c

index b597cb3d17fc110014e56c20ed268e220e323886..1d99a84dc9adb8fc0b0752e164c5e27dde1d1797 100644 (file)
@@ -643,6 +643,12 @@ retry_private:
                                continue;
                        }
 
+                       /* Self-deadlock: non-top waiter already owns the PI futex. */
+                       if (rt_mutex_owner(&pi_state->pi_mutex) == this->task) {
+                               ret = -EDEADLK;
+                               break;
+                       }
+
                        ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
                                                        this->rt_waiter,
                                                        this->task);