minijail: Add option to enter a new IPC namespace
Export this feature through the '-l' option to minijail0.
TEST=run minijail0 with the -l option, check that the executed program
is in a different ipc namesspace with /proc/self/ns/ipc.
BUG=b/25770648
Change-Id: Ia8f72cc59160fc736c8a58cb68d9894f9c92281c
Signed-off-by: Dylan Reid <dgreid@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 544651a..e3b7a65 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -91,6 +91,7 @@
int vfs:1;
int enter_vfs:1;
int pids:1;
+ int ipc:1;
int net:1;
int enter_net:1;
int userns:1;
@@ -301,6 +302,11 @@
j->flags.do_init = 1;
}
+void API minijail_namespace_ipc(struct minijail *j)
+{
+ j->flags.ipc = 1;
+}
+
void API minijail_namespace_net(struct minijail *j)
{
j->flags.net = 1;
@@ -1125,6 +1131,10 @@
pdie("mount(/, private)");
}
+ if (j->flags.ipc && unshare(CLONE_NEWIPC)) {
+ pdie("unshare(ipc)");
+ }
+
if (j->flags.enter_net) {
if (setns(j->netns_fd, CLONE_NEWNET))
pdie("setns(CLONE_NEWNET)");
diff --git a/libminijail.h b/libminijail.h
index e7f24ce..9d92462 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -50,6 +50,7 @@
void minijail_use_caps(struct minijail *j, uint64_t capmask);
void minijail_namespace_vfs(struct minijail *j);
void minijail_namespace_enter_vfs(struct minijail *j, const char *ns_path);
+void minijail_namespace_ipc(struct minijail *j);
void minijail_namespace_net(struct minijail *j);
void minijail_namespace_enter_net(struct minijail *j, const char *ns_path);
/* Implies namespace_vfs and remount_proc_readonly.
diff --git a/minijail0.1 b/minijail0.1
index 1f3b126..122ecc5 100644
--- a/minijail0.1
+++ b/minijail0.1
@@ -49,6 +49,10 @@
(Other direct numbers may be specified if minijail0 is not in sync with the
host kernel or something like 32/64-bit compatibility issues exist.)
.TP
+\fB-l\fR
+Run inside a new IPC namespace. This option makes the program's System V IPC
+namespace independent.
+.TP
\fB-p\fR
Run inside a new PID namespace. This option will make it impossible for the
program to see or affect processes that are not its descendants. This implies
diff --git a/minijail0.c b/minijail0.c
index 68c9478..fb0b3b3 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -93,7 +93,7 @@
{
size_t i;
- printf("Usage: %s [-GhiInprsvtU] [-b <src>,<dest>[,<writeable>]] [-f <file>]"
+ printf("Usage: %s [-GhiInprsvtUl] [-b <src>,<dest>[,<writeable>]] [-f <file>]"
"[-c <caps>] [-C <dir>] [-g <group>] [-S <file>] [-u <user>] "
"[-k <src>,<dest>,<type>[,<flags>]] "
"[-m \"<uid> <loweruid> <count>[,<uid> <loweruid> <count>]\"] "
@@ -116,6 +116,7 @@
" -i: exit immediately after fork (do not act as init)\n"
" Not compatible with -p\n"
" -I: run <program> as init (pid 1) inside a new pid namespace (implies -p)\n"
+ " -l: enter new IPC namespace\n"
" -L: report blocked syscalls to syslog when using seccomp filter.\n"
" Forces the following syscalls to be allowed:\n"
" ", progn);
@@ -166,7 +167,7 @@
if (argc > 1 && argv[1][0] != '-')
return 1;
while ((opt = getopt(argc, argv,
- "u:g:sS:c:C:P:b:V:f:m:M:k:a:e::vrGhHinpLtIU"))
+ "u:g:sS:c:C:P:b:V:f:m:M:k:a:e::vrGhHinplLtIU"))
!= -1) {
switch (opt) {
case 'u':
@@ -196,6 +197,9 @@
}
use_seccomp_filter = 1;
break;
+ case 'l':
+ minijail_namespace_ipc(j);
+ break;
case 'L':
minijail_log_seccomp_filter_failures(j);
break;