diff options
author | 2017-02-11 19:51:06 +0000 | |
---|---|---|
committer | 2017-02-11 19:51:06 +0000 | |
commit | 65014aebf91a57834a8398456ecc3535a02b36e8 (patch) | |
tree | 88a76e7799ac343a0e5d4718526e10f22f424680 | |
parent | Move parse_warning() into parse.c to prepare to replace errwarn.c (diff) | |
download | wireguard-openbsd-65014aebf91a57834a8398456ecc3535a02b36e8.tar.xz wireguard-openbsd-65014aebf91a57834a8398456ecc3535a02b36e8.zip |
Add a flags argument to falloc() that lets it optionally set the
close-on-exec flag on the newly allocated fd. Make falloc()'s
return arguments non-optional: assert that they're not NULL.
ok mpi@ millert@
-rw-r--r-- | share/man/man9/file.9 | 39 | ||||
-rw-r--r-- | sys/kern/exec_script.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_event.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 4 | ||||
-rw-r--r-- | sys/kern/sys_pipe.c | 15 | ||||
-rw-r--r-- | sys/kern/tty_pty.c | 6 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 31 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 13 | ||||
-rw-r--r-- | sys/sys/filedesc.h | 4 |
10 files changed, 69 insertions, 65 deletions
diff --git a/share/man/man9/file.9 b/share/man/man9/file.9 index ad530bba0c6..b3dfe90ea95 100644 --- a/share/man/man9/file.9 +++ b/share/man/man9/file.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: file.9,v 1.16 2015/11/23 17:53:57 jmc Exp $ +.\" $OpenBSD: file.9,v 1.17 2017/02/11 19:51:06 guenther Exp $ .\" .\" Copyright (c) 2002 Artur Grabowski <art@openbsd.org> .\" All rights reserved. @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 23 2015 $ +.Dd $Mdocdate: February 11 2017 $ .Dt FALLOC 9 .Os .Sh NAME @@ -38,7 +38,7 @@ .In sys/file.h .In sys/filedesc.h .Ft int -.Fn falloc "struct proc *p" "struct file **resultfp" "int *resultfd" +.Fn falloc "struct proc *p" "int flags" "struct file **resultfp" "int *resultfd" .Ft int .Fn fdrelease "struct proc *p" "int fd" .Ft void @@ -66,17 +66,32 @@ kqueues (see .Xr kqueue 2 ) , and various special purpose communication endpoints. .Pp -A new file descriptor is allocated with the function +A new file and a file descriptor for it are allocated with the function +.Fn falloc . +The +.Fa flags +argument can be used to set the +.Dv UF_EXCLOSE +flag on the new descriptor. +The larval file and fd are returned via +.Fa resultfp +and +.Fa resultfd , +which must not be +.Dv NULL . .Fn falloc -and freed with +initializes the new file to have a reference count of two: +one for the reference from the file descriptor table and one +for the caller to release with +.Fn FRELE +when it done initializing it. +.Pp +A file descriptor is freed with .Fn fdrelease . -.Fn falloc -and -.Fn fdrelease -deal with allocating and freeing slots in the file descriptor table, -expanding the table when necessary and initializing the descriptor. -It's possible to do those things in smaller steps, but it's not -recommended to make complicated kernel APIs that require it. +This releases the reference that it holds to the underlying file; +if that's the last reference then the file will be freed. +.\" with +.\" .Xr closef 9 . .Pp The files are extracted from the file descriptor table using the functions diff --git a/sys/kern/exec_script.c b/sys/kern/exec_script.c index 27faacfcc5f..0b9ae86e224 100644 --- a/sys/kern/exec_script.c +++ b/sys/kern/exec_script.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_script.c,v 1.39 2016/04/25 20:00:33 tedu Exp $ */ +/* $OpenBSD: exec_script.c,v 1.40 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: exec_script.c,v 1.13 1996/02/04 02:15:06 christos Exp $ */ /* @@ -169,7 +169,7 @@ check_shell: #endif fdplock(p->p_fd); - error = falloc(p, &fp, &epp->ep_fd); + error = falloc(p, 0, &fp, &epp->ep_fd); fdpunlock(p->p_fd); if (error) goto fail; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 8e549968e98..827fc9502f6 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_descrip.c,v 1.139 2017/01/24 04:09:59 deraadt Exp $ */ +/* $OpenBSD: kern_descrip.c,v 1.140 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */ /* @@ -895,11 +895,14 @@ fdexpand(struct proc *p) * a file descriptor for the process that refers to it. */ int -falloc(struct proc *p, struct file **resultfp, int *resultfd) +falloc(struct proc *p, int flags, struct file **resultfp, int *resultfd) { struct file *fp, *fq; int error, i; + KASSERT(resultfp != NULL); + KASSERT(resultfd != NULL); + fdpassertlocked(p->p_fd); restart: if ((error = fdalloc(p, 0, &i)) != 0) { @@ -929,13 +932,12 @@ restart: LIST_INSERT_HEAD(&filehead, fp, f_list); } p->p_fd->fd_ofiles[i] = fp; + p->p_fd->fd_ofileflags[i] |= (flags & UF_EXCLOSE); fp->f_count = 1; fp->f_cred = p->p_ucred; crhold(fp->f_cred); - if (resultfp) - *resultfp = fp; - if (resultfd) - *resultfd = i; + *resultfp = fp; + *resultfd = i; FREF(fp); return (0); } diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index c694521c411..561b9b256ea 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.77 2016/09/24 18:39:17 tedu Exp $ */ +/* $OpenBSD: kern_event.c,v 1.78 2017/02/11 19:51:06 guenther Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> @@ -440,7 +440,7 @@ sys_kqueue(struct proc *p, void *v, register_t *retval) int fd, error; fdplock(fdp); - error = falloc(p, &fp, &fd); + error = falloc(p, 0, &fp, &fd); fdpunlock(fdp); if (error) return (error); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index b69df723edf..6d12ae1931c 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.186 2017/02/08 20:58:30 guenther Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.187 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -576,7 +576,7 @@ sys_execve(struct proc *p, void *v, register_t *retval) struct vnode *vp; int indx; - if ((error = falloc(p, &fp, &indx)) != 0) + if ((error = falloc(p, 0, &fp, &indx)) != 0) break; #ifdef DIAGNOSTIC if (indx != i) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index e869b61cd8b..57c45d74335 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.75 2016/10/08 02:16:43 guenther Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.76 2017/02/11 19:51:06 guenther Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -133,7 +133,9 @@ dopipe(struct proc *p, int *ufds, int flags) struct filedesc *fdp = p->p_fd; struct file *rf, *wf; struct pipe *rpipe, *wpipe = NULL; - int fds[2], error; + int fds[2], cloexec, error; + + cloexec = (flags & O_CLOEXEC) ? UF_EXCLOSE : 0; rpipe = pool_get(&pipe_pool, PR_WAITOK); error = pipe_create(rpipe); @@ -146,7 +148,7 @@ dopipe(struct proc *p, int *ufds, int flags) fdplock(fdp); - error = falloc(p, &rf, &fds[0]); + error = falloc(p, cloexec, &rf, &fds[0]); if (error != 0) goto free2; rf->f_flag = FREAD | FWRITE | (flags & FNONBLOCK); @@ -154,7 +156,7 @@ dopipe(struct proc *p, int *ufds, int flags) rf->f_data = rpipe; rf->f_ops = &pipeops; - error = falloc(p, &wf, &fds[1]); + error = falloc(p, cloexec, &wf, &fds[1]); if (error != 0) goto free3; wf->f_flag = FREAD | FWRITE | (flags & FNONBLOCK); @@ -162,11 +164,6 @@ dopipe(struct proc *p, int *ufds, int flags) wf->f_data = wpipe; wf->f_ops = &pipeops; - if (flags & O_CLOEXEC) { - fdp->fd_ofileflags[fds[0]] |= UF_EXCLOSE; - fdp->fd_ofileflags[fds[1]] |= UF_EXCLOSE; - } - rpipe->pipe_peer = wpipe; wpipe->pipe_peer = rpipe; diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 1f1f43880ee..4d79348e7a3 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty_pty.c,v 1.78 2016/05/24 16:09:07 deraadt Exp $ */ +/* $OpenBSD: tty_pty.c,v 1.79 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */ /* @@ -1055,11 +1055,11 @@ ptmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PTMGET: fdplock(fdp); /* Grab two filedescriptors. */ - if ((error = falloc(p, &cfp, &cindx)) != 0) { + if ((error = falloc(p, 0, &cfp, &cindx)) != 0) { fdpunlock(fdp); break; } - if ((error = falloc(p, &sfp, &sindx)) != 0) { + if ((error = falloc(p, 0, &sfp, &sindx)) != 0) { fdremove(fdp, cindx); closef(cfp, p); fdpunlock(fdp); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 7a8841c4988..40433a86527 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.148 2017/01/26 01:58:00 dhill Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.149 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -94,9 +94,7 @@ sys_socket(struct proc *p, void *v, register_t *retval) return (error); fdplock(fdp); - error = falloc(p, &fp, &fd); - if (error == 0 && (type & SOCK_CLOEXEC)) - fdp->fd_ofileflags[fd] |= UF_EXCLOSE; + error = falloc(p, (type & SOCK_CLOEXEC) ? UF_EXCLOSE : 0, &fp, &fd); fdpunlock(fdp); if (error != 0) goto out; @@ -279,9 +277,7 @@ doaccept(struct proc *p, int sock, struct sockaddr *name, socklen_t *anamelen, headfp = fp; fdplock(fdp); - error = falloc(p, &fp, &tmpfd); - if (!error && (flags & SOCK_CLOEXEC)) - fdp->fd_ofileflags[tmpfd] |= UF_EXCLOSE; + error = falloc(p, (flags & SOCK_CLOEXEC) ? UF_EXCLOSE : 0, &fp, &tmpfd); fdpunlock(fdp); if (error) { FRELE(headfp, p); @@ -447,11 +443,12 @@ sys_socketpair(struct proc *p, void *v, register_t *retval) struct filedesc *fdp = p->p_fd; struct file *fp1, *fp2; struct socket *so1, *so2; - int type, flags, fflag, error, sv[2]; + int type, cloexec, nonblock, fflag, error, sv[2]; type = SCARG(uap, type) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); - flags = SCARG(uap, type) & (SOCK_CLOEXEC | SOCK_NONBLOCK); - fflag = FREAD | FWRITE | (flags & SOCK_NONBLOCK ? FNONBLOCK : 0); + cloexec = (SCARG(uap, type) & SOCK_CLOEXEC) ? UF_EXCLOSE : 0; + nonblock = SCARG(uap, type) & SOCK_NONBLOCK; + fflag = FREAD | FWRITE | (nonblock ? FNONBLOCK : 0); error = socreate(SCARG(uap, domain), &so1, type, SCARG(uap, protocol)); if (error) @@ -471,32 +468,28 @@ sys_socketpair(struct proc *p, void *v, register_t *retval) goto free2; } fdplock(fdp); - if ((error = falloc(p, &fp1, &sv[0])) != 0) + if ((error = falloc(p, cloexec, &fp1, &sv[0])) != 0) goto free3; fp1->f_flag = fflag; fp1->f_type = DTYPE_SOCKET; fp1->f_ops = &socketops; fp1->f_data = so1; - if ((error = falloc(p, &fp2, &sv[1])) != 0) + if ((error = falloc(p, cloexec, &fp2, &sv[1])) != 0) goto free4; fp2->f_flag = fflag; fp2->f_type = DTYPE_SOCKET; fp2->f_ops = &socketops; fp2->f_data = so2; - if (flags & SOCK_CLOEXEC) { - fdp->fd_ofileflags[sv[0]] |= UF_EXCLOSE; - fdp->fd_ofileflags[sv[1]] |= UF_EXCLOSE; - } error = copyout(sv, SCARG(uap, rsv), 2 * sizeof (int)); if (error == 0) { #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrfds(p, sv, 2); #endif - if (flags & SOCK_NONBLOCK) { - (*fp1->f_ops->fo_ioctl)(fp1, FIONBIO, (caddr_t)&flags, + if (nonblock) { + (*fp1->f_ops->fo_ioctl)(fp1, FIONBIO, (caddr_t)&type, p); - (*fp2->f_ops->fo_ioctl)(fp2, FIONBIO, (caddr_t)&flags, + (*fp2->f_ops->fo_ioctl)(fp2, FIONBIO, (caddr_t)&type, p); } FILE_SET_MATURE(fp1, p); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 585485281cb..f2e1604c98a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.269 2017/01/23 22:34:10 deraadt Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.270 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -802,7 +802,8 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode, fdplock(fdp); - if ((error = falloc(p, &fp, &indx)) != 0) + if ((error = falloc(p, (oflags & O_CLOEXEC) ? UF_EXCLOSE : 0, &fp, + &indx)) != 0) goto out; flags = FFLAGS(oflags); if (flags & FREAD) @@ -812,9 +813,6 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode, if (oflags & O_CREAT) ni_pledge |= PLEDGE_CPATH; - if (flags & O_CLOEXEC) - fdp->fd_ofileflags[indx] |= UF_EXCLOSE; - cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; if ((p->p_p->ps_flags & PS_PLEDGE)) cmode &= ACCESSPERMS; @@ -970,12 +968,11 @@ sys_fhopen(struct proc *p, void *v, register_t *retval) return (EINVAL); fdplock(fdp); - if ((error = falloc(p, &fp, &indx)) != 0) { + if ((error = falloc(p, (flags & O_CLOEXEC) ? UF_EXCLOSE : 0, &fp, + &indx)) != 0) { 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; diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 3c9b6b88aaf..8fd0dc38efc 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: filedesc.h,v 1.33 2017/01/25 06:15:50 mpi Exp $ */ +/* $OpenBSD: filedesc.h,v 1.34 2017/02/11 19:51:06 guenther Exp $ */ /* $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $ */ /* @@ -125,7 +125,7 @@ void filedesc_init(void); int dupfdopen(struct proc *, int, int); int fdalloc(struct proc *p, int want, int *result); void fdexpand(struct proc *); -int falloc(struct proc *p, struct file **resultfp, int *resultfd); +int falloc(struct proc *_p, int _flags, struct file **_rfp, int *_rfd); struct filedesc *fdinit(void); struct filedesc *fdshare(struct process *); struct filedesc *fdcopy(struct process *); |