Skip to content

Commit 1206a20

Browse files
aaruni96earlchew
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 c1bfc72 commit 1206a20

1 file changed

Lines changed: 34 additions & 1 deletion

File tree

bubblewrap.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,25 @@ handle_die_with_parent (void)
387387
die_with_error ("prctl");
388388
}
389389

390+
static void
391+
gate_signals (int action, sigset_t *prevmask)
392+
{
393+
sigset_t mask;
394+
395+
/* When unblocking, only restore if not previously blocked. */
396+
397+
sigemptyset (&mask);
398+
399+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGINT))
400+
sigaddset (&mask, SIGINT);
401+
402+
if (action == SIG_BLOCK || !sigismember (prevmask, SIGTERM))
403+
sigaddset (&mask, SIGTERM);
404+
405+
if (sigprocmask (action, &mask, prevmask) == -1)
406+
die_with_error ("sigprocmask");
407+
}
408+
390409
static void
391410
block_sigchild (void)
392411
{
@@ -522,6 +541,8 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
522541

523542
sigemptyset (&mask);
524543
sigaddset (&mask, SIGCHLD);
544+
sigaddset (&mask, SIGINT);
545+
sigaddset (&mask, SIGTERM);
525546

526547
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
527548
if (signal_fd == -1)
@@ -561,12 +582,17 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
561582
}
562583

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

591+
/* Propagate signal to child so that it will take the correct
592+
* action. This avoids the parent terminating, leaving an orphan. */
593+
if (fdsi.ssi_signo != SIGCHLD && kill (child_pid, fdsi.ssi_signo))
594+
die_with_error ("kill child");
595+
570596
/* We may actually get several sigchld compressed into one
571597
SIGCHLD, so we have to handle all of them. */
572598
while ((died_pid = waitpid (-1, &died_status, WNOHANG)) > 0)
@@ -2889,6 +2915,7 @@ main (int argc,
28892915
int intermediate_pids_sockets[2] = {-1, -1};
28902916
const char *exec_path = NULL;
28912917
int i;
2918+
sigset_t sigmask;
28922919

28932920
/* Handle --version early on before we try to acquire/drop
28942921
* any capabilities so it works in a build environment;
@@ -3062,6 +3089,9 @@ main (int argc,
30623089
/* We block sigchild here so that we can use signalfd in the monitor. */
30633090
block_sigchild ();
30643091

3092+
/* We block other signals here to avoid leaving an orphan. */
3093+
gate_signals (SIG_BLOCK, &sigmask);
3094+
30653095
clone_flags = SIGCHLD | CLONE_NEWNS;
30663096
if (opt_unshare_user)
30673097
clone_flags |= CLONE_NEWUSER;
@@ -3212,6 +3242,9 @@ main (int argc,
32123242
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
32133243
}
32143244

3245+
/* Unblock other signals here to receive signals from the parent. */
3246+
gate_signals (SIG_UNBLOCK, &sigmask);
3247+
32153248
if (opt_pidns_fd > 0)
32163249
{
32173250
if (setns (opt_pidns_fd, CLONE_NEWPID) != 0)

0 commit comments

Comments
 (0)