diff options
author | trasz <trasz@FreeBSD.org> | 2012-05-22 10:54:42 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2012-05-22 10:54:42 +0000 |
commit | 1efd81b29756f20e1a8bfbd51a184b918fb1880d (patch) | |
tree | 75d5975ae6b0ebb3f1767e73f2ed2b9485eb0032 | |
parent | 72726b2f32de1148afe56527b9425e60f48d8242 (diff) | |
download | FreeBSD-src-1efd81b29756f20e1a8bfbd51a184b918fb1880d.zip FreeBSD-src-1efd81b29756f20e1a8bfbd51a184b918fb1880d.tar.gz |
Fix enforcement of file size limit with O_APPEND on ZFS.
vn_rlimit_fsize takes uio->uio_offset and uio->uio_resid into account
when determining whether given write would exceed RLIMIT_FSIZE.
When APPEND flag is specified, ZFS updates uio->uio_offset to point to the
end of file.
But this happens after a call to vn_rlimit_fsize, so vn_rlimit_fsize check
can be rendered ineffective by thread that opens some file with O_APPEND
and lseeks below RLIMIT_FSIZE before calling write.
Submitted by: Mateusz Guzik <mjguzik at gmail dot com>
MFC after: 2 weeks
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index de24310..8ff15ec 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -838,6 +838,12 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) rl = zfs_range_lock(zp, woff, n, RL_WRITER); } + if (vn_rlimit_fsize(vp, uio, uio->uio_td)) { + zfs_range_unlock(rl); + ZFS_EXIT(zfsvfs); + return (EFBIG); + } + if (woff >= limit) { zfs_range_unlock(rl); ZFS_EXIT(zfsvfs); @@ -5696,9 +5702,6 @@ zfs_freebsd_write(ap) } */ *ap; { - if (vn_rlimit_fsize(ap->a_vp, ap->a_uio, ap->a_uio->uio_td)) - return (EFBIG); - return (zfs_write(ap->a_vp, ap->a_uio, ioflags(ap->a_ioflag), ap->a_cred, NULL)); } |