Skip to content

Commit 3e88c04

Browse files
committed
Add option to propagate common signals to sandboxed process
Signed-off-by: Aaruni Kaushik <akaushik@mathematik.uni-kl.de>
1 parent 8383f8c commit 3e88c04

1 file changed

Lines changed: 43 additions & 17 deletions

File tree

bubblewrap.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static bool opt_unshare_cgroup_try = FALSE;
8787
static bool opt_needs_devpts = FALSE;
8888
static bool opt_new_session = FALSE;
8989
static bool opt_die_with_parent = FALSE;
90+
static bool opt_forward_signals = FALSE;
9091
static uid_t opt_sandbox_uid = -1;
9192
static gid_t opt_sandbox_gid = -1;
9293
static int opt_sync_fd = -1;
@@ -367,6 +368,7 @@ usage (int ecode, FILE *out)
367368
" --perms OCTAL Set permissions of next argument (--bind-data, --file, etc.)\n"
368369
" --size BYTES Set size of next argument (only for --tmpfs)\n"
369370
" --chmod OCTAL PATH Change permissions of PATH (must already exist)\n"
371+
" --forward-signals Forward various commonly used signals to the child process.\n"
370372
);
371373
exit (ecode);
372374
}
@@ -381,22 +383,30 @@ handle_die_with_parent (void)
381383
die_with_error ("prctl");
382384
}
383385

386+
static int forwarded_signals[] =
387+
{
388+
SIGINT,
389+
SIGTERM,
390+
SIGCONT,
391+
SIGHUP,
392+
SIGQUIT,
393+
SIGUSR1,
394+
SIGUSR2,
395+
SIGWINCH,
396+
};
397+
384398
static void
385-
gate_signals (int action, sigset_t *prevmask)
399+
block_forwarded_signals (sigset_t *prevmask)
386400
{
387401
sigset_t mask;
388-
389-
/* When unblocking, only restore if not previously blocked. */
402+
size_t i;
390403

391404
sigemptyset (&mask);
392405

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);
406+
for (i = 0; i < N_ELEMENTS (forwarded_signals); i++)
407+
sigaddset (&mask, forwarded_signals[i]);
398408

399-
if (sigprocmask (action, &mask, prevmask) == -1)
409+
if (sigprocmask (SIG_BLOCK, &mask, prevmask) == -1)
400410
die_with_error ("sigprocmask");
401411
}
402412

@@ -521,6 +531,7 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
521531
int exitc;
522532
pid_t died_pid;
523533
int died_status;
534+
size_t i;
524535

525536
/* Close all extra fds in the monitoring process.
526537
Any passed in fds have been passed on to the child anyway. */
@@ -535,8 +546,9 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
535546

536547
sigemptyset (&mask);
537548
sigaddset (&mask, SIGCHLD);
538-
sigaddset (&mask, SIGINT);
539-
sigaddset (&mask, SIGTERM);
549+
550+
for (i = 0; i < N_ELEMENTS (forwarded_signals); i++)
551+
sigaddset (&mask, forwarded_signals[i]);
540552

541553
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
542554
if (signal_fd == -1)
@@ -584,8 +596,12 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
584596

585597
/* Propagate signal to child so that it will take the correct
586598
* 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");
599+
if (fdsi.ssi_signo != SIGCHLD)
600+
{
601+
s = kill (child_pid, fdsi.ssi_signo);
602+
if (s != 0 && s != ESRCH)
603+
die_with_error("kill child");
604+
}
589605

590606
/* We may actually get several sigchld compressed into one
591607
SIGCHLD, so we have to handle all of them. */
@@ -2553,6 +2569,10 @@ parse_args_recurse (int *argcp,
25532569
argc -= 1;
25542570
break;
25552571
}
2572+
else if (strcmp (arg, "--forward-signals") == 0)
2573+
{
2574+
opt_forward_signals = TRUE;
2575+
}
25562576
else if (*arg == '-')
25572577
{
25582578
die ("Unknown option %s", arg);
@@ -2692,7 +2712,8 @@ main (int argc,
26922712
cleanup_free char *args_data UNUSED = NULL;
26932713
int intermediate_pids_sockets[2] = {-1, -1};
26942714
const char *exec_path = NULL;
2695-
sigset_t sigmask;
2715+
sigset_t sigmask_before_forwarding;
2716+
sigemptyset (&sigmask_before_forwarding);
26962717

26972718
/* Handle --version early on before we try to acquire/drop
26982719
* any capabilities so it works in a build environment;
@@ -2867,7 +2888,8 @@ main (int argc,
28672888
block_sigchild ();
28682889

28692890
/* We block other signals here to avoid leaving an orphan. */
2870-
gate_signals (SIG_BLOCK, &sigmask);
2891+
if (opt_forward_signals)
2892+
block_forwarded_signals (&sigmask_before_forwarding);
28712893

28722894
clone_flags = SIGCHLD | CLONE_NEWNS;
28732895
if (opt_unshare_user)
@@ -3019,8 +3041,12 @@ main (int argc,
30193041
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
30203042
}
30213043

3022-
/* Unblock other signals here to receive signals from the parent. */
3023-
gate_signals (SIG_UNBLOCK, &sigmask);
3044+
/* Restore the state of sigmask from before the blocking. */
3045+
if (opt_forward_signals)
3046+
{
3047+
if (sigprocmask (SIG_SETMASK, &sigmask_before_forwarding, NULL) != 0)
3048+
die_with_error ("sigprocmask");
3049+
}
30243050

30253051
if (opt_pidns_fd > 0)
30263052
{

0 commit comments

Comments
 (0)