minijail: Don't unmount proc if not mounted
When switching in to a new mount and a new pid namespace, as well as
doing pivot_root, proc won't be mounted so leave it alone and let the
new init process handle mounting it. Rename the readonly flag to
remount_proc_ro which better reflects its meaning.
This will aid in starting complete, containerized systems with minijail.
Change-Id: Ice8f6d835b6417383c0cfb901ac737c3440dce55
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/300154
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 6f75f60..8a09cad 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -88,7 +88,7 @@
int net:1;
int userns:1;
int seccomp:1;
- int readonly:1;
+ int remount_proc_ro:1;
int usergroups:1;
int ptrace:1;
int no_new_privs:1;
@@ -127,7 +127,7 @@
{
j->flags.vfs = 0;
j->flags.enter_vfs = 0;
- j->flags.readonly = 0;
+ j->flags.remount_proc_ro = 0;
j->flags.pids = 0;
j->flags.do_init = 0;
j->flags.pid_file = 0;
@@ -141,7 +141,7 @@
{
int vfs = j->flags.vfs;
int enter_vfs = j->flags.enter_vfs;
- int readonly = j->flags.readonly;
+ int remount_proc_ro = j->flags.remount_proc_ro;
int userns = j->flags.userns;
if (j->user)
free(j->user);
@@ -150,7 +150,7 @@
/* Now restore anything we meant to keep. */
j->flags.vfs = vfs;
j->flags.enter_vfs = enter_vfs;
- j->flags.readonly = readonly;
+ j->flags.remount_proc_ro = remount_proc_ro;
j->flags.userns = userns;
/* Note, |pids| will already have been used before this call. */
}
@@ -286,7 +286,7 @@
void API minijail_namespace_pids(struct minijail *j)
{
j->flags.vfs = 1;
- j->flags.readonly = 1;
+ j->flags.remount_proc_ro = 1;
j->flags.pids = 1;
j->flags.do_init = 1;
}
@@ -296,10 +296,10 @@
j->flags.net = 1;
}
-void API minijail_remount_readonly(struct minijail *j)
+void API minijail_remount_proc_readonly(struct minijail *j)
{
j->flags.vfs = 1;
- j->flags.readonly = 1;
+ j->flags.remount_proc_ro = 1;
}
void API minijail_namespace_user(struct minijail *j)
@@ -787,7 +787,7 @@
return mount("none", "/tmp", "tmpfs", 0, "size=64M,mode=777");
}
-int remount_readonly(const struct minijail *j)
+int remount_proc_readonly(const struct minijail *j)
{
const char *kProcPath = "/proc";
const unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID;
@@ -985,7 +985,7 @@
if (j->flags.mount_tmp && mount_tmp())
pdie("mount_tmp");
- if (j->flags.readonly && remount_readonly(j))
+ if (j->flags.remount_proc_ro && remount_proc_readonly(j))
pdie("remount");
if (j->flags.caps) {
@@ -1433,6 +1433,10 @@
die("failed to set up stderr pipe");
}
+ /* If running an init program, let it decide when/how to mount /proc. */
+ if (pid_namespace && !do_init)
+ j->flags.remount_proc_ro = 0;
+
/* Strip out flags that cannot be inherited across execve. */
minijail_preexec(j);
/* Jail this process and its descendants... */
@@ -1515,6 +1519,10 @@
if (j->flags.userns)
enter_user_namespace(j, userns_pipe_fds);
+ /* If running an init program, let it decide when/how to mount /proc. */
+ if (pid_namespace && !do_init)
+ j->flags.remount_proc_ro = 0;
+
/*
* We can now drop this child into the sandbox
* then execve the target.
diff --git a/libminijail.h b/libminijail.h
index d3d1d37..8b2ae0c 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -58,7 +58,7 @@
void minijail_namespace_user(struct minijail *j);
int minijail_uidmap(struct minijail *j, const char *uidmap);
int minijail_gidmap(struct minijail *j, const char *gidmap);
-void minijail_remount_readonly(struct minijail *j);
+void minijail_remount_proc_readonly(struct minijail *j);
void minijail_run_as_init(struct minijail *j);
int minijail_write_pid_file(struct minijail *j, const char *path);
void minijail_inherit_usergroups(struct minijail *j);
diff --git a/minijail0.c b/minijail0.c
index ce8e058..4c5f9d6 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -223,7 +223,7 @@
minijail_namespace_enter_vfs(j, optarg);
break;
case 'r':
- minijail_remount_readonly(j);
+ minijail_remount_proc_readonly(j);
break;
case 'G':
minijail_inherit_usergroups(j);