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