git: efc08dab492c - stable/13 - nfscl: Handle CB_SEQUENCE not first op correctly

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Thu, 30 Dec 2021 01:28:10 UTC
The branch stable/13 has been updated by rmacklem:

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

commit efc08dab492c38a0a1830d8227c9c62e70ccf5df
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-12-16 00:36:40 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-12-30 01:24:55 +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 f34b9e3e05b6..dc86d1fded12 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3573,6 +3573,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 &&
@@ -3584,7 +3592,6 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
 		    retops++;
 		    break;
 		}
-		nd->nd_procnum = op;
 		if (op < NFSV42_CBNOPS)
 			nfsstatsv1.cbrpccnt[nd->nd_procnum]++;
 		switch (op) {
@@ -3596,9 +3603,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);
@@ -3662,9 +3666,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)
@@ -3719,8 +3720,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);
@@ -3831,6 +3830,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);
@@ -3852,12 +3855,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,