sandbox: compile seccomp-bpf policy once only
authorRobert Swiecki <robert@swiecki.net>
Thu, 1 Feb 2018 13:19:01 +0000 (14:19 +0100)
committerRobert Swiecki <robert@swiecki.net>
Thu, 1 Feb 2018 13:19:01 +0000 (14:19 +0100)
Makefile
cmdline.c
nsjail.h
sandbox.c
subproc.c

index 2bb7de2..f6b9abe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -99,8 +99,8 @@ indent:
 
 nsjail.o: nsjail.h cmdline.h common.h log.h net.h subproc.h util.h
 caps.o: caps.h nsjail.h common.h log.h util.h
-cmdline.o: cmdline.h nsjail.h caps.h common.h config.h log.h mount.h user.h
-cmdline.o: util.h
+cmdline.o: cmdline.h nsjail.h caps.h common.h config.h log.h mount.h
+cmdline.o: sandbox.h user.h util.h
 contain.o: contain.h nsjail.h caps.h cgroup.h cpu.h log.h mount.h net.h pid.h
 contain.o: user.h uts.h
 log.o: log.h nsjail.h
index e3fe0ce..26df84f 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -46,6 +46,7 @@
 #include "config.h"
 #include "log.h"
 #include "mount.h"
+#include "sandbox.h"
 #include "user.h"
 #include "util.h"
 
@@ -369,7 +370,6 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
            .iface_vs_nm = "255.255.255.0",
            .iface_vs_gw = "0.0.0.0",
            .kafel_file_path = NULL,
-           .kafel_file_ptr = NULL,
            .kafel_string = NULL,
            .orig_uid = getuid(),
            .num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
@@ -829,5 +829,10 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                }
        }
 
+       if (!sandboxPrepare(nsjconf)) {
+               LOG_E("Couldn't prepare sandboxing setup");
+               return false;
+       }
+
        return true;
 }
index bee2ae1..bc8c25f 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -23,6 +23,7 @@
 #ifndef NS_NSJAIL_H
 #define NS_NSJAIL_H
 
+#include <linux/filter.h>
 #include <netinet/ip6.h>
 #include <signal.h>
 #include <stdbool.h>
@@ -174,8 +175,8 @@ struct nsjconf_t {
        const char* cgroup_net_cls_parent;
        unsigned int cgroup_net_cls_classid;
        const char* kafel_file_path;
-       FILE* kafel_file_ptr;
        const char* kafel_string;
+       struct sock_fprog seccomp_fprog;
        long num_cpus;
        uid_t orig_uid;
        TAILQ_HEAD(udmaplist, idmap_t)
index 96b2549..1450973 100644 (file)
--- a/sandbox.c
+++ b/sandbox.c
 #endif /* PR_SET_NO_NEW_PRIVS */
 
 static bool sandboxPrepareAndCommit(struct nsjconf_t* nsjconf) {
-       if (nsjconf->kafel_file_ptr == NULL && nsjconf->kafel_string == NULL) {
+       if (nsjconf->kafel_file_path == NULL && nsjconf->kafel_string == NULL) {
                return true;
        }
-       struct sock_fprog seccomp_fprog;
-
-       kafel_ctxt_t ctxt = kafel_ctxt_create();
-
-       if (nsjconf->kafel_file_ptr != NULL) {
-               kafel_set_input_file(ctxt, nsjconf->kafel_file_ptr);
-       } else {
-               kafel_set_input_string(ctxt, nsjconf->kafel_string);
-       }
-
-       if (kafel_compile(ctxt, &seccomp_fprog) != 0) {
-               LOG_E("Could not compile policy: %s", kafel_error_msg(ctxt));
-               kafel_ctxt_destroy(&ctxt);
-               return false;
-       }
-       kafel_ctxt_destroy(&ctxt);
 
        if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
                PLOG_W("prctl(PR_SET_NO_NEW_PRIVS, 1) failed");
                return false;
        }
-       if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_fprog, 0, 0)) {
+       if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &nsjconf->seccomp_fprog, 0, 0)) {
                PLOG_W("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed");
                return false;
        }
@@ -68,12 +52,33 @@ static bool sandboxPrepareAndCommit(struct nsjconf_t* nsjconf) {
 bool sandboxApply(struct nsjconf_t* nsjconf) { return sandboxPrepareAndCommit(nsjconf); }
 
 bool sandboxPrepare(struct nsjconf_t* nsjconf) {
-       if (nsjconf->kafel_file_path == NULL) {
+       if (nsjconf->kafel_file_path == NULL && nsjconf->kafel_string == NULL) {
                return true;
        }
-       if ((nsjconf->kafel_file_ptr = fopen(nsjconf->kafel_file_path, "r")) == NULL) {
-               PLOG_W("Couldn't open kafel policy file '%s'", nsjconf->kafel_file_path);
+       FILE* f = NULL;
+       if (nsjconf->kafel_file_path && !(f = fopen(nsjconf->kafel_file_path, "r"))) {
+               PLOG_W(
+                   "Couldn't open the kafel seccomp policy file '%s'", nsjconf->kafel_file_path);
                return false;
        }
+
+       kafel_ctxt_t ctxt = kafel_ctxt_create();
+
+       if (f) {
+               kafel_set_input_file(ctxt, f);
+       } else if (nsjconf->kafel_string) {
+               kafel_set_input_string(ctxt, nsjconf->kafel_string);
+       } else {
+               LOG_F(
+                   "No kafel seccomp-bpf config file available, nor policy as a string was "
+                   "defined");
+       }
+
+       if (kafel_compile(ctxt, &nsjconf->seccomp_fprog) != 0) {
+               LOG_E("Could not compile policy: %s", kafel_error_msg(ctxt));
+               kafel_ctxt_destroy(&ctxt);
+               return false;
+       }
+       kafel_ctxt_destroy(&ctxt);
        return true;
 }
index 0484e8a..df7985a 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -51,7 +51,7 @@
 #include "user.h"
 #include "util.h"
 
-static const char subprocDoneChar = 'D';
+static const char kSubprocDoneChar = 'D';
 
 #if !defined(CLONE_NEWCGROUP)
 #define CLONE_NEWCGROUP 0x02000000
@@ -130,9 +130,6 @@ static bool subprocReset(void) {
 
 static int subprocNewProc(
     struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err, int pipefd) {
-       if (sandboxPrepare(nsjconf) == false) {
-               _exit(0xff);
-       }
        if (containSetupFD(nsjconf, fd_in, fd_out, fd_err) == false) {
                _exit(0xff);
        }
@@ -154,7 +151,7 @@ static int subprocNewProc(
                if (utilReadFromFd(pipefd, &doneChar, sizeof(doneChar)) != sizeof(doneChar)) {
                        _exit(0xff);
                }
-               if (doneChar != subprocDoneChar) {
+               if (doneChar != kSubprocDoneChar) {
                        _exit(0xff);
                }
        }
@@ -385,8 +382,8 @@ static bool subprocInitParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd)
                LOG_E("Couldn't initialize user namespaces for pid %d", pid);
                return false;
        }
-       if (utilWriteToFd(pipefd, &subprocDoneChar, sizeof(subprocDoneChar)) !=
-           sizeof(subprocDoneChar)) {
+       if (utilWriteToFd(pipefd, &kSubprocDoneChar, sizeof(kSubprocDoneChar)) !=
+           sizeof(kSubprocDoneChar)) {
                LOG_E("Couldn't signal the new process via a socketpair");
                return false;
        }