sandbox: compile seccomp-bpf policy once only

This commit is contained in:
Robert Swiecki 2018-02-01 14:19:01 +01:00
parent 354c5ae47b
commit 19ea0703f2
5 changed files with 40 additions and 32 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -34,31 +34,15 @@
#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;
}

View File

@ -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;
}