diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2021-12-13 23:32:19 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2021-12-27 00:55:09 +0000 |
commit | 3c3b641a610cf57577c26850edb9a1de2c024f96 (patch) | |
tree | 3e77b6ec2f77d3ce4ab7f5b1ebe60ba4b7dd398c | |
parent | 030acb63d9a86b9a7bd15b06e60699abfa8a0a2b (diff) | |
download | src-3c3b641a610cf57577c26850edb9a1de2c024f96.tar.gz src-3c3b641a610cf57577c26850edb9a1de2c024f96.zip |
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
(cherry picked from commit fe04c91184e9e82609a657c4e6e70e213ed3a859)
-rw-r--r-- | sys/fs/nfsclient/nfs_clvnops.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index fefec912cfae..38b637c5c062 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -3733,6 +3733,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); @@ -3741,18 +3742,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; |