Skip to content

Commit 18ab896

Browse files
committed
nfsd: handle get_client_locked() failure in nfsd4_setclientid_confirm()
jira KERNEL-238 cve CVE-2025-38724 Rebuild_History Non-Buildable kernel-6.12.0-124.16.1.el10_1 commit-author Jeff Layton <jlayton@kernel.org> commit 908e4ea Lei Lu recently reported that nfsd4_setclientid_confirm() did not check the return value from get_client_locked(). a SETCLIENTID_CONFIRM could race with a confirmed client expiring and fail to get a reference. That could later lead to a UAF. Fix this by getting a reference early in the case where there is an extant confirmed client. If that fails then treat it as if there were no confirmed client found at all. In the case where the unconfirmed client is expiring, just fail and return the result from get_client_locked(). Reported-by: lei lu <llfamsec@gmail.com> Closes: https://lore.kernel.org/linux-nfs/CAEBF3_b=UvqzNKdnfD_52L05Mqrqui9vZ2eFamgAbV0WG+FNWQ@mail.gmail.com/ Fixes: d20c11d ("nfsd: Protect session creation and client confirm using client_lock") Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> (cherry picked from commit 908e4ea) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 468437a commit 18ab896

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

fs/nfsd/nfs4state.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4697,10 +4697,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
46974697
}
46984698
status = nfs_ok;
46994699
if (conf) {
4700-
old = unconf;
4701-
unhash_client_locked(old);
4702-
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
4703-
} else {
4700+
if (get_client_locked(conf) == nfs_ok) {
4701+
old = unconf;
4702+
unhash_client_locked(old);
4703+
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
4704+
} else {
4705+
conf = NULL;
4706+
}
4707+
}
4708+
4709+
if (!conf) {
47044710
old = find_confirmed_client_by_name(&unconf->cl_name, nn);
47054711
if (old) {
47064712
status = nfserr_clid_inuse;
@@ -4717,10 +4723,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
47174723
}
47184724
trace_nfsd_clid_replaced(&old->cl_clientid);
47194725
}
4726+
status = get_client_locked(unconf);
4727+
if (status != nfs_ok) {
4728+
old = NULL;
4729+
goto out;
4730+
}
47204731
move_to_confirmed(unconf);
47214732
conf = unconf;
47224733
}
4723-
get_client_locked(conf);
47244734
spin_unlock(&nn->client_lock);
47254735
if (conf == unconf)
47264736
fsnotify_dentry(conf->cl_nfsd_info_dentry, FS_MODIFY);

0 commit comments

Comments
 (0)