mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Michael Bommarito <michael.bommarito@gmail.com>
To: Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>
Cc: "Darren Hart" <dvhart@infradead.org>,
	"Davidlohr Bueso" <dave@stgolabs.net>,
	"André Almeida" <andrealmeid@igalia.com>,
	"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
	"Clark Williams" <clrkwllms@kernel.org>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Ji'an Zhou" <eilaimemedsnaimel@gmail.com>,
	linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev
Subject: [PATCH] futex/requeue: Clean up requeue state on the self-deadlock path
Date: Sun, 28 Jun 2026 22:00:49 -0400	[thread overview]
Message-ID: <20260629020049.2082397-1-michael.bommarito@gmail.com> (raw)

futex_requeue() can reach the self-deadlock check after get_pi_state()
has taken a reference for the waiter and futex_requeue_pi_prepare() has
set this->pi_state and moved the waiter's requeue_state to
Q_REQUEUE_PI_IN_PROGRESS. The check returns -EDEADLK and breaks out of
the requeue loop without undoing any of that, unlike the sibling
rt_mutex_start_proxy_lock() failure path which clears this->pi_state,
drops the reference with put_pi_state() and calls
futex_requeue_pi_complete().

The extra pi_state reference is therefore leaked (the post-loop
put_pi_state() only balances the initial reference taken in
futex_proxy_trylock_atomic()), and the waiter is left in
Q_REQUEUE_PI_IN_PROGRESS. When that waiter is next woken on the source
futex it enters futex_requeue_pi_wakeup_sync() and waits for a requeue
completion that never comes, since futex_requeue_pi_complete() was
skipped; on a !PREEMPT_RT kernel this is an unkillable busy-spin that
pins a CPU. The path is reachable by an unprivileged FUTEX_CMP_REQUEUE_PI
that requeues a non-top waiter which already owns the target PI futex.

Make the -EDEADLK path perform the same cleanup as the
rt_mutex_start_proxy_lock() deadlock path.

Fixes: 74e144274af3 ("futex/requeue: Prevent NULL pointer dereference in remove_waiter() on self-deadlock")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
Built x86_64 with W=1, no new warnings; checkpatch --strict clean.

Reproduced with an unprivileged user program under QEMU/KVM: the
triggering FUTEX_CMP_REQUEUE_PI leaves the requeued owner spinning
permanently in futex_requeue_pi_wakeup_sync() (requeue_state stuck at
Q_REQUEUE_PI_WAIT) and kmemleak reports the leaked futex_pi_state. With
this patch the requeue still returns -EDEADLK, but the waiter no longer
wedges and kmemleak is clean. The futex selftests pass and are unchanged
from the unpatched kernel.

 kernel/futex/requeue.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c
index 7384672916fb6..73ca06ec32454 100644
--- a/kernel/futex/requeue.c
+++ b/kernel/futex/requeue.c
@@ -648,6 +648,9 @@ int futex_requeue(u32 __user *uaddr1, unsigned int flags1,
 			/* Self-deadlock: non-top waiter already owns the PI futex. */
 			if (rt_mutex_owner(&pi_state->pi_mutex) == this->task) {
 				ret = -EDEADLK;
+				this->pi_state = NULL;
+				put_pi_state(pi_state);
+				futex_requeue_pi_complete(this, ret);
 				break;
 			}
 

base-commit: f24ca6729076623c9a0547ecc71e4fc1c4b65c3c
-- 
2.53.0


             reply	other threads:[~2026-06-29  2:01 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-29  2:00 Michael Bommarito [this message]
2026-07-01 12:54 ` Sebastian Andrzej Siewior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260629020049.2082397-1-michael.bommarito@gmail.com \
    --to=michael.bommarito@gmail.com \
    --cc=andrealmeid@igalia.com \
    --cc=bigeasy@linutronix.de \
    --cc=clrkwllms@kernel.org \
    --cc=dave@stgolabs.net \
    --cc=dvhart@infradead.org \
    --cc=eilaimemedsnaimel@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-devel@lists.linux.dev \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome