Make --disable_proc work
authorJagger <robert@swiecki.net>
Sat, 15 Aug 2015 18:48:48 +0000 (20:48 +0200)
committerJagger <robert@swiecki.net>
Sat, 15 Aug 2015 18:48:48 +0000 (20:48 +0200)
contain.c
contain.h
subproc.c

index 9ed023ad07f17436a1d140f85cb5a4ff177b357f..39ecde33a93338e162dec8ff42f7e59dc5c56f2b 100644 (file)
--- a/contain.c
+++ b/contain.c
@@ -99,7 +99,7 @@ static bool containUidGidMap(struct nsjconf_t *nsjconf, uid_t uid, gid_t gid)
        return true;
 }
 
-bool containDropPrivs(struct nsjconf_t * nsjconf)
+bool containInitUserNs(struct nsjconf_t * nsjconf)
 {
        if (containSetGroups() == false) {
                return false;
@@ -107,6 +107,11 @@ bool containDropPrivs(struct nsjconf_t * nsjconf)
        if (containUidGidMap(nsjconf, nsjconf->uid, nsjconf->gid) == false) {
                return false;
        }
+       return true;
+}
+
+bool containDropPrivs(struct nsjconf_t * nsjconf)
+{
        /*
         * Best effort because of /proc/self/setgroups
         */
@@ -433,19 +438,35 @@ bool containSetLimits(struct nsjconf_t * nsjconf)
        return true;
 }
 
-bool containMakeFdsCOE(void)
+static bool containMakeFdsCOENaive(void)
+{
+       // Don't use getrlimit(RLIMIT_NOFILE) here, as it can return an artifically small value
+       // (e.g. 32), which could be smaller than a maximum assigned number to file-descriptors
+       // in this process. Just use some reasonably sane value (e.g. 1024)
+       for (unsigned fd = (STDERR_FILENO + 1); fd < 1024; fd++) {
+               int flags = fcntl(fd, F_GETFD, 0);
+               if (flags == -1) {
+                       continue;
+               }
+               fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+               LOG_D("Set fd '%d' flag to FD_CLOEXEC", fd);
+       }
+       return true;
+}
+
+static bool containMakeFdsCOEProc(void)
 {
        /* Make all fds above stderr close-on-exec */
        DIR *dir = opendir("/proc/self/fd");
        if (dir == NULL) {
-               PLOG_E("opendir('/proc/self/fd')");
+               PLOG_D("opendir('/proc/self/fd')");
                return false;
        }
        for (;;) {
                errno = 0;
                struct dirent *entry = readdir(dir);
                if (entry == NULL && errno != 0) {
-                       PLOG_E("readdir('/proc/self/fd')");
+                       PLOG_D("readdir('/proc/self/fd')");
                        closedir(dir);
                        return false;
                }
@@ -466,7 +487,7 @@ bool containMakeFdsCOE(void)
                if (fd > STDERR_FILENO) {
                        int flags = fcntl(fd, F_GETFD, 0);
                        if (flags == -1) {
-                               PLOG_E("fcntl(fd, F_GETFD, 0)");
+                               PLOG_D("fcntl(fd, F_GETFD, 0)");
                                return false;
                        }
                        fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
@@ -477,6 +498,18 @@ bool containMakeFdsCOE(void)
        return true;
 }
 
+bool containMakeFdsCOE(void)
+{
+       if (containMakeFdsCOEProc() == true) {
+               return true;
+       }
+       if (containMakeFdsCOENaive() == true) {
+               return true;
+       }
+       LOG_E("Couldn't mark relevant file-descriptors as close-on-exec with any known method");
+       return false;
+}
+
 bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err, int fd_log)
 {
        /* Make sure all logs go to the parent process from now on */
index 9d97729e7e30920bd82cdc9553f12473e261a96f..46976969cc6b1a7d80173278b4597915a76be9ac 100644 (file)
--- a/contain.h
+++ b/contain.h
@@ -26,6 +26,7 @@
 
 #include "common.h"
 
+bool containInitUserNs(struct nsjconf_t *nsjconf);
 bool containDropPrivs(struct nsjconf_t *nsjconf);
 bool containPrepareEnv(struct nsjconf_t *nsjconf);
 bool containMountFS(struct nsjconf_t *nsjconf);
index e672c9e3d7479d1b44d333e44dac76e92c46d01e..af0d3a7cbf6cb65af4da1281779dda450d9d9b32 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -47,6 +47,9 @@
 
 static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int pipefd)
 {
+       if (containInitUserNs(nsjconf) == false) {
+               exit(1);
+       }
        if (containPrepareEnv(nsjconf) == false) {
                exit(1);
        }
@@ -214,7 +217,7 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
 
        if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
                if (nsjconf->clone_newpid) {
-                       LOG_W("CLONE_NEWPID requested. It causes troubles with unshare() "
+                       LOG_D("CLONE_NEWPID requested. It causes troubles with unshare() "
                              "[ENOMEM with clone/fork/vfork]. Disabling it");
                        flags &= ~(CLONE_NEWPID);
                }