Skip to content

Commit 9fe7aeb

Browse files
committed
Add option to propagate common signals to sandboxed process
Signed-off-by: Aaruni Kaushik <akaushik@mathematik.uni-kl.de>
1 parent 1206a20 commit 9fe7aeb

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
@@ -78,6 +78,7 @@ static bool opt_unshare_cgroup_try = false;
7878
static bool opt_needs_devpts = false;
7979
static bool opt_new_session = false;
8080
static bool opt_die_with_parent = false;
81+
static bool opt_forward_signals = false;
8182
static uid_t opt_sandbox_uid = -1;
8283
static gid_t opt_sandbox_gid = -1;
8384
static int opt_sync_fd = -1;
@@ -373,6 +374,7 @@ usage (int ecode, FILE *out)
373374
" --perms OCTAL Set permissions of next argument (--bind-data, --file, etc.)\n"
374375
" --size BYTES Set size of next argument (only for --tmpfs)\n"
375376
" --chmod OCTAL PATH Change permissions of PATH (must already exist)\n"
377+
" --forward-signals Forward various commonly used signals to the child process.\n"
376378
);
377379
exit (ecode);
378380
}
@@ -387,22 +389,30 @@ handle_die_with_parent (void)
387389
die_with_error ("prctl");
388390
}
389391

392+
static int forwarded_signals[] =
393+
{
394+
SIGINT,
395+
SIGTERM,
396+
SIGCONT,
397+
SIGHUP,
398+
SIGQUIT,
399+
SIGUSR1,
400+
SIGUSR2,
401+
SIGWINCH,
402+
};
403+
390404
static void
391-
gate_signals (int action, sigset_t *prevmask)
405+
block_forwarded_signals (sigset_t *prevmask)
392406
{
393407
sigset_t mask;
394-
395-
/* When unblocking, only restore if not previously blocked. */
408+
size_t i;
396409

397410
sigemptyset (&mask);
398411

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

405-
if (sigprocmask (action, &mask, prevmask) == -1)
415+
if (sigprocmask (SIG_BLOCK, &mask, prevmask) == -1)
406416
die_with_error ("sigprocmask");
407417
}
408418

@@ -527,6 +537,7 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
527537
int exitc;
528538
pid_t died_pid;
529539
int died_status;
540+
size_t i;
530541

531542
/* Close all extra fds in the monitoring process.
532543
Any passed in fds have been passed on to the child anyway. */
@@ -541,8 +552,9 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
541552

542553
sigemptyset (&mask);
543554
sigaddset (&mask, SIGCHLD);
544-
sigaddset (&mask, SIGINT);
545-
sigaddset (&mask, SIGTERM);
555+
556+
for (i = 0; i < N_ELEMENTS (forwarded_signals); i++)
557+
sigaddset (&mask, forwarded_signals[i]);
546558

547559
signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
548560
if (signal_fd == -1)
@@ -590,8 +602,12 @@ monitor_child (int event_fd, pid_t child_pid, int setup_finished_fd)
590602

591603
/* Propagate signal to child so that it will take the correct
592604
* 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");
605+
if (fdsi.ssi_signo != SIGCHLD)
606+
{
607+
s = kill (child_pid, fdsi.ssi_signo);
608+
if (s != 0 && s != ESRCH)
609+
die_with_error("kill child");
610+
}
595611

596612
/* We may actually get several sigchld compressed into one
597613
SIGCHLD, so we have to handle all of them. */
@@ -2768,6 +2784,10 @@ parse_args_recurse (int *argcp,
27682784
argc -= 1;
27692785
break;
27702786
}
2787+
else if (strcmp (arg, "--forward-signals") == 0)
2788+
{
2789+
opt_forward_signals = true;
2790+
}
27712791
else if (*arg == '-')
27722792
{
27732793
die ("Unknown option %s", arg);
@@ -2915,7 +2935,8 @@ main (int argc,
29152935
int intermediate_pids_sockets[2] = {-1, -1};
29162936
const char *exec_path = NULL;
29172937
int i;
2918-
sigset_t sigmask;
2938+
sigset_t sigmask_before_forwarding;
2939+
sigemptyset (&sigmask_before_forwarding);
29192940

29202941
/* Handle --version early on before we try to acquire/drop
29212942
* any capabilities so it works in a build environment;
@@ -3090,7 +3111,8 @@ main (int argc,
30903111
block_sigchild ();
30913112

30923113
/* We block other signals here to avoid leaving an orphan. */
3093-
gate_signals (SIG_BLOCK, &sigmask);
3114+
if (opt_forward_signals)
3115+
block_forwarded_signals (&sigmask_before_forwarding);
30943116

30953117
clone_flags = SIGCHLD | CLONE_NEWNS;
30963118
if (opt_unshare_user)
@@ -3242,8 +3264,12 @@ main (int argc,
32423264
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
32433265
}
32443266

3245-
/* Unblock other signals here to receive signals from the parent. */
3246-
gate_signals (SIG_UNBLOCK, &sigmask);
3267+
/* Restore the state of sigmask from before the blocking. */
3268+
if (opt_forward_signals)
3269+
{
3270+
if (sigprocmask (SIG_SETMASK, &sigmask_before_forwarding, NULL) != 0)
3271+
die_with_error ("sigprocmask");
3272+
}
32473273

32483274
if (opt_pidns_fd > 0)
32493275
{

0 commit comments

Comments
 (0)