Skip to content

Commit 223f192

Browse files
aaruni96earlchew
authored andcommitted
Add patch from containers#402
[bubblewrap] Propagate SIGTERM and SIGINT to child Co-authored-by: Earl Chew <earl_chew@yahoo.com> Signed-off-by: Aaruni Kaushik <akaushik@mathematik.uni-kl.de>
1 parent dc63ec6 commit 223f192

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
@@ -383,6 +383,25 @@ handle_die_with_parent (void)
383383
die_with_error ("prctl");
384384
}
385385

386+
static void
387+
gate_signals (int action, sigset_t *prevmask)
388+
{
389+
sigset_t mask;
390+
391+
/* When unblocking, only restore if not previously blocked. */
392+
393+
sigemptyset (&mask);
394+
395+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGINT))
396+
sigaddset (&mask, SIGINT);
397+
398+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGTERM))
399+
sigaddset (&mask, SIGTERM);
400+
401+
if (sigprocmask (action, &mask, prevmask) == -1)
402+
die_with_error ("sigprocmask");
403+
}
404+
386405
static void
387406
block_sigchild (void)
388407
{
@@ -518,6 +537,8 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
518537

519538
sigemptyset (&mask);
520539
sigaddset (&mask, SIGCHLD);
540+
sigaddset (&mask, SIGINT);
541+
sigaddset (&mask, SIGTERM);
521542

522543
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
523544
if (signal_fd == -1)
@@ -557,12 +578,17 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
557578
}
558579

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

587+
/* Propagate signal to child so that it will take the correct
588+
* action. This avoids the parent terminating, leaving an orphan. */
589+
if (fdsi.ssi_signo != SIGCHLD && kill (child_pid, fdsi.ssi_signo))
590+
die_with_error ("kill child");
591+
566592
/* We may actually get several sigchld compressed into one
567593
SIGCHLD, so we have to handle all of them. */
568594
while ((died_pid = waitpid (-1, &died_status, WNOHANG)) > 0)
@@ -2716,6 +2742,7 @@ main (int argc,
27162742
cleanup_free char *args_data UNUSED = NULL;
27172743
int intermediate_pids_sockets[2] = {-1, -1};
27182744
const char *exec_path = NULL;
2745+
sigset_t sigmask;
27192746

27202747
/* Handle --version early on before we try to acquire/drop
27212748
* any capabilities so it works in a build environment;
@@ -2889,6 +2916,9 @@ main (int argc,
28892916
/* We block sigchild here so that we can use signalfd in the monitor. */
28902917
block_sigchild ();
28912918

2919+
/* We block other signals here to avoid leaving an orphan. */
2920+
gate_signals (SIG_BLOCK, &sigmask);
2921+
28922922
clone_flags = SIGCHLD | CLONE_NEWNS;
28932923
if (opt_unshare_user)
28942924
clone_flags |= CLONE_NEWUSER;
@@ -3039,6 +3069,9 @@ main (int argc,
30393069
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
30403070
}
30413071

3072+
/* Unblock other signals here to receive signals from the parent. */
3073+
gate_signals (SIG_UNBLOCK, &sigmask);
3074+
30423075
if (opt_pidns_fd > 0)
30433076
{
30443077
if (setns (opt_pidns_fd, CLONE_NEWPID) != 0)

0 commit comments

Comments
 (0)