git: 8e74cc2b4ec0 - stable/13 - nfsd: Add checks for layout errors in LayoutReturn

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Fri, 10 Dec 2021 00:59:36 UTC
The branch stable/13 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=8e74cc2b4ec090e592cc808e55a6936207b4d302

commit 8e74cc2b4ec090e592cc808e55a6936207b4d302
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-11-26 23:42:32 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-12-10 00:55:47 +0000

    nfsd: Add checks for layout errors in LayoutReturn
    
    For a LayoutReturn when using the Flexible File Layout,
    error reports may be provided in the request.
    Sanity check the size of these error reports and
    check that they exist before calling nfsrv_flexlayouterr().
    
    PR:     260012
    
    (cherry picked from commit bdd57cbb1bdafcf2ebffa73c52f0fffc9410ea7b)
---
 sys/fs/nfsserver/nfs_nfsdserv.c  | 6 ++++++
 sys/fs/nfsserver/nfs_nfsdstate.c | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index f5ff9f8fab83..4ca49f75fc2c 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -4959,6 +4959,12 @@ nfsrvd_layoutreturn(struct nfsrv_descript *nd, __unused int isdgram,
 		}
 
 		maxcnt = fxdr_unsigned(int, *tl);
+		/*
+		 * There is no fixed upper bound defined in the RFCs,
+		 * but 128Kbytes should be more than sufficient.
+		 */
+		if (maxcnt < 0 || maxcnt > 131072)
+			maxcnt = 0;
 		if (maxcnt > 0) {
 			layp = malloc(maxcnt + 1, M_TEMP, M_WAITOK);
 			error = nfsrv_mtostr(nd, (char *)layp, maxcnt);
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index e9acacb27cbd..67f615ecea7c 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -7301,7 +7301,7 @@ nfsrv_layoutreturn(struct nfsrv_descript *nd, vnode_t vp,
 			}
 			NFSDRECALLUNLOCK();
 		}
-		if (layouttype == NFSLAYOUT_FLEXFILE)
+		if (layouttype == NFSLAYOUT_FLEXFILE && layp != NULL)
 			nfsrv_flexlayouterr(nd, layp, maxcnt, p);
 	} else if (kind == NFSV4LAYOUTRET_FSID)
 		nfsrv_freelayouts(&nd->nd_clientid,