Use dummy init with -Me
authorRobert Swiecki <swiecki@google.com>
Wed, 11 May 2016 14:20:05 +0000 (16:20 +0200)
committerRobert Swiecki <swiecki@google.com>
Wed, 11 May 2016 14:20:05 +0000 (16:20 +0200)
subproc.c

index 1ed666fd2e433cee49e2e52e267a88f027079aae..94b4329aadad2d45fba1beec17fefc87cf6e17ec 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -278,6 +278,23 @@ static bool subprocInitParent(struct nsjconf_t *nsjconf, pid_t pid, int pipefd)
        return true;
 }
 
+void subprocDummyInit()
+{
+       pid_t pid = syscall(__NR_clone, (uintptr_t) 0, NULL, NULL, NULL, (uintptr_t) 0);
+       if (pid == -1) {
+               LOG_F("Couldn't create a dummy init process");
+       }
+       if (pid > 0) {
+               return;
+       }
+       if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) {
+               LOG_W("(prctl(PR_SET_PDEATHSIG, SIGKILL) failed");
+       }
+       for (;;) {
+               pause();
+       }
+}
+
 void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err)
 {
        if (netLimitConns(nsjconf, fd_in) == false) {
@@ -293,16 +310,16 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
        flags |= (nsjconf->clone_newuts ? CLONE_NEWUTS : 0);
 
        if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
-               if (nsjconf->clone_newpid) {
-                       LOG_D("CLONE_NEWPID requested. It causes troubles with unshare() "
-                             "[ENOMEM with clone/fork/vfork]. Disabling it");
-                       flags &= ~(CLONE_NEWPID);
-               }
                LOG_D("Entering namespace with flags: %#lx", flags);
                if (unshare(flags) == -1) {
                        PLOG_E("unshare(%#lx)", flags);
                        _exit(EXIT_FAILURE);
                }
+               if (nsjconf->clone_newpid) {
+                       LOG_D
+                           ("CLONE_NEWPID requested. We must create a dummy init process, to avoid ENOMEM with clone/fork/vfork");
+                       subprocDummyInit();
+               }
                subprocNewProc(nsjconf, fd_in, fd_out, fd_err, -1);
        }