Author: kevans Date: Wed Sep 25 19:20:41 2019 New Revision: 352711 URL: https://svnweb.freebsd.org/changeset/base/352711
Log: rfork(2): add RFSPAWN flag When RFSPAWN is passed, rfork exhibits vfork(2) semantics but also resets signal handlers in the child during creation to avoid a point of corruption of parent state from the child. This flag will be used by posix_spawn(3) to handle potential signal issues. Reviewed by: jilles, kib Differential Revision: https://reviews.freebsd.org/D19058 Modified: head/lib/libc/sys/rfork.2 head/sys/kern/kern_fork.c head/sys/kern/kern_sig.c head/sys/sys/proc.h head/sys/sys/signalvar.h head/sys/sys/unistd.h Modified: head/lib/libc/sys/rfork.2 ============================================================================== --- head/lib/libc/sys/rfork.2 Wed Sep 25 18:50:57 2019 (r352710) +++ head/lib/libc/sys/rfork.2 Wed Sep 25 19:20:41 2019 (r352711) @@ -5,7 +5,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 12, 2011 +.Dd September 25, 2019 .Dt RFORK 2 .Os .Sh NAME @@ -34,7 +34,9 @@ and open files. The .Fa flags argument -is the logical OR of some subset of: +is either +.Dv RFSPAWN +or the logical OR of some subset of: .Bl -tag -width ".Dv RFLINUXTHPN" .It Dv RFPROC If set a new process is created; otherwise changes affect the @@ -103,6 +105,14 @@ This is intended to mimic certain Linux clone behaviou File descriptors in a shared file descriptor table are kept open until either they are explicitly closed or all processes sharing the table exit. +.Pp +If +.Dv RFSPAWN +is passed, +.Nm +will use +.Xr vfork 2 +semantics but reset all signal actions in the child to default. .Pp If .Dv RFPROC Modified: head/sys/kern/kern_fork.c ============================================================================== --- head/sys/kern/kern_fork.c Wed Sep 25 18:50:57 2019 (r352710) +++ head/sys/kern/kern_fork.c Wed Sep 25 19:20:41 2019 (r352711) @@ -170,10 +170,18 @@ sys_rfork(struct thread *td, struct rfork_args *uap) /* Don't allow kernel-only flags. */ if ((uap->flags & RFKERNELONLY) != 0) return (EINVAL); + /* RFSPAWN must not appear with others */ + if ((uap->flags & RFSPAWN) != 0 && uap->flags != RFSPAWN) + return (EINVAL); AUDIT_ARG_FFLAGS(uap->flags); bzero(&fr, sizeof(fr)); - fr.fr_flags = uap->flags; + if ((uap->flags & RFSPAWN) != 0) { + fr.fr_flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; + fr.fr_flags2 = FR2_DROPSIG_CAUGHT; + } else { + fr.fr_flags = uap->flags; + } fr.fr_pidp = &pid; error = fork1(td, &fr); if (error == 0) { @@ -471,6 +479,11 @@ do_fork(struct thread *td, struct fork_req *fr, struct } else { sigacts_copy(newsigacts, p1->p_sigacts); p2->p_sigacts = newsigacts; + if ((fr->fr_flags2 & FR2_DROPSIG_CAUGHT) != 0) { + mtx_lock(&p2->p_sigacts->ps_mtx); + sig_drop_caught(p2); + mtx_unlock(&p2->p_sigacts->ps_mtx); + } } if (fr->fr_flags & RFTSIGZMB) Modified: head/sys/kern/kern_sig.c ============================================================================== --- head/sys/kern/kern_sig.c Wed Sep 25 18:50:57 2019 (r352710) +++ head/sys/kern/kern_sig.c Wed Sep 25 19:20:41 2019 (r352711) @@ -986,12 +986,7 @@ execsigs(struct proc *p) PROC_LOCK_ASSERT(p, MA_OWNED); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); - while (SIGNOTEMPTY(ps->ps_sigcatch)) { - sig = sig_ffs(&ps->ps_sigcatch); - sigdflt(ps, sig); - if ((sigprop(sig) & SIGPROP_IGNORE) != 0) - sigqueue_delete_proc(p, sig); - } + sig_drop_caught(p); /* * As CloudABI processes cannot modify signal handlers, fully @@ -3856,4 +3851,21 @@ sigacts_shared(struct sigacts *ps) { return (ps->ps_refcnt > 1); +} + +void +sig_drop_caught(struct proc *p) +{ + int sig; + struct sigacts *ps; + + ps = p->p_sigacts; + PROC_LOCK_ASSERT(p, MA_OWNED); + mtx_assert(&ps->ps_mtx, MA_OWNED); + while (SIGNOTEMPTY(ps->ps_sigcatch)) { + sig = sig_ffs(&ps->ps_sigcatch); + sigdflt(ps, sig); + if ((sigprop(sig) & SIGPROP_IGNORE) != 0) + sigqueue_delete_proc(p, sig); + } } Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Wed Sep 25 18:50:57 2019 (r352710) +++ head/sys/sys/proc.h Wed Sep 25 19:20:41 2019 (r352711) @@ -1006,6 +1006,8 @@ struct fork_req { int *fr_pd_fd; int fr_pd_flags; struct filecaps *fr_pd_fcaps; + int fr_flags2; +#define FR2_DROPSIG_CAUGHT 0x00001 /* Drop caught non-DFL signals */ }; /* Modified: head/sys/sys/signalvar.h ============================================================================== --- head/sys/sys/signalvar.h Wed Sep 25 18:50:57 2019 (r352710) +++ head/sys/sys/signalvar.h Wed Sep 25 19:20:41 2019 (r352711) @@ -381,6 +381,7 @@ void sigacts_copy(struct sigacts *dest, struct sigacts void sigacts_free(struct sigacts *ps); struct sigacts *sigacts_hold(struct sigacts *ps); int sigacts_shared(struct sigacts *ps); +void sig_drop_caught(struct proc *p); void sigexit(struct thread *td, int sig) __dead2; int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **); int sig_ffs(sigset_t *set); Modified: head/sys/sys/unistd.h ============================================================================== --- head/sys/sys/unistd.h Wed Sep 25 18:50:57 2019 (r352710) +++ head/sys/sys/unistd.h Wed Sep 25 19:20:41 2019 (r352711) @@ -188,11 +188,14 @@ #define RFTSIGNUM(flags) (((flags) >> RFTSIGSHIFT) & RFTSIGMASK) #define RFTSIGFLAGS(signum) ((signum) << RFTSIGSHIFT) #define RFPROCDESC (1<<28) /* return a process descriptor */ -#define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */ +/* kernel: parent sleeps until child exits (vfork) */ +#define RFPPWAIT (1<<31) +/* user: vfork(2) semantics, clear signals */ +#define RFSPAWN (1U<<31) #define RFFLAGS (RFFDG | RFPROC | RFMEM | RFNOWAIT | RFCFDG | \ RFTHREAD | RFSIGSHARE | RFLINUXTHPN | RFSTOPPED | RFHIGHPID | RFTSIGZMB | \ - RFPROCDESC | RFPPWAIT) -#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPPWAIT | RFPROCDESC) + RFPROCDESC | RFSPAWN | RFPPWAIT) +#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPROCDESC) #endif /* __BSD_VISIBLE */ _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"