Init user-ns setresuid/setresgid before initializing other NSes
authorRobert Swiecki <swiecki@google.com>
Tue, 7 Feb 2017 17:31:50 +0000 (18:31 +0100)
committerRobert Swiecki <swiecki@google.com>
Tue, 7 Feb 2017 17:31:50 +0000 (18:31 +0100)
Makefile
contain.c
user.c
user.h

index f3b610bdfc86c438ee9cd3479a199f673603acef..7532c8a41510fcad34eea8062ce3ebda8554c570 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,8 @@ indent:
 
 nsjail.o: nsjail.h common.h cmdline.h log.h net.h subproc.h
 cmdline.o: cmdline.h common.h log.h util.h
-contain.o: contain.h common.h cgroup.h log.h mount.h net.h pid.h util.h uts.h
+contain.o: contain.h common.h cgroup.h log.h mount.h net.h pid.h user.h
+contain.o: util.h uts.h
 log.o: log.h common.h
 cgroup.o: cgroup.h common.h log.h util.h
 mount.o: mount.h common.h log.h subproc.h util.h
index 1ab9e69ed14b95d71b648713af956cfa6c4dcbd1..4d3d377d5aec2321b5d0c55734f4892d2b846101 100644 (file)
--- a/contain.c
+++ b/contain.c
 #include "mount.h"
 #include "net.h"
 #include "pid.h"
+#include "user.h"
 #include "util.h"
 #include "uts.h"
 
+static bool containUserNs(struct nsjconf_t *nsjconf)
+{
+       return userInitNsFromChild(nsjconf);
+}
+
 static bool containInitPidNs(struct nsjconf_t *nsjconf)
 {
        return pidInitNs(nsjconf);
@@ -72,23 +78,6 @@ static bool containInitCgroupNs(void)
 
 static bool containDropPrivs(struct nsjconf_t *nsjconf)
 {
-       /*
-        * Best effort because of /proc/self/setgroups
-        */
-       gid_t *group_list = NULL;
-       if (setgroups(0, group_list) == -1) {
-               PLOG_D("setgroups(NULL) failed");
-       }
-       if (syscall(__NR_setresgid, nsjconf->inside_gid, nsjconf->inside_gid, nsjconf->inside_gid)
-           == -1) {
-               PLOG_E("setresgid(%u)", nsjconf->inside_gid);
-               return false;
-       }
-       if (syscall(__NR_setresuid, nsjconf->inside_uid, nsjconf->inside_uid, nsjconf->inside_uid)
-           == -1) {
-               PLOG_E("setresuid(%u)", nsjconf->inside_uid);
-               return false;
-       }
 #ifndef PR_SET_NO_NEW_PRIVS
 #define PR_SET_NO_NEW_PRIVS 38
 #endif
@@ -354,6 +343,9 @@ bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_er
 
 bool containContain(struct nsjconf_t * nsjconf)
 {
+       if (containUserNs(nsjconf) == false) {
+               return false;
+       }
        if (containInitPidNs(nsjconf) == false) {
                return false;
        }
diff --git a/user.c b/user.c
index 950fea77f7a45da1e09fba4b7b12757d1c891ecd..ae145f83f10191acebd96c5c417f08f122f38eaf 100644 (file)
--- a/user.c
+++ b/user.c
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/syscall.h>
 #include <unistd.h>
 
 #include "log.h"
@@ -189,3 +190,26 @@ bool userInitNsFromParent(struct nsjconf_t * nsjconf, pid_t pid)
        }
        return true;
 }
+
+bool userInitNsFromChild(struct nsjconf_t * nsjconf)
+{
+       /*
+        * Best effort because of /proc/self/setgroups
+        */
+       gid_t *group_list = NULL;
+       if (setgroups(0, group_list) == -1) {
+               PLOG_D("setgroups(NULL) failed");
+       }
+       if (syscall(__NR_setresgid, nsjconf->inside_gid, nsjconf->inside_gid, nsjconf->inside_gid)
+           == -1) {
+               PLOG_E("setresgid(%u)", nsjconf->inside_gid);
+               return false;
+       }
+       if (syscall(__NR_setresuid, nsjconf->inside_uid, nsjconf->inside_uid, nsjconf->inside_uid)
+           == -1) {
+               PLOG_E("setresuid(%u)", nsjconf->inside_uid);
+               return false;
+       }
+
+       return true;
+}
diff --git a/user.h b/user.h
index 4ef208b1c37e2028d4ba6271395f15f80d3d3a05..396f232875d1df01f760966432002d308c769354 100644 (file)
--- a/user.h
+++ b/user.h
@@ -28,4 +28,6 @@
 
 bool userInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid);
 
+bool userInitNsFromChild(struct nsjconf_t *nsjconf);
+
 #endif                         /* NS_USER_H */