Source-Changes-HG archive

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

[src/netbsd-9]: src/bin/sh Pull up following revision(s) (requested by kre in...



details:   https://anonhg.NetBSD.org/src/rev/2aa0feff522a
branches:  netbsd-9
changeset: 744690:2aa0feff522a
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Feb 10 18:54:14 2020 +0000

description:
Pull up following revision(s) (requested by kre in ticket #684):

        bin/sh/jobs.c: revision 1.107
        bin/sh/main.c: revision 1.83
        bin/sh/main.c: revision 1.84
        bin/sh/main.c: revision 1.85

If we are invoked with SIGCHLD ignored, we fail badly, as we assume
that we can always wait(2) for our children, and an ignored SIGCHLD
prevents that.   Recent versions of bash can be convinced (due to a
bug most likely) to invoke us that way.   Always return SIGCHLD to
SIG_DFL during init - we already prevent scripts from fiddling it.

All ash derived shells apparently have this problem (observed by
Martijn Dekker, and notified on the bash-bug list).  Actual issue
diagnosed by Harald van Dijk (same list).

Actually, the issue with bash (in previous) is more likely that the
SIGCHLD is blocked rather than ignored.   We want neither.   Make sure
SIGCHLD is unblocked as well as SIG_DFL.

XXX pullup -9

bin/sh: Fixes -Werror=shadow causing build breaks.
Conflicting variable name, sigset_t sigs has been renamed to sigset_t mask

Reviewed by: kamil@

Avoid a core dump if a child process that is not one of our
children happens to exit while we are waiting for another child
to exit.

This can happen with code like
        sh -c '
                sleep 5 &
                exec sh -c "sleep 10 & wait !$"
              '

when the inner "sh" is waiting for the 10 second sleep to be
done, the 5 second sleep started earlier terminates.   It is
a child of our process, as the inner shell is the same process
as the outer one, but not a known child (the inner shell has no
idea what the outer one did before it started).

This was observed in the wild by Martijn Dekker (where the outer
shell was bash but that's irrelevant).

XXX pullup -9

diffstat:

 bin/sh/jobs.c |   7 +++++--
 bin/sh/main.c |  20 ++++++++++++++++++--
 2 files changed, 23 insertions(+), 4 deletions(-)

diffs (69 lines):

diff -r df214070f1a2 -r 2aa0feff522a bin/sh/jobs.c
--- a/bin/sh/jobs.c     Mon Feb 10 18:50:29 2020 +0000
+++ b/bin/sh/jobs.c     Mon Feb 10 18:54:14 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: jobs.c,v 1.106 2019/03/26 13:32:26 kre Exp $   */
+/*     $NetBSD: jobs.c,v 1.106.2.1 2020/02/10 18:54:14 martin Exp $    */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)jobs.c     8.5 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: jobs.c,v 1.106 2019/03/26 13:32:26 kre Exp $");
+__RCSID("$NetBSD: jobs.c,v 1.106.2.1 2020/02/10 18:54:14 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -820,6 +820,9 @@
                        if ((i = dowait(WBLOCK|WNOFREE, NULL, &job)) == -1)
                               return 128 + lastsig();
 
+                       if (job == NULL)        /* an interloper */
+                               continue;
+
                        /*
                         * one of the job's processes exited,
                         * but there are more
diff -r df214070f1a2 -r 2aa0feff522a bin/sh/main.c
--- a/bin/sh/main.c     Mon Feb 10 18:50:29 2020 +0000
+++ b/bin/sh/main.c     Mon Feb 10 18:54:14 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.82 2019/02/09 09:33:20 kre Exp $    */
+/*     $NetBSD: main.c,v 1.82.2.1 2020/02/10 18:54:14 martin Exp $     */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c     8.7 (Berkeley) 7/19/95";
 #else
-__RCSID("$NetBSD: main.c,v 1.82 2019/02/09 09:33:20 kre Exp $");
+__RCSID("$NetBSD: main.c,v 1.82.2.1 2020/02/10 18:54:14 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -108,6 +108,22 @@
        char *shinit;
        uid_t uid;
        gid_t gid;
+       sigset_t mask;
+
+       /*
+        * If we happen to be invoked with SIGCHLD ignored, we cannot
+        * successfully do almost anything.   Perhaps we should remember
+        * its state and pass it on ignored to children if it was ignored
+        * on entry, but that seems like just leaving the shit on the
+        * footpath for someone else to fall into...
+        */
+       (void)signal(SIGCHLD, SIG_DFL);
+       /*
+        * Similarly, SIGCHLD must not be blocked
+        */
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGCHLD);
+       sigprocmask(SIG_UNBLOCK, &mask, NULL);
 
        uid = getuid();
        gid = getgid();



Home | Main Index | Thread Index | Old Index