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-16 00:36:40 +0000
commite0861304a7b6b9c410db69be6148a5510c6b2d23 (patch)
tree60c5a7a1f5477180977a71829f16465894662ace
parent0cd475f86b09144843258dfcbc95af649aab7cec (diff)
downloadsrc-e0861304a7b6b9c410db69be6148a5510c6b2d23.tar.gz
src-e0861304a7b6b9c410db69be6148a5510c6b2d23.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. Reported by: rtm@lcs.mit.edu Tested by: rtm@lcs.mit.edu PR: 260412 MFC after: 2 weeks
-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 ead90fd49c14..5262986645cd 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3571,6 +3571,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 &&
@@ -3582,7 +3590,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) {
@@ -3594,9 +3601,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);
@@ -3660,9 +3664,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)
@@ -3717,8 +3718,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);
@@ -3829,6 +3828,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);
@@ -3850,12 +3853,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,