git: bdd57cbb1bda - main - nfsd: Add checks for layout errors in LayoutReturn

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Fri, 26 Nov 2021 23:46:05 UTC
The branch main has been updated by rmacklem:

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

commit bdd57cbb1bdafcf2ebffa73c52f0fffc9410ea7b
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-11-26 23:42:32 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-11-26 23:42:32 +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().
    
    Reported by:    rtm@lcs.mit.edu
    Tested by:      rtm@lcs.mit.edu
    PR:     260012
    MFC after:      2 weeks
---
 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 a590c599518f..80c492251ce8 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 360bc00b8df3..4cfac532f063 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,