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:40:53 +0000
commitc8180893d7fef8557d8f8cdd5945468be5023da2 (patch)
treea3f6e2ed7e36366f1c576606a89f32a3e534823e
parent63b77ab1554eb642ad28c35339f08ccfeaab13e5 (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 cca977b31e8e..ece924630514 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -1972,6 +1972,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)