Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Stop masking SIGSTOP in a vfork(2)ed child



details:   https://anonhg.NetBSD.org/src/rev/5647c6bb2672
branches:  trunk
changeset: 322809:5647c6bb2672
user:      kamil <kamil%NetBSD.org@localhost>
date:      Sat May 19 02:42:58 2018 +0000

description:
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>

diffstat:

 sys/kern/kern_sig.c         |  12 ++++++++----
 tests/lib/libc/sys/t_fork.c |  10 ++--------
 2 files changed, 10 insertions(+), 12 deletions(-)

diffs (91 lines):

diff -r 0d8fb89d868a -r 5647c6bb2672 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Sat May 19 01:53:24 2018 +0000
+++ b/sys/kern/kern_sig.c       Sat May 19 02:42:58 2018 +0000
@@ -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 @@
 
 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 @@
        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 @@
                        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 @@
                        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) {
diff -r 0d8fb89d868a -r 5647c6bb2672 tests/lib/libc/sys/t_fork.c
--- a/tests/lib/libc/sys/t_fork.c       Sat May 19 01:53:24 2018 +0000
+++ b/tests/lib/libc/sys/t_fork.c       Sat May 19 02:42:58 2018 +0000
@@ -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 @@
        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.



Home | Main Index | Thread Index | Old Index