git: 7deb47265d12 - stable/13 - nfsd: Reply NFSERR_SEQMISORDERED for bogus seqid argument

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Wed, 16 Feb 2022 01:03:26 UTC
The branch stable/13 has been updated by rmacklem:

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

commit 7deb47265d12caf83fb3d0ed047fc291da187937
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-02-09 23:17:50 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-02-16 01:02:28 +0000

    nfsd: Reply NFSERR_SEQMISORDERED for bogus seqid argument
    
    The ESXi NFSv4.1 client bogusly sends the wrong value
    for the csa_sequence argument for a Create_session operation.
    RFC8881 requires this value to be the same as the sequence
    reply from the ExchangeID operation most recently done for
    the client ID.
    
    Without this patch, the server replies NFSERR_STALECLIENTID,
    which is the correct response for an NFSv4.0 SetClientIDConfirm
    but is not the correct error for NFSv4.1/4.2, which is
    specified as NFSERR_SEQMISORDERED in RFC8881.
    This patch fixes this.
    
    This change does not fix the issue reported in the PR, where
    the ESXi client loops, attempting ExchangeID/Create_session
    repeatedly.
    
    PR:     261291
    
    (cherry picked from commit 17a56f3fabdfacb62f6d8858643cdb1861c8c1b5)
---
 sys/fs/nfsserver/nfs_nfsdstate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 1d0884683904..2abb99a5079e 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -676,10 +676,11 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
 	 * Perform any operations specified by the opflags.
 	 */
 	if (opflags & CLOPS_CONFIRM) {
-		if (((nd->nd_flag & ND_NFSV41) != 0 &&
-		     clp->lc_confirm.lval[0] != confirm.lval[0]) ||
-		    ((nd->nd_flag & ND_NFSV41) == 0 &&
-		     clp->lc_confirm.qval != confirm.qval))
+		if ((nd->nd_flag & ND_NFSV41) != 0 &&
+		     clp->lc_confirm.lval[0] != confirm.lval[0])
+			error = NFSERR_SEQMISORDERED;
+		else if ((nd->nd_flag & ND_NFSV41) == 0 &&
+		     clp->lc_confirm.qval != confirm.qval)
 			error = NFSERR_STALECLIENTID;
 		else if (nfsrv_notsamecredname(nd, clp))
 			error = NFSERR_CLIDINUSE;