Skip to content

Commit 8383f8c

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 623780a commit 8383f8c

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
@@ -381,6 +381,25 @@ handle_die_with_parent (void)
381381
die_with_error ("prctl");
382382
}
383383

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

517536
sigemptyset (&mask);
518537
sigaddset (&mask, SIGCHLD);
538+
sigaddset (&mask, SIGINT);
539+
sigaddset (&mask, SIGTERM);
519540

520541
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
521542
if (signal_fd == -1)
@@ -555,12 +576,17 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
555576
}
556577

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

585+
/* Propagate signal to child so that it will take the correct
586+
* action. This avoids the parent terminating, leaving an orphan. */
587+
if (fdsi.ssi_signo != SIGCHLD && kill (child_pid, fdsi.ssi_signo))
588+
die_with_error ("kill child");
589+
564590
/* We may actually get several sigchld compressed into one
565591
SIGCHLD, so we have to handle all of them. */
566592
while ((died_pid = waitpid (-1, &died_status, WNOHANG)) > 0)
@@ -2666,6 +2692,7 @@ main (int argc,
26662692
cleanup_free char *args_data UNUSED = NULL;
26672693
int intermediate_pids_sockets[2] = {-1, -1};
26682694
const char *exec_path = NULL;
2695+
sigset_t sigmask;
26692696

26702697
/* Handle --version early on before we try to acquire/drop
26712698
* any capabilities so it works in a build environment;
@@ -2839,6 +2866,9 @@ main (int argc,
28392866
/* We block sigchild here so that we can use signalfd in the monitor. */
28402867
block_sigchild ();
28412868

2869+
/* We block other signals here to avoid leaving an orphan. */
2870+
gate_signals (SIG_BLOCK, &sigmask);
2871+
28422872
clone_flags = SIGCHLD | CLONE_NEWNS;
28432873
if (opt_unshare_user)
28442874
clone_flags |= CLONE_NEWUSER;
@@ -2989,6 +3019,9 @@ main (int argc,
29893019
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
29903020
}
29913021

3022+
/* Unblock other signals here to receive signals from the parent. */
3023+
gate_signals (SIG_UNBLOCK, &sigmask);
3024+
29923025
if (opt_pidns_fd > 0)
29933026
{
29943027
if (setns (opt_pidns_fd, CLONE_NEWPID) != 0)

0 commit comments

Comments
 (0)