Page MenuHomeFreeBSD

D19058.id53532.diff
No OneTemporary

D19058.id53532.diff

Index: lib/libc/gen/posix_spawn.c
===================================================================
--- lib/libc/gen/posix_spawn.c
+++ lib/libc/gen/posix_spawn.c
@@ -203,7 +203,14 @@
pid_t p;
volatile int error = 0;
- p = vfork();
+ /*
+ * Passing RFSPAWN to rfork(2) gives us effectively a vfork that drops
+ * non-ignored signal handlers. We'll fall back to the slightly less
+ * ideal vfork(2) if we get an EINVAL from rfork.
+ */
+ p = rfork(RFSPAWN);
+ if (p == -1 && errno == EINVAL)
+ p = vfork();
switch (p) {
case -1:
return (errno);
Index: lib/libc/sys/rfork.2
===================================================================
--- lib/libc/sys/rfork.2
+++ lib/libc/sys/rfork.2
@@ -5,7 +5,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 12, 2011
+.Dd February 1, 2019
.Dt RFORK 2
.Os
.Sh NAME
@@ -34,7 +34,9 @@
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
@@ -105,6 +107,14 @@
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
is set, the
value returned in the parent process
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -172,10 +172,17 @@
/* 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) {
@@ -476,6 +483,8 @@
} else {
sigacts_copy(newsigacts, p1->p_sigacts);
p2->p_sigacts = newsigacts;
+ if ((fr->fr_flags2 & FR2_DROPSIG_CAUGHT) != 0)
+ sig_drop_caught(p2);
}
if (fr->fr_flags & RFTSIGZMB)
Index: sys/kern/kern_sig.c
===================================================================
--- sys/kern/kern_sig.c
+++ sys/kern/kern_sig.c
@@ -985,12 +985,7 @@
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
@@ -3838,3 +3833,18 @@
return (ps->ps_refcnt > 1);
}
+
+void
+sig_drop_caught(struct proc *p)
+{
+ int sig;
+ struct sigacts *ps;
+
+ ps = p->p_sigacts;
+ 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);
+ }
+}
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -997,6 +997,8 @@
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 */
};
/*
Index: sys/sys/signalvar.h
===================================================================
--- sys/sys/signalvar.h
+++ sys/sys/signalvar.h
@@ -381,6 +381,7 @@
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);
Index: sys/sys/unistd.h
===================================================================
--- sys/sys/unistd.h
+++ sys/sys/unistd.h
@@ -188,11 +188,13 @@
#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)
+#define RFSPAWN (1<<31) /* user: vfork(2) semantics, clear signals */
#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 */

File Metadata

Mime Type
text/plain
Expires
Tue, Jun 23, 8:03 PM (16 h, 31 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34257906
Default Alt Text
D19058.id53532.diff (4 KB)

Event Timeline