summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <matthew@cvs.openbsd.org>2012-05-21 16:41:04 +0000
committerMatthew Dempsky <matthew@cvs.openbsd.org>2012-05-21 16:41:04 +0000
commit3c1fa8e419a5e898b32c4ef37779f8fd20ee0d03 (patch)
tree0f65ca68802374f5f70eecd3e784908032342add
parent1d6a8efae8419f4d0742c0677fc7181dec6e243a (diff)
Cleanup O_CLOEXEC handling and make sure UF_EXCLOSE is set correctly
when opening /dev/fd/* (i.e., UF_EXCLOSE is now set iff O_CLOEXEC is set, rather than copying UF_EXCLOSE from the file descriptor being dup'd). Also, add support for O_CLOEXEC and O_DIRECTORY to fhopen(). ok krw, guenther; feedback from millert; testing and bug finding by krw
-rw-r--r--sys/kern/kern_descrip.c5
-rw-r--r--sys/kern/vfs_syscalls.c14
2 files changed, 13 insertions, 6 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 9aa2f55b225..4e46b056e04 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.95 2012/05/14 02:41:13 guenther Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.96 2012/05/21 16:41:03 matthew Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -1233,7 +1233,8 @@ dupfdopen(struct filedesc *fdp, int indx, int dfd, int mode)
return (EDEADLK);
fdp->fd_ofiles[indx] = wfp;
- fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
+ fdp->fd_ofileflags[indx] = (fdp->fd_ofileflags[indx] & UF_EXCLOSE) |
+ (fdp->fd_ofileflags[dfd] & ~UF_EXCLOSE);
wfp->f_count++;
fd_used(fdp, indx);
return (0);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 6ac0211eb36..adfd1684156 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.183 2012/05/14 02:41:13 guenther Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.184 2012/05/21 16:41:03 matthew Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -859,8 +859,10 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
if ((error = falloc(p, &fp, &indx)) != 0)
goto out;
-
flags = FFLAGS(oflags);
+ if (flags & O_CLOEXEC)
+ fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
+
cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
NDINITAT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fd, path, p);
p->p_dupfd = -1; /* XXX check for fdopen */
@@ -932,8 +934,6 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
}
}
VOP_UNLOCK(vp, 0, p);
- if (flags & O_CLOEXEC)
- fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
*retval = indx;
FILE_SET_MATURE(fp, p);
out:
@@ -1019,6 +1019,8 @@ sys_fhopen(struct proc *p, void *v, register_t *retval)
fp = NULL;
goto bad;
}
+ if (flags & O_CLOEXEC)
+ fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
goto bad;
@@ -1039,6 +1041,10 @@ sys_fhopen(struct proc *p, void *v, register_t *retval)
error = EOPNOTSUPP;
goto bad;
}
+ if ((flags & O_DIRECTORY) && vp->v_type != VDIR) {
+ error = ENOTDIR;
+ goto bad;
+ }
if (flags & FREAD) {
if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)
goto bad;