diff options
author | simon <simon@FreeBSD.org> | 2008-02-14 11:44:31 +0000 |
---|---|---|
committer | simon <simon@FreeBSD.org> | 2008-02-14 11:44:31 +0000 |
commit | 49aa39283b5da2ce1669bb252c6544ed9383fd5d (patch) | |
tree | 222b3284491d2eac0031b87892acec39fc669129 /sys/kern | |
parent | 30aa45f24bdd40449d3297b08a7214d362264c2c (diff) | |
download | FreeBSD-src-49aa39283b5da2ce1669bb252c6544ed9383fd5d.zip FreeBSD-src-49aa39283b5da2ce1669bb252c6544ed9383fd5d.tar.gz |
Fix sendfile(2) write-only file permission bypass.
Security: FreeBSD-SA-08:03.sendfile
Submitted by: kib
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_descrip.c | 2 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 31 |
2 files changed, 18 insertions, 15 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 7e53062..27a5289 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2050,7 +2050,7 @@ _fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags) int error; *vpp = NULL; - if ((error = _fget(td, fd, &fp, 0, 0)) != 0) + if ((error = _fget(td, fd, &fp, flags, 0)) != 0) return (error); if (fp->f_vnode == NULL) { error = EINVAL; diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 789276e..9709376 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1796,20 +1796,23 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap, goto out; vfslocked = VFS_LOCK_GIANT(vp->v_mount); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - obj = vp->v_object; - if (obj != NULL) { - /* - * Temporarily increase the backing VM object's reference - * count so that a forced reclamation of its vnode does not - * immediately destroy it. - */ - VM_OBJECT_LOCK(obj); - if ((obj->flags & OBJ_DEAD) == 0) { - vm_object_reference_locked(obj); - VM_OBJECT_UNLOCK(obj); - } else { - VM_OBJECT_UNLOCK(obj); - obj = NULL; + if (vp->v_type == VREG) { + obj = vp->v_object; + if (obj != NULL) { + /* + * Temporarily increase the backing VM + * object's reference count so that a forced + * reclamation of its vnode does not + * immediately destroy it. + */ + VM_OBJECT_LOCK(obj); + if ((obj->flags & OBJ_DEAD) == 0) { + vm_object_reference_locked(obj); + VM_OBJECT_UNLOCK(obj); + } else { + VM_OBJECT_UNLOCK(obj); + obj = NULL; + } } } VOP_UNLOCK(vp, 0); |