svn commit: r352711 - in head: lib/libc/sys sys/kern sys/sys
Kyle Evans
kevans at FreeBSD.org
Wed Sep 25 19:20:43 UTC 2019
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 */
More information about the svn-src-head
mailing list