git: 6d16489da847 - stable/12 - nfscl: Handle CB_SEQUENCE not first op correctly

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

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

commit 6d16489da847852adb998c5f44b238d0b9c39aaf
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: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,