aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2025-11-26 19:20:27 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2025-11-26 19:20:27 +0000
commitaa1cf240887ddcca66dfb969fdc5a8d545396037 (patch)
tree8b55c63363be49778de495a2bc4bf248ed5e5355
parentd45816f369eb0099fd274fee23a3bf137ee794b1 (diff)
nfs_nfsdstate.c: Add sanity checks for lock stateids
Bugzilla PR reported a crash caused by a synthetic client doing a Lock operation request with a delegation stateid. This patch fixes the problem by adding sanity checks for the type of stateid provided as an argument to the Lock and LockU operations. It has been tested with the FreeBSD, Linux and Solaris 11.4 clients. Hopefully, other NFSv4 clients will work ok as well. PR: 291080 Tested by: Robert Morris <rtm@lcs.mit.edu> MFC after: 2 weeks
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 111b0f26d0b5..3fae2be5af46 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -1977,6 +1977,20 @@ tryagain:
error = NFSERR_BADSTATEID;
}
+ /*
+ * Sanity check the stateid for the Lock/LockU cases.
+ */
+ if (error == 0 && (new_stp->ls_flags & NFSLCK_LOCK) != 0 &&
+ (((new_stp->ls_flags & NFSLCK_OPENTOLOCK) != 0 &&
+ (stp->ls_flags & NFSLCK_OPEN) == 0) ||
+ ((new_stp->ls_flags & NFSLCK_OPENTOLOCK) == 0 &&
+ (stp->ls_flags & NFSLCK_LOCK) == 0)))
+ error = NFSERR_BADSTATEID;
+ if (error == 0 && (new_stp->ls_flags & NFSLCK_UNLOCK) != 0 &&
+ (stp->ls_flags & NFSLCK_LOCK) == 0)
+ error = NFSERR_BADSTATEID;
+
+ /* Sanity check the delegation stateid. */
if (error == 0 &&
(stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) &&
getlckret == 0 && stp->ls_lfp != lfp)