auth_domain_put() uses kref_put_lock(), which atomically decrements the refcount before acquiring auth_domain_lock. This creates a window where an auth_domain entry is still linked on the hash list with refcount == 0. auth_domain_lookup() walks the hash under auth_domain_lock but uses plain kref_get() to acquire a reference. If it finds an entry in this transient zero-refcount state, refcount_inc() triggers a WARN and refuses to increment (saturating refcount_t semantics), but the function returns the pointer anyway. The caller then holds a dangling reference: when the concurrent auth_domain_put() finally acquires the lock and runs auth_domain_release(), the object is freed while the lookup caller still has a pointer to it. The sibling function auth_domain_find() already handles this correctly using kref_get_unless_zero(). Apply the same pattern in auth_domain_lookup(): treat a zero-refcount entry as absent and continue searching. The loop then either finds another live entry or falls through to insert the new domain, preserving existing semantics. Reported-by: Chris Mason Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton --- net/sunrpc/svcauth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 55b4d2874188..8e01f0626759 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -245,8 +245,10 @@ auth_domain_lookup(char *name, struct auth_domain *new) spin_lock(&auth_domain_lock); hlist_for_each_entry(hp, head, hash) { - if (strcmp(hp->name, name)==0) { - kref_get(&hp->ref); + if (strcmp(hp->name, name) == 0) { + if (!kref_get_unless_zero(&hp->ref)) + continue; + spin_unlock(&auth_domain_lock); return hp; } --- base-commit: 508c9eaa7e0b952c4fe019880796e6207e3cd201 change-id: 20260520-nfsd-fixes-f137572d0480 Best regards, -- Jeff Layton