The branch main has been updated by rmacklem:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=aa1cf240887ddcca66dfb969fdc5a8d545396037

commit aa1cf240887ddcca66dfb969fdc5a8d545396037
Author:     Rick Macklem <[email protected]>
AuthorDate: 2025-11-26 19:20:27 +0000
Commit:     Rick Macklem <[email protected]>
CommitDate: 2025-11-26 19:20:27 +0000

    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 <[email protected]>
    MFC after:      2 weeks
---
 sys/fs/nfsserver/nfs_nfsdstate.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

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)

Reply via email to