git: fe04c91184e9 - main - nfscl: add a filesize limit check to nfs_allocate()

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Mon, 13 Dec 2021 23:35:49 UTC
The branch main has been updated by rmacklem:

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

commit fe04c91184e9e82609a657c4e6e70e213ed3a859
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-12-13 23:32:19 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-12-13 23:32:19 +0000

    nfscl: add a filesize limit check to nfs_allocate()
    
    As reported in PR#260343, nfs_allocate() did not check
    the filesize rlimit. This patch adds that check.
    
    PR:     260343
    Reviewed by:    asomers
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D33422
---
 sys/fs/nfsclient/nfs_clvnops.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 4a027ea07f26..ba2ba27b8fb6 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3761,6 +3761,7 @@ nfs_allocate(struct vop_allocate_args *ap)
 	off_t alen;
 	int attrflag, error, ret;
 	struct timespec ts;
+	struct uio io;
 
 	attrflag = 0;
 	nmp = VFSTONFS(vp->v_mount);
@@ -3769,18 +3770,24 @@ nfs_allocate(struct vop_allocate_args *ap)
 	if (NFSHASNFSV4(nmp) && nmp->nm_minorvers >= NFSV42_MINORVERSION &&
 	    (nmp->nm_privflag & NFSMNTP_NOALLOCATE) == 0) {
 		mtx_unlock(&nmp->nm_mtx);
+		alen = *ap->a_len;
+		if ((uint64_t)alen > nfs_maxalloclen)
+			alen = nfs_maxalloclen;
+
+		/* Check the file size limit. */
+		io.uio_offset = *ap->a_offset;
+		io.uio_resid = alen;
+		error = vn_rlimit_fsize(vp, &io, td);
+
 		/*
 		 * Flush first to ensure that the allocate adds to the
 		 * file's allocation on the server.
 		 */
-		error = ncl_flush(vp, MNT_WAIT, td, 1, 0);
-		if (error == 0) {
-			alen = *ap->a_len;
-			if ((uint64_t)alen > nfs_maxalloclen)
-				alen = nfs_maxalloclen;
+		if (error == 0)
+			error = ncl_flush(vp, MNT_WAIT, td, 1, 0);
+		if (error == 0)
 			error = nfsrpc_allocate(vp, *ap->a_offset, alen,
 			    &nfsva, &attrflag, ap->a_cred, td, NULL);
-		}
 		if (error == 0) {
 			*ap->a_offset += alen;
 			*ap->a_len -= alen;