aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2020-09-14 00:44:50 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2020-09-14 00:44:50 +0000
commit2848d6d4de29756672bea4b1e7ff059b66e77874 (patch)
treefcd6ce4c8eb55515e3b07fdf1b3e30f06ab9ebe6 /sys/fs
parent073e409487fcf31c8d4ead0962540c8dc6bd0888 (diff)
downloadsrc-2848d6d4de29756672bea4b1e7ff059b66e77874.tar.gz
src-2848d6d4de29756672bea4b1e7ff059b66e77874.zip
Fix a case where the NFSv4.0 server might crash if delegations are enabled.
asomers@ reported a crash on an NFSv4.0 server with a backtrace of: kdb_backtrace vpanic panic nfsrv_docallback nfsrv_checkgetattr nfsrvd_getattr nfsrvd_dorpc nfssvc_program svc_run_internal svc_thread_start fork_exit fork_trampoline where the panic message was "docallb", which indicates that a callback was attempted when the ClientID is unconfirmed. This would not normally occur, but it is possible to have an unconfirmed ClientID structure with delegation structure(s) chained off it if the client were to issue a SetClientID with the same "id" but different "verifier" after acquiring delegations on the previously confirmed ClientID. The bug appears to be that nfsrv_checkgetattr() failed to check for this uncommon case of an unconfirmed ClientID with a delegation structure that no longer refers to a delegation the client knows about. This patch adds a check for this case, handling it as if no delegation exists, which is the case when the above occurs. Although difficult to reproduce, this change should avoid the panic(). PR: 249127 Reported by: asomers Reviewed by: asomers MFC after: 1 week Differential Revision: https://reviews.freebbsd.org/D26342
Notes
Notes: svn path=/head/; revision=365703
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index bc8fa10a2b3e..973ff8264696 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -5707,8 +5707,14 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
goto out;
}
clp = stp->ls_clp;
- delegfilerev = stp->ls_filerev;
+ /* If the clientid is not confirmed, ignore the delegation. */
+ if (clp->lc_flags & LCL_NEEDSCONFIRM) {
+ NFSUNLOCKSTATE();
+ goto out;
+ }
+
+ delegfilerev = stp->ls_filerev;
/*
* If the Write delegation was issued as a part of this Compound RPC
* or if we have an Implied Clientid (used in a previous Op in this