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
This commit is contained in:
Rick Macklem 2021-12-15 16:36:40 -08:00
parent 0cd475f86b
commit e0861304a7

View File

@ -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,