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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.