aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2021-12-16 00:36:40 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2021-12-30 01:32:33 +0000
commit6d16489da847852adb998c5f44b238d0b9c39aaf (patch)
tree86f0b55d87adae958fb8b61397ce544a63c4d268
parent8253e8833725f82f3e48a02c4bb43548feeb8d00 (diff)
downloadsrc-6d16489da847852adb998c5f44b238d0b9c39aaf.tar.gz
src-6d16489da847852adb998c5f44b238d0b9c39aaf.zip
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)
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c30
1 files 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,