coreutils
[Top][All Lists]
Advanced

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

[PATCH] timeout: Ensure SIGCHLD signal is not blocked


From: Thomas Jarosch
Subject: [PATCH] timeout: Ensure SIGCHLD signal is not blocked
Date: Wed, 18 Oct 2017 18:47:49 +0200

We inherit the signal mask from our parent process,
therefore ensure SIGCHLD is not blocked.

If SIGCHLD is blocked, sigsuspend() won't be interrupted
when the child process exits and we hang until the timeout (SIGALRM).

The issue has been found by an "autotest" testsuite
doing high level tests of a custom distribution.
One complex test case got stuck 100% of the time.

This fixes a regression from

commit 2f69dba5df8caaf9eda658c1808b1379e9949f22
Author: Tobias Stoeckmann <address@hidden>
Date:   Sun Feb 5 13:23:22 2017 +0100

    timeout: fix race possibly terminating wrong process


Please CC: comments, I'm not subscribed to the list.

Signed-off-by: Thomas Jarosch <address@hidden>
---
 src/timeout.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/src/timeout.c b/src/timeout.c
index a58b84f4e..aa2fff7d9 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -323,6 +323,16 @@ parse_duration (const char* str)
   return duration;
 }
 
+static void
+unblock_signal (int sig)
+{
+  sigset_t unblock_set;
+  sigemptyset (&unblock_set);
+  sigaddset (&unblock_set, sig);
+  if (sigprocmask (SIG_UNBLOCK, &unblock_set, NULL) != 0)
+    error (0, errno, _("warning: sigprocmask"));
+}
+
 static void
 install_sigchld (void)
 {
@@ -333,6 +343,10 @@ install_sigchld (void)
                                  more likely to work cleanly.  */
 
   sigaction (SIGCHLD, &sa, NULL);
+
+  /* we inherit the signal mask from our parent process,
+     ensure SIGCHLD is not blocked. */
+  unblock_signal(SIGCHLD);
 }
 
 static void
@@ -369,16 +383,6 @@ block_cleanup (int sigterm, sigset_t *old_set)
     error (0, errno, _("warning: sigprocmask"));
 }
 
-static void
-unblock_signal (int sig)
-{
-  sigset_t unblock_set;
-  sigemptyset (&unblock_set);
-  sigaddset (&unblock_set, sig);
-  if (sigprocmask (SIG_UNBLOCK, &unblock_set, NULL) != 0)
-    error (0, errno, _("warning: sigprocmask"));
-}
-
 /* Try to disable core dumps for this process.
    Return TRUE if successful, FALSE otherwise.  */
 static bool
-- 
2.14.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]