From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neilb@ownmail.net>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>,
Mohammed Alquraini <mohammed.saad.alquraini@gmail.com>
Subject: [PATCH] SUNRPC: Fix use-after-free in svc_age_temp_xprts_now()
Date: Thu, 22 Oct 2026 16:53:57 -0400 [thread overview]
Message-ID: <20261022205357.3239985-1-cel@kernel.org> (raw)
svc_age_temp_xprts_now() moves each matching temporary transport
onto a local list under sv_lock, then drops the lock and walks the
local list without holding a reference on any of them. In the
meantime svc_delete_xprt() can take sv_lock, unlink the same
xpt_list node, and drop the transport's last reference. An idle
temporary transport holds only that one reference, so a peer FIN
that arrives between the two loops frees the svc_sock out from under
the second loop. The notifier then sets XPT_CLOSE in freed memory,
and svc_xprt_enqueue() reads xpt_flags and xpt_server from the freed
object and queues that object on a pool for an nfsd thread. KASAN
reports a slab-use-after-free in svc_xprt_enqueue() under
nfsd_inetaddr_event(), with the object freed by svc_sock_free() on
an nfsd thread.
The two-phase walk dates from when the second loop called into the
socket layer and could sleep. Commit 546125d16142 ("sunrpc: don't
call sleeping functions from the notifier block callbacks") moved
that work to the nfsd threads, so nothing left in the second loop
needs sv_lock dropped. Mark and enqueue each matching transport
under sv_lock in a single pass, as svc_age_temp_xprts() already
does, so that svc_delete_xprt() cannot unlink and free a transport
the notifier is still touching.
Fixes: c3d4879e01be ("sunrpc: Add a function to close temporary transports immediately")
Reported-by: Mohammed Alquraini <mohammed.saad.alquraini@gmail.com>
Signed-off-by: Chuck Lever <cel@kernel.org>
---
net/sunrpc/svc_xprt.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
Mohammed, thanks for the report. Please test and report your results.
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 5db42e53be62..076c624fe675 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1075,29 +1075,21 @@ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
{
struct svc_xprt *xprt;
struct list_head *le, *next;
- LIST_HEAD(to_be_closed);
spin_lock_bh(&serv->sv_lock);
list_for_each_safe(le, next, &serv->sv_tempsocks) {
xprt = list_entry(le, struct svc_xprt, xpt_list);
- if (rpc_cmp_addr(server_addr, (struct sockaddr *)
- &xprt->xpt_local)) {
- dprintk("svc_age_temp_xprts_now: found %p\n", xprt);
- list_move(le, &to_be_closed);
- }
- }
- spin_unlock_bh(&serv->sv_lock);
-
- while (!list_empty(&to_be_closed)) {
- le = to_be_closed.next;
+ if (!rpc_cmp_addr(server_addr, (struct sockaddr *)
+ &xprt->xpt_local))
+ continue;
list_del_init(le);
- xprt = list_entry(le, struct svc_xprt, xpt_list);
set_bit(XPT_CLOSE, &xprt->xpt_flags);
set_bit(XPT_KILL_TEMP, &xprt->xpt_flags);
dprintk("svc_age_temp_xprts_now: queuing xprt %p for closing\n",
xprt);
svc_xprt_enqueue(xprt);
}
+ spin_unlock_bh(&serv->sv_lock);
}
EXPORT_SYMBOL_GPL(svc_age_temp_xprts_now);
--
2.54.0
next reply other threads:[~2026-10-22 20:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 20:53 Chuck Lever [this message]
2026-10-23 2:13 ` [PATCH] SUNRPC: Fix use-after-free in svc_age_temp_xprts_now() NeilBrown
2026-10-26 10:30 ` Mohammed
2026-10-26 13:05 ` Chuck Lever
2026-10-26 13:39 ` Mohammed
2026-10-26 11:44 ` Jeff Layton
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=20261022205357.3239985-1-cel@kernel.org \
--to=cel@kernel.org \
--cc=dai.ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=mohammed.saad.alquraini@gmail.com \
--cc=neilb@ownmail.net \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
/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