From b3a734483e9263c26570003a96701df3d7538048 Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Wed, 8 Jun 2016 02:09:14 +0000 Subject: [PATCH] Introduce the PD_CLOEXEC for pdfork(2). Reviewed by: mjg --- lib/libc/sys/pdfork.2 | 6 +++++- sys/kern/kern_fork.c | 8 ++++++-- sys/kern/sys_procdesc.c | 16 ++++++++++++++++ sys/sys/procdesc.h | 6 ++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/libc/sys/pdfork.2 b/lib/libc/sys/pdfork.2 index e057f769b89e..5f1a86e3b961 100644 --- a/lib/libc/sys/pdfork.2 +++ b/lib/libc/sys/pdfork.2 @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 7, 2014 +.Dd June 8, 2016 .Dt PDFORK 2 .Os .Sh NAME @@ -80,6 +80,10 @@ This option is not permitted in capability mode (see .Xr cap_enter 2 ) . .El +.Bl -tag -width ".Dv PD_DAEMON" +.It Dv PD_CLOEXEC +Set close-on-exec on process descriptor. +.El .Pp .Fn pdgetpid queries the process ID (PID) in the process descriptor diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index e00409767f75..1260c98e727c 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -827,6 +827,10 @@ fork1(struct thread *td, struct fork_req *fr) /* Must provide a place to put a procdesc if creating one. */ if (fr->fr_pd_fd == NULL) return (EINVAL); + + /* Check if we are using supported flags. */ + if ((fr->fr_pd_flags & ~PD_ALLOWED_AT_FORK) != 0) + return (EINVAL); } p1 = td->td_proc; @@ -878,8 +882,8 @@ fork1(struct thread *td, struct fork_req *fr) * later. */ if (flags & RFPROCDESC) { - error = falloc_caps(td, &fp_procdesc, fr->fr_pd_fd, 0, - fr->fr_pd_fcaps); + error = procdesc_falloc(td, &fp_procdesc, fr->fr_pd_fd, + fr->fr_pd_flags, fr->fr_pd_fcaps); if (error != 0) goto fail2; } diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c index 0d3b1f4334bd..37139c1243aa 100644 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -242,6 +242,22 @@ procdesc_new(struct proc *p, int flags) refcount_init(&pd->pd_refcount, 2); } +/* + * Create a new process decriptor for the process that refers to it. + */ +int +procdesc_falloc(struct thread *td, struct file **resultfp, int *resultfd, + int flags, struct filecaps *fcaps) +{ + int fflags; + + fflags = 0; + if (flags & PD_CLOEXEC) + fflags = O_CLOEXEC; + + return (falloc_caps(td, resultfp, resultfd, fflags, fcaps)); +} + /* * Initialize a file with a process descriptor. */ diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h index 1a3bc98d1322..a9bad27361b2 100644 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -101,6 +101,9 @@ void procdesc_finit(struct procdesc *, struct file *); pid_t procdesc_pid(struct file *); void procdesc_reap(struct proc *); +int procdesc_falloc(struct thread *, struct file **, int *, int, + struct filecaps *); + #else /* !_KERNEL */ #include @@ -127,5 +130,8 @@ __END_DECLS * Flags which can be passed to pdfork(2). */ #define PD_DAEMON 0x00000001 /* Don't exit when procdesc closes. */ +#define PD_CLOEXEC 0x00000002 /* Close file descriptor on exec. */ + +#define PD_ALLOWED_AT_FORK (PD_DAEMON | PD_CLOEXEC) #endif /* !_SYS_PROCDESC_H_ */