From: Chuck Lever <cel@kernel.org>
To: Jeff Layton <jlayton@kernel.org>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: linux-nfs@vger.kernel.org, Wolfgang Walter <linux@stwm.de>,
Chuck Lever <cel@kernel.org>
Subject: [PATCH v4 1/9] NFSD: Prevent lock owner use-after-free during client teardown
Date: Thu, 09 Jul 2026 13:40:24 -0400 [thread overview]
Message-ID: <20260709-cel-v4-1-1d519d9be0cb@kernel.org> (raw)
In-Reply-To: <20260709-cel-v4-0-1d519d9be0cb@kernel.org>
__destroy_client() releases a client's open owners, but a lock owner
whose only reference is a blocked lock (nbl) stays on
cl_ownerstr_hashtbl. client_has_state() does not count a bare owner,
so DESTROY_CLIENTID can reach __destroy_client() with such owners
present.
__destroy_client() then walks the table, calling remove_blocked_locks()
on each owner without a reference. Freeing a blocked lock drops the
owner reference held via flc_owner. The per-net laundromat reaps
blocked locks from nn->blocked_locks_lru independently of client state.
The two paths share blocked_locks_lock only for the list splice, not
the owner's lifetime. The laundromat therefore frees the owner as
__destroy_client() dereferences it, a NULL dereference in
remove_blocked_locks().
nfsd4_release_lockowner() holds a reference across the same call;
__destroy_client() does not. Hold cl_lock across the walk, taking a
reference and unhashing each owner, then drop it before
remove_blocked_locks() and nfs4_put_stateowner(), which take
blocked_locks_lock and cl_lock.
Reported-by: Wolfgang Walter <linux@stwm.de>
Closes: https://lore.kernel.org/linux-nfs/6eccafaaaa60651ef091257c3439c46b@stwm.de/
Fixes: 68ef3bc31664 ("nfsd: remove blocked locks on client teardown")
Reviewed-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
---
fs/nfsd/nfs4state.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a4398dc861a5..e000ed3e96e9 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2758,14 +2758,24 @@ __destroy_client(struct nfs4_client *clp)
release_openowner(oo);
}
for (i = 0; i < OWNER_HASH_SIZE; i++) {
- struct nfs4_stateowner *so, *tmp;
+ struct nfs4_stateowner *so;
- list_for_each_entry_safe(so, tmp, &clp->cl_ownerstr_hashtbl[i],
- so_strhash) {
+ spin_lock(&clp->cl_lock);
+ while (!list_empty(&clp->cl_ownerstr_hashtbl[i])) {
+ so = list_first_entry(&clp->cl_ownerstr_hashtbl[i],
+ struct nfs4_stateowner, so_strhash);
/* Should be no openowners at this point */
WARN_ON_ONCE(so->so_is_open_owner);
+ nfs4_get_stateowner(so);
+ unhash_lockowner_locked(lockowner(so));
+ spin_unlock(&clp->cl_lock);
+
remove_blocked_locks(lockowner(so));
+ nfs4_put_stateowner(so);
+
+ spin_lock(&clp->cl_lock);
}
+ spin_unlock(&clp->cl_lock);
}
nfsd4_return_all_client_layouts(clp);
nfsd4_shutdown_copy(clp);
--
2.54.0
next prev parent reply other threads:[~2026-07-09 17:40 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 17:40 [PATCH v4 0/9] NFSD: Fix UAFs in client teardown and state revocation Chuck Lever
2026-07-09 17:40 ` Chuck Lever [this message]
2026-07-09 17:40 ` [PATCH v4 2/9] NFSD: Prevent client use-after-free during delegation revoke Chuck Lever
2026-07-09 17:40 ` [PATCH v4 3/9] NFSD: Prevent client use-after-free during admin state revocation Chuck Lever
2026-07-09 17:40 ` [PATCH v4 4/9] NFSD: Prevent client use-after-free during export " Chuck Lever
2026-07-09 17:40 ` [PATCH v4 5/9] NFSD: Prevent client use-after-free during NFSv4.0 revoked-state cleanup Chuck Lever
2026-07-09 17:40 ` [PATCH v4 6/9] NFSD: Consolidate the revocation-path client unpin Chuck Lever
2026-07-09 17:40 ` [PATCH v4 7/9] NFSD: Prevent client use-after-free during blocked-lock reaping Chuck Lever
2026-07-09 18:36 ` Jeff Layton
2026-07-09 17:40 ` [PATCH v4 8/9] NFSD: Prevent client use-after-free during close_lru reaping Chuck Lever
2026-07-09 18:37 ` Jeff Layton
2026-07-09 17:40 ` [PATCH v4 9/9] NFSD: Release the export reference when reaping open stateids Chuck Lever
2026-07-09 18:40 ` Jeff Layton
2026-07-09 19:55 ` Chuck Lever
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=20260709-cel-v4-1-1d519d9be0cb@kernel.org \
--to=cel@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=linux@stwm.de \
--cc=neil@brown.name \
--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.