minijail: Support entering an existing net namespace.
When launching a full OS as the jailed process, it is useful to first be
able to configure a network namespace and start the new process in that
namespace.
This adds the "-e<net namespace file>" optional argument to -e. It
allows, for example, passing "-e/var/run/netns/newns" to minijail0.
Change-Id: I0613162072a1d14f10c58444c514f6d052c3d1e5
Signed-off-by: Dylan Reid <dgreid@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index a797823..4f2228a 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -87,6 +87,7 @@
int enter_vfs:1;
int pids:1;
int net:1;
+ int enter_net:1;
int userns:1;
int seccomp:1;
int remount_proc_ro:1;
@@ -108,6 +109,7 @@
uint64_t caps;
pid_t initpid;
int mountns_fd;
+ int netns_fd;
int filter_len;
int binding_count;
char *chrootdir;
@@ -297,6 +299,16 @@
j->flags.net = 1;
}
+void API minijail_namespace_enter_net(struct minijail *j, const char *ns_path)
+{
+ int ns_fd = open(ns_path, O_RDONLY);
+ if (ns_fd < 0) {
+ pdie("failed to open namespace '%s'", ns_path);
+ }
+ j->netns_fd = ns_fd;
+ j->flags.enter_net = 1;
+}
+
void API minijail_remount_proc_readonly(struct minijail *j)
{
j->flags.vfs = 1;
@@ -1011,8 +1023,12 @@
pdie("mount(/, private)");
}
- if (j->flags.net && unshare(CLONE_NEWNET))
+ if (j->flags.enter_net) {
+ if (setns(j->netns_fd, CLONE_NEWNET))
+ pdie("setns(CLONE_NEWNET)");
+ } else if (j->flags.net && unshare(CLONE_NEWNET)) {
pdie("unshare(net)");
+ }
if (j->flags.chroot && enter_chroot(j))
pdie("chroot");
diff --git a/libminijail.h b/libminijail.h
index 62e4007..bfce714 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -51,6 +51,7 @@
void minijail_namespace_vfs(struct minijail *j);
void minijail_namespace_enter_vfs(struct minijail *j, const char *ns_path);
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.
* WARNING: this is NOT THREAD SAFE. See the block comment in </libminijail.c>.
*/
diff --git a/minijail0.c b/minijail0.c
index 8329080..e272702 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -86,7 +86,7 @@
" -c <caps>: restrict caps to <caps>\n"
" -C <dir>: chroot to <dir>\n"
" Not compatible with -P\n"
- " -e: enter new network namespace\n"
+ " -e[file]: enter new network namespace, or existing one if 'file' is provided\n"
" -f <file>: write the pid of the jailed process to <file>\n"
" -G: inherit secondary groups from uid\n"
" -g <group>: change gid to <group>\n"
@@ -145,7 +145,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:vrGhHinpLetIU")) != -1) {
+ "u:g:sS:c:C:P:b:V:f:m:M:e::vrGhHinpLtIU")) != -1) {
switch (opt) {
case 'u':
set_user(j, optarg);
@@ -233,7 +233,10 @@
minijail_namespace_pids(j);
break;
case 'e':
- minijail_namespace_net(j);
+ if (optarg)
+ minijail_namespace_enter_net(j, optarg);
+ else
+ minijail_namespace_net(j);
break;
case 'i':
*exit_immediately = 1;