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.