Use a subprocess to setup unshare mount /proc
authorJagger <robert@swiecki.net>
Thu, 12 May 2016 20:25:48 +0000 (22:25 +0200)
committerJagger <robert@swiecki.net>
Thu, 12 May 2016 20:25:48 +0000 (22:25 +0200)
mount.c
subproc.c

diff --git a/mount.c b/mount.c
index 6ce9614e7dc87332bb806ba762dc972b73671ccc..1fe466b9e19156a1c001637dced3dacd0497b3a2 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -23,6 +23,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <sched.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -31,6 +32,7 @@
 #include <sys/statvfs.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
 #include "log.h"
@@ -128,7 +130,7 @@ static bool mountRemountRO(struct mounts_t *mpt)
        return true;
 }
 
-bool mountInitNs(struct nsjconf_t * nsjconf)
+static bool mountInitNsInternal(struct nsjconf_t *nsjconf)
 {
        if (nsjconf->clone_newns == false) {
                if (chroot(nsjconf->chroot) == -1) {
@@ -205,3 +207,31 @@ bool mountInitNs(struct nsjconf_t * nsjconf)
 
        return true;
 }
+
+/*
+ * With mode MODE_STANDALONE_EXECVE it's required to mount /proc inside a new process,
+ *  as the current process is still in the original PID namespace (man pid_namespaces)
+ */
+bool mountInitNs(struct nsjconf_t * nsjconf)
+{
+       if (nsjconf->mode != MODE_STANDALONE_EXECVE) {
+               return mountInitNsInternal(nsjconf);
+       }
+
+       pid_t pid =
+           syscall(__NR_clone, (uintptr_t) CLONE_FS | SIGCHLD, NULL, NULL, NULL, (uintptr_t) 0);
+       if (pid == -1) {
+               return false;
+       }
+
+       if (pid == 0) {
+               exit(mountInitNsInternal(nsjconf) ? 0 : 1);
+       }
+
+       int status;
+       while (wait4(pid, &status, 0, NULL) != pid) ;
+       if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+               return true;
+       }
+       return false;
+}
index 94b4329aadad2d45fba1beec17fefc87cf6e17ec..57d20e6c39e6a85854389530f9f2508de39139be 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -280,7 +280,7 @@ static bool subprocInitParent(struct nsjconf_t *nsjconf, pid_t pid, int pipefd)
 
 void subprocDummyInit()
 {
-       pid_t pid = syscall(__NR_clone, (uintptr_t) 0, NULL, NULL, NULL, (uintptr_t) 0);
+       pid_t pid = syscall(__NR_clone, (uintptr_t) CLONE_FS, NULL, NULL, NULL, (uintptr_t) 0);
        if (pid == -1) {
                LOG_F("Couldn't create a dummy init process");
        }