Reland "Add optional signal forwarder and '-z' option to cli"
This is a reland of https://android-review.googlesource.com/#/c/365114/,
using NSIG instead of SIGUNUSED.
This reverts commit 7151582f0b847b62ec74c600dd6b99e8a0078c75.
Bug: None
Test: Build for ARM, MIPS, x86.
Change-Id: I5135c5c36fb4f98467790efaa0cba6d82e2ca2b6
diff --git a/libminijail.c b/libminijail.c
index 2e3e8b6..1da4e19 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -127,6 +127,7 @@
int reset_signal_mask : 1;
int close_open_fds : 1;
int new_session_keyring : 1;
+ int forward_signals : 1;
} flags;
uid_t uid;
gid_t gid;
@@ -169,6 +170,7 @@
j->flags.do_init = 0;
j->flags.pid_file = 0;
j->flags.cgroups = 0;
+ j->flags.forward_signals = 0;
}
/*
@@ -619,6 +621,12 @@
return 0;
}
+int API minijail_forward_signals(struct minijail *j)
+{
+ j->flags.forward_signals = 1;
+ return 0;
+}
+
int API minijail_mount_with_data(struct minijail *j, const char *src,
const char *dest, const char *type,
unsigned long flags, const char *data)
@@ -1504,6 +1512,42 @@
}
}
+static pid_t forward_pid = -1;
+
+static void forward_signal(__attribute__((unused)) int nr,
+ __attribute__((unused)) siginfo_t *siginfo,
+ __attribute__((unused)) void *void_context)
+{
+ if (forward_pid != -1) {
+ kill(forward_pid, nr);
+ }
+}
+
+static void install_signal_handlers(void)
+{
+ struct sigaction act;
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = &forward_signal;
+ act.sa_flags = SA_SIGINFO | SA_RESTART;
+
+ /* Handle all signals, except SIGCHLD. */
+ for (int nr = 1; nr < NSIG; nr++) {
+ /*
+ * We don't care if we get EINVAL: that just means that we
+ * can't handle this signal, so let's skip it and continue.
+ */
+ sigaction(nr, &act, NULL);
+ }
+ /* Reset SIGCHLD's handler. */
+ signal(SIGCHLD, SIG_DFL);
+
+ /* Handle real-time signals. */
+ for (int nr = SIGRTMIN; nr <= SIGRTMAX; nr++) {
+ sigaction(nr, &act, NULL);
+ }
+}
+
void API minijail_enter(const struct minijail *j)
{
/*
@@ -2022,6 +2066,11 @@
j->initpid = child_pid;
+ if (j->flags.forward_signals) {
+ forward_pid = child_pid;
+ install_signal_handlers();
+ }
+
if (j->flags.pid_file)
write_pid_file_or_die(j);
diff --git a/libminijail.h b/libminijail.h
index 9177ca8..a1f2f74 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -104,6 +104,12 @@
int minijail_add_to_cgroup(struct minijail *j, const char *path);
/*
+ * Install signal handlers in the minijail process that forward received
+ * signals to the jailed child process.
+ */
+int minijail_forward_signals(struct minijail *j);
+
+/*
* minijail_enter_chroot: enables chroot() restriction for @j
* @j minijail to apply restriction to
* @dir directory to chroot() to. Owned by caller.
diff --git a/minijail0.c b/minijail0.c
index 470a8df..b9f4e5a 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -111,7 +111,7 @@
{
size_t i;
/* clang-format off */
- printf("Usage: %s [-GhHiIKlLnNprstUvyY]\n"
+ printf("Usage: %s [-GhHiIKlLnNprstUvyYz]\n"
" [-a <table>]\n"
" [-b <src>,<dest>[,<writeable>]] [-k <src>,<dest>,<type>[,<flags>][,<data>]]\n"
" [-c <caps>] [-C <dir>] [-P <dir>] [-e[file]] [-f <file>] [-g <group>]\n"
@@ -177,6 +177,7 @@
" -V <file>: Enter specified mount namespace.\n"
" -w: Create and join a new anonymous session keyring.\n"
" -Y: Synchronize seccomp filters across thread group.\n"
+ " -z: Don't forward signals to jailed process.\n"
" --ambient: Raise ambient capabilities. Requires -c.\n");
/* clang-format on */
}
@@ -197,6 +198,7 @@
{
int opt;
int use_seccomp_filter = 0;
+ int forward = 1;
int binding = 0;
int chroot = 0, pivot_root = 0;
int mount_ns = 0, skip_remount = 0;
@@ -210,7 +212,7 @@
return 1;
const char *optstring =
- "u:g:sS:c:C:P:b:V:f:m::M::k:a:e::T:vrGhHinNplLt::IUKwyY";
+ "u:g:sS:c:C:P:b:V:f:m::M::k:a:e::T:vrGhHinNplLt::IUKwyYz";
int longoption_index = 0;
/* clang-format off */
const struct option long_options[] = {
@@ -434,6 +436,9 @@
case 'Y':
minijail_set_seccomp_filter_tsync(j);
break;
+ case 'z':
+ forward = 0;
+ break;
/* Long options. */
case 128: /* Ambient caps. */
ambient_caps = 1;
@@ -454,6 +459,10 @@
exit(1);
}
+ /* Set up signal handlers in minijail unless asked not to. */
+ if (forward)
+ minijail_forward_signals(j);
+
/* Only allow bind mounts when entering a chroot or using pivot_root. */
if (binding && !(chroot || pivot_root)) {
fprintf(stderr, "Can't add bind mounts without chroot or"