The branch stable/12 has been updated by rmacklem:

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

commit 6d16489da847852adb998c5f44b238d0b9c39aaf
Author:     Rick Macklem <rmack...@freebsd.org>
AuthorDate: 2021-12-16 00:36:40 +0000
Commit:     Rick Macklem <rmack...@freebsd.org>
CommitDate: 2021-12-30 01:32:33 +0000

    nfscl: Handle CB_SEQUENCE not first op correctly
    
    The check for "not first operation" in CB_SEQUENCE
    was done after the slot, etc. was updated. This patch
    moves the check to the beginning of CB_SEQUENCE
    processing.
    
    While here, also fix the check for "no CB_SEQUENCE operation first"
    by moving the check to the beginning of callback operation parsing,
    since the check was in a couple of the other operations, but
    not all of them.
    
    PR:     260412
    
    (cherry picked from commit e0861304a7b6b9c410db69be6148a5510c6b2d23)
---
 sys/fs/nfsclient/nfs_clstate.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 68e4d3f009bd..d6ed7970e805 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3460,6 +3460,14 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
                *repp++ = *tl;
                op = fxdr_unsigned(int, *tl);
+               nd->nd_procnum = op;
+               if (i == 0 && op != NFSV4OP_CBSEQUENCE && minorvers !=
+                   NFSV4_MINORVERSION) {
+                   nd->nd_repstat = NFSERR_OPNOTINSESS;
+                   *repp = nfscl_errmap(nd, minorvers);
+                   retops++;
+                   break;
+               }
                if (op < NFSV4OP_CBGETATTR ||
                   (op > NFSV4OP_CBRECALL && minorvers == NFSV4_MINORVERSION) ||
                   (op > NFSV4OP_CBNOTIFYDEVID &&
@@ -3469,7 +3477,6 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                    retops++;
                    break;
                }
-               nd->nd_procnum = op;
                if (op < NFSV41_CBNOPS)
                        nfsstatsv1.cbrpccnt[nd->nd_procnum]++;
                switch (op) {
@@ -3481,9 +3488,6 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                        if (!error)
                                error = nfsrv_getattrbits(nd, &attrbits,
                                    NULL, NULL);
-                       if (error == 0 && i == 0 &&
-                           minorvers != NFSV4_MINORVERSION)
-                               error = NFSERR_OPNOTINSESS;
                        if (!error) {
                                mp = nfscl_getmnt(minorvers, sessionid, cbident,
                                    &clp);
@@ -3547,9 +3551,6 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                        tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED);
                        trunc = fxdr_unsigned(int, *tl);
                        error = nfsm_getfh(nd, &nfhp);
-                       if (error == 0 && i == 0 &&
-                           minorvers != NFSV4_MINORVERSION)
-                               error = NFSERR_OPNOTINSESS;
                        if (!error) {
                                NFSLOCKCLSTATE();
                                if (minorvers == NFSV4_MINORVERSION)
@@ -3604,8 +3605,6 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                                NFSBCOPY(tl, stateid.other, NFSX_STATEIDOTHER);
                                if (minorvers == NFSV4_MINORVERSION)
                                        error = NFSERR_NOTSUPP;
-                               else if (i == 0)
-                                       error = NFSERR_OPNOTINSESS;
                                NFSCL_DEBUG(4, "off=%ju len=%ju sq=%u err=%d\n",
                                    (uintmax_t)off, (uintmax_t)len,
                                    stateid.seqid, error);
@@ -3716,6 +3715,10 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                        }
                        break;
                case NFSV4OP_CBSEQUENCE:
+                       if (i != 0) {
+                           error = NFSERR_SEQUENCEPOS;
+                           break;
+                       }
                        NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID +
                            5 * NFSX_UNSIGNED);
                        bcopy(tl, sessionid, NFSX_V4SESSIONID);
@@ -3737,12 +3740,9 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
                                }
                        }
                        NFSLOCKCLSTATE();
-                       if (i == 0) {
-                               clp = nfscl_getclntsess(sessionid);
-                               if (clp == NULL)
-                                       error = NFSERR_SERVERFAULT;
-                       } else
-                               error = NFSERR_SEQUENCEPOS;
+                       clp = nfscl_getclntsess(sessionid);
+                       if (clp == NULL)
+                               error = NFSERR_SERVERFAULT;
                        if (error == 0) {
                                tsep = nfsmnt_mdssession(clp->nfsc_nmp);
                                error = nfsv4_seqsession(seqid, slotid,

Reply via email to