git: 3053b2a3dcab - main - nfs_clrpcops.c: Add sanity checks for the slot cnts

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Mon, 27 Oct 2025 14:38:18 UTC
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=3053b2a3dcab6e05311c3b696bee4c9e5698d93a

commit 3053b2a3dcab6e05311c3b696bee4c9e5698d93a
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2025-10-27 14:35:27 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2025-10-27 14:35:27 +0000

    nfs_clrpcops.c: Add sanity checks for the slot cnts
    
    The reply to CreateSession includes the slot cnt for
    both fore and back slots. It should never be larger
    than the argument specified and the fore slot cnt
    should always be at least 1.
    
    Without this patch, the replied slot cnts were not
    being sanity checked.
    
    While here, replace 64 with NFSV4_SLOTS (which is 64).
    
    Reported by:    Ilja Van Sprundel <ivansprundel@ioactive.com>
    Reviewed by:    emaste, markj
    MFC after:      3 days
    Differential Revision:  https://reviews.freebsd.org/D53363
---
 sys/fs/nfsclient/nfs_clrpcops.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index d3b83eb8b94b..d9f27c3f31a2 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -5599,7 +5599,7 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,
 	}
 	*tl++ = txdr_unsigned(4096);		/* Max response size cached */
 	*tl++ = txdr_unsigned(20);		/* Max operations */
-	*tl++ = txdr_unsigned(64);		/* Max slots */
+	*tl++ = txdr_unsigned(NFSV4_SLOTS);	/* Max slots */
 	*tl = 0;				/* No rdma ird */
 
 	/* Fill in back channel attributes. */
@@ -5668,6 +5668,11 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,
 		sep->nfsess_maxcache = fxdr_unsigned(int, *tl++);
 		tl++;
 		sep->nfsess_foreslots = fxdr_unsigned(uint16_t, *tl++);
+		if (sep->nfsess_foreslots == 0) {
+			error = NFSERR_BADXDR;
+			goto nfsmout;
+		} else if (sep->nfsess_foreslots > NFSV4_SLOTS)
+			sep->nfsess_foreslots = NFSV4_SLOTS;
 		NFSCL_DEBUG(4, "fore slots=%d\n", (int)sep->nfsess_foreslots);
 		irdcnt = fxdr_unsigned(int, *tl);
 		if (irdcnt < 0 || irdcnt > 1) {
@@ -5681,6 +5686,8 @@ nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep,
 		NFSM_DISSECT(tl, uint32_t *, 7 * NFSX_UNSIGNED);
 		tl += 5;
 		sep->nfsess_backslots = fxdr_unsigned(uint16_t, *tl);
+		if (sep->nfsess_backslots > NFSV4_CBSLOTS)
+			sep->nfsess_backslots = NFSV4_CBSLOTS;
 		NFSCL_DEBUG(4, "back slots=%d\n", (int)sep->nfsess_backslots);
 	}
 	error = nd->nd_repstat;