Skip to content

Commit b2d0eee

Browse files
committed
Add patch from containers#402
Signed-off-by: Aaruni Kaushik <akaushik@mathematik.uni-kl.de>
1 parent ad76c2d commit b2d0eee

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

bubblewrap.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,25 @@ handle_die_with_parent (void)
379379
die_with_error ("prctl");
380380
}
381381

382+
static void
383+
gate_signals (int action, sigset_t *prevmask)
384+
{
385+
sigset_t mask;
386+
387+
/* When unblocking, only restore if not previously blocked. */
388+
389+
sigemptyset (&mask);
390+
391+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGINT))
392+
sigaddset (&mask, SIGINT);
393+
394+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGTERM))
395+
sigaddset (&mask, SIGTERM);
396+
397+
if (sigprocmask (action, &mask, prevmask) == -1)
398+
die_with_error ("sigprocmask");
399+
}
400+
382401
static void
383402
block_sigchild (void)
384403
{
@@ -514,6 +533,8 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
514533

515534
sigemptyset (&mask);
516535
sigaddset (&mask, SIGCHLD);
536+
sigaddset (&mask, SIGINT);
537+
sigaddset (&mask, SIGTERM);
517538

518539
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
519540
if (signal_fd == -1)
@@ -553,12 +574,17 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
553574
}
554575

555576
/* We need to read the signal_fd, or it will keep polling as read,
556-
* however we ignore the details as we get them from waitpid
577+
* however we ignore the details for SIGCHLD as we get them from waitpid
557578
* below anyway */
558579
s = read (signal_fd, &fdsi, sizeof (struct signalfd_siginfo));
559580
if (s == -1 && errno != EINTR && errno != EAGAIN)
560581
die_with_error ("read signalfd");
561582

583+
/* Propagate signal to child so that it will take the correct
584+
* action. This avoids the parent terminating, leaving an orphan. */
585+
if (fdsi.ssi_signo != SIGCHLD && kill (child_pid, fdsi.ssi_signo))
586+
die_with_error ("kill child");
587+
562588
/* We may actually get several sigchld compressed into one
563589
SIGCHLD, so we have to handle all of them. */
564590
while ((died_pid = waitpid (-1, &died_status, WNOHANG)) > 0)
@@ -2641,6 +2667,7 @@ main (int argc,
26412667
int res UNUSED;
26422668
cleanup_free char *args_data UNUSED = NULL;
26432669
int intermediate_pids_sockets[2] = {-1, -1};
2670+
sigset_t sigmask;
26442671

26452672
/* Handle --version early on before we try to acquire/drop
26462673
* any capabilities so it works in a build environment;
@@ -2814,6 +2841,9 @@ main (int argc,
28142841
/* We block sigchild here so that we can use signalfd in the monitor. */
28152842
block_sigchild ();
28162843

2844+
/* We block other signals here to avoid leaving an orphan. */
2845+
gate_signals (SIG_BLOCK, &sigmask);
2846+
28172847
clone_flags = SIGCHLD | CLONE_NEWNS;
28182848
if (opt_unshare_user)
28192849
clone_flags |= CLONE_NEWUSER;
@@ -2964,6 +2994,9 @@ main (int argc,
29642994
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
29652995
}
29662996

2997+
/* Unblock other signals here to receive signals from the parent. */
2998+
gate_signals (SIG_UNBLOCK, &sigmask);
2999+
29673000
if (opt_pidns_fd > 0)
29683001
{
29693002
if (setns (opt_pidns_fd, CLONE_NEWPID) != 0)

0 commit comments

Comments
 (0)