Module Name:    src
Committed By:   kamil
Date:           Sat May 19 02:42:59 UTC 2018

Modified Files:
        src/sys/kern: kern_sig.c
        src/tests/lib/libc/sys: t_fork.c

Log Message:
Stop masking SIGSTOP in a vfork(2)ed child

Keep the traditional BSD behavior masking SIGTSTP, SIGTTIN and SIGTTOU in
a vfork(2)ed child before exec(3)/exit(3). This is useful in shells and
prevents deadlocking, when a parent cannot unstop the sleeping child.

Change the behavior for SIGSTOP. This signal is by design not maskable and
this property shall be obeyed without exceptions. The STOP behavior is
expected in the context of debuggers and useful in standalone programs.

It is still possible to stop a vfork(2)ed child, however it requires
proc.curproc.stopfork=1, but it is not a flexible solution.

FreeBSD and OpenBSD keep masking SIGSTOP in a vfork(2)ed child.
Linux does not mask stop signals in the same scenarios.

This fixes ATF test: t_vfork:raise2.
No known regressions reported in the existing ATF tests.

Discussed with <kre>

Sponsored by <The NetBSD Foundation>


To generate a diff of this commit:
cvs rdiff -u -r1.344 -r1.345 src/sys/kern/kern_sig.c
cvs rdiff -u -r1.1 -r1.2 src/tests/lib/libc/sys/t_fork.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.344 src/sys/kern/kern_sig.c:1.345
--- src/sys/kern/kern_sig.c:1.344	Wed May 16 00:42:15 2018
+++ src/sys/kern/kern_sig.c	Sat May 19 02:42:58 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.344 2018/05/16 00:42:15 kamil Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.345 2018/05/19 02:42:58 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.344 2018/05/16 00:42:15 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.345 2018/05/19 02:42:58 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -114,6 +114,7 @@ static callout_t	proc_stop_ch	__cachelin
 
 sigset_t		contsigmask	__cacheline_aligned;
 static sigset_t		stopsigmask	__cacheline_aligned;
+static sigset_t		vforksigmask	__cacheline_aligned;
 sigset_t		sigcantmask	__cacheline_aligned;
 
 static void	ksiginfo_exechook(struct proc *, void *);
@@ -322,6 +323,7 @@ siginit(struct proc *p)
 	ps = p->p_sigacts;
 	sigemptyset(&contsigmask);
 	sigemptyset(&stopsigmask);
+	sigemptyset(&vforksigmask);
 	sigemptyset(&sigcantmask);
 	for (signo = 1; signo < NSIG; signo++) {
 		prop = sigprop[signo];
@@ -329,6 +331,8 @@ siginit(struct proc *p)
 			sigaddset(&contsigmask, signo);
 		if (prop & SA_STOP)
 			sigaddset(&stopsigmask, signo);
+		if (prop & SA_STOP && signo != SIGSTOP)
+			sigaddset(&vforksigmask, signo);
 		if (prop & SA_CANTMASK)
 			sigaddset(&sigcantmask, signo);
 		if (prop & SA_IGNORE && signo != SIGCONT)
@@ -1682,14 +1686,14 @@ issignal(struct lwp *l)
 			sp = &l->l_sigpend;
 			ss = sp->sp_set;
 			if ((p->p_lflag & PL_PPWAIT) != 0)
-				sigminusset(&stopsigmask, &ss);
+				sigminusset(&vforksigmask, &ss);
 			sigminusset(&l->l_sigmask, &ss);
 
 			if ((signo = firstsig(&ss)) == 0) {
 				sp = &p->p_sigpend;
 				ss = sp->sp_set;
 				if ((p->p_lflag & PL_PPWAIT) != 0)
-					sigminusset(&stopsigmask, &ss);
+					sigminusset(&vforksigmask, &ss);
 				sigminusset(&l->l_sigmask, &ss);
 
 				if ((signo = firstsig(&ss)) == 0) {

Index: src/tests/lib/libc/sys/t_fork.c
diff -u src/tests/lib/libc/sys/t_fork.c:1.1 src/tests/lib/libc/sys/t_fork.c:1.2
--- src/tests/lib/libc/sys/t_fork.c:1.1	Fri May 18 06:39:58 2018
+++ src/tests/lib/libc/sys/t_fork.c	Sat May 19 02:42:58 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_fork.c,v 1.1 2018/05/18 06:39:58 kamil Exp $	*/
+/*	$NetBSD: t_fork.c,v 1.2 2018/05/19 02:42:58 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2018\
  The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_fork.c,v 1.1 2018/05/18 06:39:58 kamil Exp $");
+__RCSID("$NetBSD: t_fork.c,v 1.2 2018/05/19 02:42:58 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -139,12 +139,6 @@ raise_raw(int sig)
 	pid_t child, parent, watcher, wpid;
 	int expect_core = (sig == SIGABRT) ? 1 : 0;
 
-#ifdef VFORK
-	if (sig == SIGSTOP) {
-		atf_tc_expect_fail("SIGSTOP shall not be ignored");
-	}
-#endif
-
 	/*
 	 * Spawn a dedicated thread to watch for a stopped child and emit
 	 * the SIGTERM signal to it.

Reply via email to