Enforce RLIMIT_FSIZE before VOP_WRITE. This adds support to file
system drivers where it was missing from and fixes one buggy implementation. The arguably weird semantics of the check are maintained (v_size vs. va_bytes, overwrite).
This commit is contained in:
parent
f7be22cf8e
commit
0c20c076ce
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.64 2010/04/09 08:09:18 hannken Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.65 2010/04/23 15:38:46 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
|
||||
@ -48,7 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.64 2010/04/09 08:09:18 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.65 2010/04/23 15:38:46 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -564,7 +564,6 @@ msdosfs_write(void *v)
|
||||
vsize_t bytelen;
|
||||
off_t oldoff;
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct proc *p = curproc;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(vp);
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
@ -599,17 +598,6 @@ msdosfs_write(void *v)
|
||||
if (uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX)
|
||||
return (EFBIG);
|
||||
|
||||
/*
|
||||
* If they've exceeded their filesize limit, tell them about it.
|
||||
*/
|
||||
if (((uio->uio_offset + uio->uio_resid) >
|
||||
p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(p, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return (EFBIG);
|
||||
}
|
||||
|
||||
fstrans_start(vp->v_mount, FSTRANS_SHARED);
|
||||
/*
|
||||
* If the offset we are starting the write at is beyond the end of
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: smbfs_io.c,v 1.33 2009/06/22 21:13:50 njoly Exp $ */
|
||||
/* $NetBSD: smbfs_io.c,v 1.34 2010/04/23 15:38:47 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2001, Boris Popov
|
||||
@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: smbfs_io.c,v 1.33 2009/06/22 21:13:50 njoly Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: smbfs_io.c,v 1.34 2010/04/23 15:38:47 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -244,9 +244,8 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
|
||||
{
|
||||
struct smbmount *smp = VTOSMBFS(vp);
|
||||
struct smbnode *np = VTOSMB(vp);
|
||||
struct smb_cred scred;
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
struct smb_cred scred;
|
||||
int error = 0;
|
||||
int extended = 0;
|
||||
size_t resid = uiop->uio_resid;
|
||||
@ -270,6 +269,8 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
|
||||
}
|
||||
if (ioflag & IO_APPEND) {
|
||||
#if notyet
|
||||
struct proc *p = curproc;
|
||||
|
||||
/*
|
||||
* File size can be changed by another client
|
||||
*/
|
||||
@ -277,18 +278,19 @@ smbfs_writevnode(struct vnode *vp, struct uio *uiop,
|
||||
error = VOP_GETATTR(vp, &vattr, cred, td);
|
||||
if (error)
|
||||
return (error);
|
||||
if (np->n_size + uiop->uio_resid >
|
||||
p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(p, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return EFBIG;
|
||||
}
|
||||
#endif
|
||||
uiop->uio_offset = np->n_size;
|
||||
}
|
||||
}
|
||||
if (uiop->uio_resid == 0)
|
||||
return 0;
|
||||
if (p && uiop->uio_offset + uiop->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(p, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return EFBIG;
|
||||
}
|
||||
smb_makescred(&scred, l, cred);
|
||||
error = smb_write(smp->sm_share, np->n_fid, uiop, &scred);
|
||||
SMBVDEBUG("after: ofs=%lld,resid=%zu,err=%d\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tmpfs_vnops.c,v 1.68 2010/03/29 13:11:33 pooka Exp $ */
|
||||
/* $NetBSD: tmpfs_vnops.c,v 1.69 2010/04/23 15:38:47 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.68 2010/03/29 13:11:33 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.69 2010/04/23 15:38:47 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dirent.h>
|
||||
@ -594,7 +594,6 @@ tmpfs_write(void *v)
|
||||
bool extended;
|
||||
int error;
|
||||
off_t oldsize;
|
||||
struct proc *p = curproc;
|
||||
struct tmpfs_node *node;
|
||||
struct uvm_object *uobj;
|
||||
|
||||
@ -613,15 +612,6 @@ tmpfs_write(void *v)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (((uio->uio_offset + uio->uio_resid) >
|
||||
p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(p, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
error = EFBIG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ioflag & IO_APPEND)
|
||||
uio->uio_offset = node->tn_size;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_vnops.c,v 1.170 2010/03/29 13:11:32 pooka Exp $ */
|
||||
/* $NetBSD: vfs_vnops.c,v 1.171 2010/04/23 15:38:46 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
@ -66,7 +66,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.170 2010/03/29 13:11:32 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.171 2010/04/23 15:38:46 pooka Exp $");
|
||||
|
||||
#include "veriexec.h"
|
||||
|
||||
@ -351,6 +351,32 @@ vn_close(struct vnode *vp, int flags, kauth_cred_t cred)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
enforce_rlimit_fsize(struct vnode *vp, struct uio *uio, int ioflag)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
off_t testoff;
|
||||
|
||||
if (uio->uio_rw != UIO_WRITE || vp->v_type != VREG)
|
||||
return 0;
|
||||
|
||||
KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
|
||||
if (ioflag & IO_APPEND)
|
||||
testoff = vp->v_size;
|
||||
else
|
||||
testoff = uio->uio_offset;
|
||||
|
||||
if (testoff + uio->uio_resid >
|
||||
l->l_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(l->l_proc, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return EFBIG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Package up an I/O request on a vnode into a uio and do it.
|
||||
*/
|
||||
@ -382,16 +408,23 @@ vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset,
|
||||
} else {
|
||||
auio.uio_vmspace = l->l_proc->p_vmspace;
|
||||
}
|
||||
|
||||
if ((error = enforce_rlimit_fsize(vp, &auio, ioflg)) != 0)
|
||||
goto out;
|
||||
|
||||
if (rw == UIO_READ) {
|
||||
error = VOP_READ(vp, &auio, ioflg, cred);
|
||||
} else {
|
||||
error = VOP_WRITE(vp, &auio, ioflg, cred);
|
||||
}
|
||||
|
||||
if (aresid)
|
||||
*aresid = auio.uio_resid;
|
||||
else
|
||||
if (auio.uio_resid && error == 0)
|
||||
error = EIO;
|
||||
|
||||
out:
|
||||
if ((ioflg & IO_NODELOCKED) == 0) {
|
||||
VOP_UNLOCK(vp, 0);
|
||||
}
|
||||
@ -520,7 +553,12 @@ vn_write(file_t *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
uio->uio_offset = *offset;
|
||||
count = uio->uio_resid;
|
||||
|
||||
if ((error = enforce_rlimit_fsize(vp, uio, ioflag)) != 0)
|
||||
goto out;
|
||||
|
||||
error = VOP_WRITE(vp, uio, ioflag, cred);
|
||||
|
||||
if (flags & FOF_UPDATE_OFFSET) {
|
||||
if (ioflag & IO_APPEND) {
|
||||
/*
|
||||
@ -535,6 +573,8 @@ vn_write(file_t *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
||||
} else
|
||||
*offset += count - uio->uio_resid;
|
||||
}
|
||||
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0);
|
||||
return (error);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_bio.c,v 1.183 2009/03/14 14:46:11 dsl Exp $ */
|
||||
/* $NetBSD: nfs_bio.c,v 1.184 2010/04/23 15:38:47 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.183 2009/03/14 14:46:11 dsl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.184 2010/04/23 15:38:47 pooka Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_nfs.h"
|
||||
@ -480,6 +480,19 @@ nfs_write(void *v)
|
||||
if (error)
|
||||
return (error);
|
||||
uio->uio_offset = np->n_size;
|
||||
|
||||
/*
|
||||
* This is already checked above VOP_WRITE, but recheck
|
||||
* the append case here to make sure our idea of the
|
||||
* file size is as fresh as possible.
|
||||
*/
|
||||
if (uio->uio_offset + uio->uio_resid >
|
||||
l->l_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(l->l_proc, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return (EFBIG);
|
||||
}
|
||||
}
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
@ -487,17 +500,6 @@ nfs_write(void *v)
|
||||
return (EFBIG);
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
/*
|
||||
* Maybe this should be above the vnode op call, but so long as
|
||||
* file servers have no limits, i don't think it matters
|
||||
*/
|
||||
if (l && l->l_proc && uio->uio_offset + uio->uio_resid >
|
||||
l->l_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(l->l_proc, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return (EFBIG);
|
||||
}
|
||||
|
||||
origoff = uio->uio_offset;
|
||||
do {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ext2fs_readwrite.c,v 1.55 2009/10/19 18:41:17 bouyer Exp $ */
|
||||
/* $NetBSD: ext2fs_readwrite.c,v 1.56 2010/04/23 15:38:46 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
@ -60,7 +60,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.55 2009/10/19 18:41:17 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.56 2010/04/23 15:38:46 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -224,7 +224,6 @@ ext2fs_write(void *v)
|
||||
struct inode *ip;
|
||||
struct m_ext2fs *fs;
|
||||
struct buf *bp;
|
||||
struct proc *p;
|
||||
struct ufsmount *ump;
|
||||
daddr_t lbn;
|
||||
off_t osize;
|
||||
@ -270,19 +269,6 @@ ext2fs_write(void *v)
|
||||
if (uio->uio_offset < 0 ||
|
||||
(uint64_t)uio->uio_offset + uio->uio_resid > ump->um_maxfilesize)
|
||||
return (EFBIG);
|
||||
/*
|
||||
* Maybe this should be above the vnode op call, but so long as
|
||||
* file servers have no limits, I don't think it matters.
|
||||
*/
|
||||
p = curproc;
|
||||
if (vp->v_type == VREG && p &&
|
||||
uio->uio_offset + uio->uio_resid >
|
||||
p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(p, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return (EFBIG);
|
||||
}
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ufs_readwrite.c,v 1.94 2009/02/22 20:28:07 ad Exp $ */
|
||||
/* $NetBSD: ufs_readwrite.c,v 1.95 2010/04/23 15:38:46 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.94 2009/02/22 20:28:07 ad Exp $");
|
||||
__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.95 2010/04/23 15:38:46 pooka Exp $");
|
||||
|
||||
#ifdef LFS_READWRITE
|
||||
#define FS struct lfs
|
||||
@ -217,7 +217,6 @@ WRITE(void *v)
|
||||
struct inode *ip;
|
||||
FS *fs;
|
||||
struct buf *bp;
|
||||
struct lwp *l;
|
||||
kauth_cred_t cred;
|
||||
daddr_t lbn;
|
||||
off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize;
|
||||
@ -272,19 +271,6 @@ WRITE(void *v)
|
||||
if (vp == fs->lfs_ivnode)
|
||||
return (EPERM);
|
||||
#endif
|
||||
/*
|
||||
* Maybe this should be above the vnode op call, but so long as
|
||||
* file servers have no limits, I don't think it matters.
|
||||
*/
|
||||
l = curlwp;
|
||||
if (vp->v_type == VREG && l &&
|
||||
uio->uio_offset + uio->uio_resid >
|
||||
l->l_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
|
||||
mutex_enter(proc_lock);
|
||||
psignal(l->l_proc, SIGXFSZ);
|
||||
mutex_exit(proc_lock);
|
||||
return (EFBIG);
|
||||
}
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user