summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsimon <simon@FreeBSD.org>2008-02-14 11:44:31 +0000
committersimon <simon@FreeBSD.org>2008-02-14 11:44:31 +0000
commit49aa39283b5da2ce1669bb252c6544ed9383fd5d (patch)
tree222b3284491d2eac0031b87892acec39fc669129 /sys
parent30aa45f24bdd40449d3297b08a7214d362264c2c (diff)
downloadFreeBSD-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')
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/uipc_syscalls.c31
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);
OpenPOWER on IntegriCloud