aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2025-11-26 19:20:27 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2025-12-10 03:36:04 +0000
commitffd47a4bc6716452da795aeaed3429d2392abb73 (patch)
tree29bcc5a0541879d1d7e55cd3ef316fe752fd6d24
parent224d65015465d085f2e07edccef1f23a8c217b88 (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 (cherry picked from commit aa1cf240887ddcca66dfb969fdc5a8d545396037)
-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)