cmdline: move to C++
This commit is contained in:
parent
0a311af2ad
commit
840b75025c
16
Makefile
16
Makefile
@ -30,13 +30,13 @@ COMMON_FLAGS += -O2 -c \
|
|||||||
CFLAGS += $(COMMON_FLAGS) \
|
CFLAGS += $(COMMON_FLAGS) \
|
||||||
-std=gnu11
|
-std=gnu11
|
||||||
CXXFLAGS += $(COMMON_FLAGS) $(shell pkg-config --cflags protobuf) \
|
CXXFLAGS += $(COMMON_FLAGS) $(shell pkg-config --cflags protobuf) \
|
||||||
-std=c++11 -Wno-unused -Wno-unused-parameter
|
-std=c++14 -fno-exceptions -Wno-unused -Wno-unused-parameter
|
||||||
LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs protobuf)
|
LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs protobuf)
|
||||||
|
|
||||||
BIN = nsjail
|
BIN = nsjail
|
||||||
LIBS = kafel/libkafel.a
|
LIBS = kafel/libkafel.a
|
||||||
SRCS_C = caps.c cmdline.c contain.c log.c cgroup.c mount.c net.c pid.c sandbox.c subproc.c user.c util.c uts.c cpu.c
|
SRCS_C = caps.c contain.c log.c cgroup.c mount.c net.c pid.c sandbox.c subproc.c user.c util.c uts.c cpu.c
|
||||||
SRCS_CXX = nsjail.cc config.cc
|
SRCS_CXX = cmdline.cc config.cc nsjail.cc
|
||||||
SRCS_PROTO = config.proto
|
SRCS_PROTO = config.proto
|
||||||
SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc)
|
SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc)
|
||||||
SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h)
|
SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h)
|
||||||
@ -97,10 +97,7 @@ indent:
|
|||||||
|
|
||||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||||
|
|
||||||
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
|
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
|
|
||||||
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: contain.h nsjail.h caps.h cgroup.h cpu.h log.h mount.h net.h pid.h
|
||||||
contain.o: user.h uts.h
|
contain.o: user.h uts.h
|
||||||
log.o: log.h nsjail.h
|
log.o: log.h nsjail.h
|
||||||
@ -115,5 +112,8 @@ user.o: user.h nsjail.h common.h log.h subproc.h util.h
|
|||||||
util.o: util.h nsjail.h common.h log.h
|
util.o: util.h nsjail.h common.h log.h
|
||||||
uts.o: uts.h nsjail.h log.h
|
uts.o: uts.h nsjail.h log.h
|
||||||
cpu.o: cpu.h nsjail.h log.h util.h
|
cpu.o: cpu.h nsjail.h log.h util.h
|
||||||
config.o: common.h caps.h nsjail.h cmdline.h config.h log.h mount.h user.h
|
cmdline.o: cmdline.h nsjail.h caps.h common.h log.h mount.h sandbox.h user.h
|
||||||
config.o: util.h
|
cmdline.o: util.h config.h
|
||||||
|
config.o: common.h caps.h nsjail.h config.h log.h mount.h user.h util.h
|
||||||
|
config.o: cmdline.h
|
||||||
|
nsjail.o: nsjail.h cmdline.h common.h log.h net.h subproc.h util.h
|
||||||
|
@ -36,19 +36,27 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/personality.h>
|
#include <sys/personality.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "caps.h"
|
#include "caps.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "sandbox.h"
|
#include "sandbox.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
namespace cmdline {
|
||||||
|
|
||||||
struct custom_option {
|
struct custom_option {
|
||||||
struct option opt;
|
struct option opt;
|
||||||
@ -194,7 +202,7 @@ static void cmdlineUsage(const char* pname) {
|
|||||||
LOG_HELP_BOLD(" nsjail -Me --chroot / --disable_proc -- /bin/echo \"ABC\"");
|
LOG_HELP_BOLD(" nsjail -Me --chroot / --disable_proc -- /bin/echo \"ABC\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmdlineLogParams(struct nsjconf_t* nsjconf) {
|
void logParams(struct nsjconf_t* nsjconf) {
|
||||||
switch (nsjconf->mode) {
|
switch (nsjconf->mode) {
|
||||||
case MODE_LISTEN_TCP:
|
case MODE_LISTEN_TCP:
|
||||||
LOG_I("Mode: LISTEN_TCP");
|
LOG_I("Mode: LISTEN_TCP");
|
||||||
@ -263,7 +271,7 @@ void cmdlineLogParams(struct nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
|
uint64_t parseRLimit(int res, const char* optarg, unsigned long mul) {
|
||||||
if (strcasecmp(optarg, "inf") == 0) {
|
if (strcasecmp(optarg, "inf") == 0) {
|
||||||
return RLIM64_INFINITY;
|
return RLIM64_INFINITY;
|
||||||
}
|
}
|
||||||
@ -315,71 +323,71 @@ static char* cmdlineSplitStrByColon(char* spec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
|
||||||
(*nsjconf) = (const struct nsjconf_t){
|
std::unique_ptr<struct nsjconf_t> nsjconf = std::make_unique<struct nsjconf_t>();
|
||||||
.exec_file = NULL,
|
|
||||||
.use_execveat = false,
|
nsjconf->exec_file = NULL;
|
||||||
.exec_fd = -1,
|
nsjconf->use_execveat = false;
|
||||||
.argv = NULL,
|
nsjconf->exec_fd = -1;
|
||||||
.hostname = "NSJAIL",
|
nsjconf->argv = NULL;
|
||||||
.cwd = "/",
|
nsjconf->hostname = "NSJAIL";
|
||||||
.chroot = NULL,
|
nsjconf->cwd = "/";
|
||||||
.port = 0,
|
nsjconf->chroot = NULL;
|
||||||
.bindhost = "::",
|
nsjconf->port = 0;
|
||||||
.log_fd = STDERR_FILENO,
|
nsjconf->bindhost = "::";
|
||||||
.logfile = NULL,
|
nsjconf->log_fd = STDERR_FILENO;
|
||||||
.loglevel = INFO,
|
nsjconf->logfile = NULL;
|
||||||
.daemonize = false,
|
nsjconf->loglevel = INFO;
|
||||||
.tlimit = 0,
|
nsjconf->daemonize = false;
|
||||||
.max_cpus = 0,
|
nsjconf->tlimit = 0;
|
||||||
.keep_caps = false,
|
nsjconf->max_cpus = 0;
|
||||||
.disable_no_new_privs = false,
|
nsjconf->keep_caps = false;
|
||||||
.rl_as = 512 * (1024 * 1024),
|
nsjconf->disable_no_new_privs = false;
|
||||||
.rl_core = 0,
|
nsjconf->rl_as = 512 * (1024 * 1024);
|
||||||
.rl_cpu = 600,
|
nsjconf->rl_core = 0;
|
||||||
.rl_fsize = 1 * (1024 * 1024),
|
nsjconf->rl_cpu = 600;
|
||||||
.rl_nofile = 32,
|
nsjconf->rl_fsize = 1 * (1024 * 1024);
|
||||||
.rl_nproc = cmdlineParseRLimit(RLIMIT_NPROC, "soft", 1),
|
nsjconf->rl_nofile = 32;
|
||||||
.rl_stack = cmdlineParseRLimit(RLIMIT_STACK, "soft", 1),
|
nsjconf->rl_nproc = parseRLimit(RLIMIT_NPROC, "soft", 1);
|
||||||
.personality = 0,
|
nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, "soft", 1);
|
||||||
.clone_newnet = true,
|
nsjconf->personality = 0;
|
||||||
.clone_newuser = true,
|
nsjconf->clone_newnet = true;
|
||||||
.clone_newns = true,
|
nsjconf->clone_newuser = true;
|
||||||
.clone_newpid = true,
|
nsjconf->clone_newns = true;
|
||||||
.clone_newipc = true,
|
nsjconf->clone_newpid = true;
|
||||||
.clone_newuts = true,
|
nsjconf->clone_newipc = true;
|
||||||
.clone_newcgroup = true,
|
nsjconf->clone_newuts = true;
|
||||||
.mode = MODE_STANDALONE_ONCE,
|
nsjconf->clone_newcgroup = true;
|
||||||
.is_root_rw = false,
|
nsjconf->mode = MODE_STANDALONE_ONCE;
|
||||||
.is_silent = false,
|
nsjconf->is_root_rw = false;
|
||||||
.skip_setsid = false,
|
nsjconf->is_silent = false;
|
||||||
.max_conns_per_ip = 0,
|
nsjconf->skip_setsid = false;
|
||||||
.tmpfs_size = 4 * (1024 * 1024),
|
nsjconf->max_conns_per_ip = 0;
|
||||||
.mount_proc = true,
|
nsjconf->tmpfs_size = 4 * (1024 * 1024);
|
||||||
.proc_path = "/proc",
|
nsjconf->mount_proc = true;
|
||||||
.is_proc_rw = false,
|
nsjconf->proc_path = "/proc";
|
||||||
.cgroup_mem_mount = "/sys/fs/cgroup/memory",
|
nsjconf->is_proc_rw = false;
|
||||||
.cgroup_mem_parent = "NSJAIL",
|
nsjconf->cgroup_mem_mount = "/sys/fs/cgroup/memory";
|
||||||
.cgroup_mem_max = (size_t)0,
|
nsjconf->cgroup_mem_parent = "NSJAIL";
|
||||||
.cgroup_pids_mount = "/sys/fs/cgroup/pids",
|
nsjconf->cgroup_mem_max = (size_t)0;
|
||||||
.cgroup_pids_parent = "NSJAIL",
|
nsjconf->cgroup_pids_mount = "/sys/fs/cgroup/pids";
|
||||||
.cgroup_pids_max = 0U,
|
nsjconf->cgroup_pids_parent = "NSJAIL";
|
||||||
.cgroup_net_cls_mount = "/sys/fs/cgroup/net_cls",
|
nsjconf->cgroup_pids_max = 0U;
|
||||||
.cgroup_net_cls_parent = "NSJAIL",
|
nsjconf->cgroup_net_cls_mount = "/sys/fs/cgroup/net_cls";
|
||||||
.cgroup_net_cls_classid = 0U,
|
nsjconf->cgroup_net_cls_parent = "NSJAIL";
|
||||||
.cgroup_cpu_mount = "/sys/fs/cgroup/cpu",
|
nsjconf->cgroup_net_cls_classid = 0U;
|
||||||
.cgroup_cpu_parent = "NSJAIL",
|
nsjconf->cgroup_cpu_mount = "/sys/fs/cgroup/cpu";
|
||||||
.cgroup_cpu_ms_per_sec = 0U,
|
nsjconf->cgroup_cpu_parent = "NSJAIL";
|
||||||
.iface_no_lo = false,
|
nsjconf->cgroup_cpu_ms_per_sec = 0U;
|
||||||
.iface_vs = NULL,
|
nsjconf->iface_no_lo = false;
|
||||||
.iface_vs_ip = "0.0.0.0",
|
nsjconf->iface_vs = NULL;
|
||||||
.iface_vs_nm = "255.255.255.0",
|
nsjconf->iface_vs_ip = "0.0.0.0";
|
||||||
.iface_vs_gw = "0.0.0.0",
|
nsjconf->iface_vs_nm = "255.255.255.0";
|
||||||
.kafel_file_path = NULL,
|
nsjconf->iface_vs_gw = "0.0.0.0";
|
||||||
.kafel_string = NULL,
|
nsjconf->kafel_file_path = NULL;
|
||||||
.orig_uid = getuid(),
|
nsjconf->kafel_string = NULL;
|
||||||
.num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
|
nsjconf->orig_uid = getuid();
|
||||||
};
|
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
|
||||||
TAILQ_INIT(&nsjconf->pids);
|
TAILQ_INIT(&nsjconf->pids);
|
||||||
TAILQ_INIT(&nsjconf->mountpts);
|
TAILQ_INIT(&nsjconf->mountpts);
|
||||||
@ -392,13 +400,13 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
static char cmdlineTmpfsSz[PATH_MAX] = "size=4194304";
|
static char cmdlineTmpfsSz[PATH_MAX] = "size=4194304";
|
||||||
|
|
||||||
struct ints_t* f;
|
struct ints_t* f;
|
||||||
f = utilMalloc(sizeof(struct ints_t));
|
f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
|
||||||
f->val = STDIN_FILENO;
|
f->val = STDIN_FILENO;
|
||||||
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
||||||
f = utilMalloc(sizeof(struct ints_t));
|
f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
|
||||||
f->val = STDOUT_FILENO;
|
f->val = STDOUT_FILENO;
|
||||||
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
||||||
f = utilMalloc(sizeof(struct ints_t));
|
f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
|
||||||
f->val = STDERR_FILENO;
|
f->val = STDERR_FILENO;
|
||||||
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
||||||
|
|
||||||
@ -433,7 +441,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
nsjconf->cwd = optarg;
|
nsjconf->cwd = optarg;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (configParse(nsjconf, optarg) == false) {
|
if (configParse(nsjconf.get(), optarg) == false) {
|
||||||
LOG_F("Couldn't parse configuration from '%s' file", optarg);
|
LOG_F("Couldn't parse configuration from '%s' file", optarg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -452,14 +460,14 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
nsjconf->logfile = optarg;
|
nsjconf->logfile = optarg;
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
nsjconf->log_fd = strtol(optarg, NULL, 0);
|
nsjconf->log_fd = strtol(optarg, NULL, 0);
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -467,20 +475,20 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
nsjconf->loglevel = DEBUG;
|
nsjconf->loglevel = DEBUG;
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
nsjconf->loglevel = WARNING;
|
nsjconf->loglevel = WARNING;
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
nsjconf->loglevel = FATAL;
|
nsjconf->loglevel = FATAL;
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -494,25 +502,25 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
case 0x0201:
|
case 0x0201:
|
||||||
nsjconf->rl_as = cmdlineParseRLimit(RLIMIT_AS, optarg, (1024 * 1024));
|
nsjconf->rl_as = parseRLimit(RLIMIT_AS, optarg, (1024 * 1024));
|
||||||
break;
|
break;
|
||||||
case 0x0202:
|
case 0x0202:
|
||||||
nsjconf->rl_core = cmdlineParseRLimit(RLIMIT_CORE, optarg, (1024 * 1024));
|
nsjconf->rl_core = parseRLimit(RLIMIT_CORE, optarg, (1024 * 1024));
|
||||||
break;
|
break;
|
||||||
case 0x0203:
|
case 0x0203:
|
||||||
nsjconf->rl_cpu = cmdlineParseRLimit(RLIMIT_CPU, optarg, 1);
|
nsjconf->rl_cpu = parseRLimit(RLIMIT_CPU, optarg, 1);
|
||||||
break;
|
break;
|
||||||
case 0x0204:
|
case 0x0204:
|
||||||
nsjconf->rl_fsize = cmdlineParseRLimit(RLIMIT_FSIZE, optarg, (1024 * 1024));
|
nsjconf->rl_fsize = parseRLimit(RLIMIT_FSIZE, optarg, (1024 * 1024));
|
||||||
break;
|
break;
|
||||||
case 0x0205:
|
case 0x0205:
|
||||||
nsjconf->rl_nofile = cmdlineParseRLimit(RLIMIT_NOFILE, optarg, 1);
|
nsjconf->rl_nofile = parseRLimit(RLIMIT_NOFILE, optarg, 1);
|
||||||
break;
|
break;
|
||||||
case 0x0206:
|
case 0x0206:
|
||||||
nsjconf->rl_nproc = cmdlineParseRLimit(RLIMIT_NPROC, optarg, 1);
|
nsjconf->rl_nproc = parseRLimit(RLIMIT_NPROC, optarg, 1);
|
||||||
break;
|
break;
|
||||||
case 0x0207:
|
case 0x0207:
|
||||||
nsjconf->rl_stack = cmdlineParseRLimit(RLIMIT_STACK, optarg, (1024 * 1024));
|
nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, optarg, (1024 * 1024));
|
||||||
break;
|
break;
|
||||||
case 0x0301:
|
case 0x0301:
|
||||||
nsjconf->personality |= ADDR_COMPAT_LAYOUT;
|
nsjconf->personality |= ADDR_COMPAT_LAYOUT;
|
||||||
@ -564,7 +572,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
break;
|
break;
|
||||||
case 0x0505: {
|
case 0x0505: {
|
||||||
struct ints_t* f;
|
struct ints_t* f;
|
||||||
f = utilMalloc(sizeof(struct ints_t));
|
f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
|
||||||
f->val = (int)strtol(optarg, NULL, 0);
|
f->val = (int)strtol(optarg, NULL, 0);
|
||||||
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
|
||||||
} break;
|
} break;
|
||||||
@ -575,10 +583,11 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
nsjconf->max_cpus = strtoul(optarg, NULL, 0);
|
nsjconf->max_cpus = strtoul(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0509: {
|
case 0x0509: {
|
||||||
struct ints_t* f = utilMalloc(sizeof(struct ints_t));
|
struct ints_t* f =
|
||||||
|
reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
|
||||||
f->val = capsNameToVal(optarg);
|
f->val = capsNameToVal(optarg);
|
||||||
if (f->val == -1) {
|
if (f->val == -1) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
|
||||||
} break;
|
} break;
|
||||||
@ -603,7 +612,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
nsjconf->use_execveat = true;
|
nsjconf->use_execveat = true;
|
||||||
break;
|
break;
|
||||||
case 'E': {
|
case 'E': {
|
||||||
struct charptr_t* p = utilMalloc(sizeof(struct charptr_t));
|
struct charptr_t* p = reinterpret_cast<struct charptr_t*>(
|
||||||
|
utilMalloc(sizeof(struct charptr_t)));
|
||||||
p->val = optarg;
|
p->val = optarg;
|
||||||
TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
|
TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
|
||||||
} break;
|
} break;
|
||||||
@ -613,9 +623,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
char* cnt = cmdlineSplitStrByColon(o_id);
|
char* cnt = cmdlineSplitStrByColon(o_id);
|
||||||
size_t count =
|
size_t count =
|
||||||
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
||||||
if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */,
|
if (userParseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
|
||||||
false /* is_newidmap */) == false) {
|
false /* is_newidmap */) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'g': {
|
case 'g': {
|
||||||
@ -624,9 +634,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
char* cnt = cmdlineSplitStrByColon(o_id);
|
char* cnt = cmdlineSplitStrByColon(o_id);
|
||||||
size_t count =
|
size_t count =
|
||||||
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
||||||
if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */,
|
if (userParseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
|
||||||
false /* is_newidmap */) == false) {
|
false /* is_newidmap */) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'U': {
|
case 'U': {
|
||||||
@ -635,9 +645,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
char* cnt = cmdlineSplitStrByColon(o_id);
|
char* cnt = cmdlineSplitStrByColon(o_id);
|
||||||
size_t count =
|
size_t count =
|
||||||
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
||||||
if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */,
|
if (userParseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
|
||||||
true /* is_newidmap */) == false) {
|
true /* is_newidmap */) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'G': {
|
case 'G': {
|
||||||
@ -646,38 +656,40 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
char* cnt = cmdlineSplitStrByColon(o_id);
|
char* cnt = cmdlineSplitStrByColon(o_id);
|
||||||
size_t count =
|
size_t count =
|
||||||
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
|
||||||
if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */,
|
if (userParseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
|
||||||
true /* is_newidmap */) == false) {
|
true /* is_newidmap */) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'R': {
|
case 'R': {
|
||||||
const char* dst = cmdlineSplitStrByColon(optarg);
|
const char* dst = cmdlineSplitStrByColon(optarg);
|
||||||
dst = dst ? dst : optarg;
|
dst = dst ? dst : optarg;
|
||||||
if (!mountAddMountPtTail(nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
|
if (!mountAddMountPtTail(nsjconf.get(), /* src= */ optarg, dst,
|
||||||
|
/* fs_type= */ "",
|
||||||
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
|
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
|
||||||
/* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
|
/* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
|
||||||
0, /* is_symlink= */ false)) {
|
0, /* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 'B': {
|
case 'B': {
|
||||||
const char* dst = cmdlineSplitStrByColon(optarg);
|
const char* dst = cmdlineSplitStrByColon(optarg);
|
||||||
dst = dst ? dst : optarg;
|
dst = dst ? dst : optarg;
|
||||||
if (!mountAddMountPtTail(nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
|
if (!mountAddMountPtTail(nsjconf.get(), /* src= */ optarg, dst,
|
||||||
|
/* fs_type= */ "",
|
||||||
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
|
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
|
||||||
/* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
|
/* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
|
||||||
0, /* is_symlink= */ false)) {
|
0, /* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 'T': {
|
case 'T': {
|
||||||
if (!mountAddMountPtTail(nsjconf, /* src= */ NULL, optarg, "tmpfs",
|
if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, optarg, "tmpfs",
|
||||||
/* options= */ cmdlineTmpfsSz, /* flags= */ 0,
|
/* options= */ cmdlineTmpfsSz, /* flags= */ 0,
|
||||||
/* isDir= */ NS_DIR_YES,
|
/* isDir= */ NS_DIR_YES,
|
||||||
/* mandatory= */ true, NULL, NULL, NULL, 0,
|
/* mandatory= */ true, NULL, NULL, NULL, 0,
|
||||||
/* is_symlink= */ false)) {
|
/* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -700,7 +712,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
LOG_E(" -M r - MODE_STANDALONE_RERUN");
|
LOG_E(" -M r - MODE_STANDALONE_RERUN");
|
||||||
LOG_E(" -M e - MODE_STANDALONE_EXECVE");
|
LOG_E(" -M e - MODE_STANDALONE_EXECVE");
|
||||||
cmdlineUsage(argv[0]);
|
cmdlineUsage(argv[0]);
|
||||||
return false;
|
return nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -760,7 +772,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
if (access(nsjconf->kafel_file_path, R_OK) == -1) {
|
if (access(nsjconf->kafel_file_path, R_OK) == -1) {
|
||||||
PLOG_E("kafel config file '%s' cannot be opened for reading",
|
PLOG_E("kafel config file '%s' cannot be opened for reading",
|
||||||
nsjconf->kafel_file_path);
|
nsjconf->kafel_file_path);
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0901:
|
case 0x0901:
|
||||||
@ -768,37 +780,39 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cmdlineUsage(argv[0]);
|
cmdlineUsage(argv[0]);
|
||||||
return false;
|
return nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsjconf->mount_proc) {
|
if (nsjconf->mount_proc) {
|
||||||
if (!mountAddMountPtTail(nsjconf, /* src= */ NULL, nsjconf->proc_path, "proc", "",
|
if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, nsjconf->proc_path, "proc",
|
||||||
nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
|
"", nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
|
||||||
/* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
|
/* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsjconf->chroot) {
|
if (nsjconf->chroot) {
|
||||||
if (!mountAddMountPtHead(nsjconf, nsjconf->chroot, "/", /* fs_type= */ "",
|
if (!mountAddMountPtHead(nsjconf.get(), nsjconf->chroot, "/", /* fs_type= */ "",
|
||||||
/* options= */ "",
|
/* options= */ "",
|
||||||
nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE)
|
nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE)
|
||||||
: (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
|
: (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
|
||||||
/* isDir= */ NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0,
|
/* isDir= */ NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0,
|
||||||
/* is_symlink= */ false)) {
|
/* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!mountAddMountPtHead(nsjconf, /* src= */ NULL, "/", "tmpfs", /* options= */ "",
|
if (!mountAddMountPtHead(nsjconf.get(), /* src= */ NULL, "/", "tmpfs",
|
||||||
nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
|
/* options= */ "", nsjconf->is_root_rw ? 0 : MS_RDONLY,
|
||||||
|
/* isDir= */ NS_DIR_YES,
|
||||||
/* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
|
/* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&nsjconf->uids)) {
|
if (TAILQ_EMPTY(&nsjconf->uids)) {
|
||||||
struct idmap_t* p = utilMalloc(sizeof(struct idmap_t));
|
struct idmap_t* p =
|
||||||
|
reinterpret_cast<struct idmap_t*>(utilMalloc(sizeof(struct idmap_t)));
|
||||||
p->inside_id = getuid();
|
p->inside_id = getuid();
|
||||||
p->outside_id = getuid();
|
p->outside_id = getuid();
|
||||||
p->count = 1U;
|
p->count = 1U;
|
||||||
@ -806,7 +820,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
TAILQ_INSERT_HEAD(&nsjconf->uids, p, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->uids, p, pointers);
|
||||||
}
|
}
|
||||||
if (TAILQ_EMPTY(&nsjconf->gids)) {
|
if (TAILQ_EMPTY(&nsjconf->gids)) {
|
||||||
struct idmap_t* p = utilMalloc(sizeof(struct idmap_t));
|
struct idmap_t* p =
|
||||||
|
reinterpret_cast<struct idmap_t*>(utilMalloc(sizeof(struct idmap_t)));
|
||||||
p->inside_id = getgid();
|
p->inside_id = getgid();
|
||||||
p->outside_id = getgid();
|
p->outside_id = getgid();
|
||||||
p->count = 1U;
|
p->count = 1U;
|
||||||
@ -814,8 +829,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
TAILQ_INSERT_HEAD(&nsjconf->gids, p, pointers);
|
TAILQ_INSERT_HEAD(&nsjconf->gids, p, pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logInitLogFile(nsjconf) == false) {
|
if (logInitLogFile(nsjconf.get()) == false) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[optind]) {
|
if (argv[optind]) {
|
||||||
@ -824,7 +839,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) {
|
if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) {
|
||||||
cmdlineUsage(argv[0]);
|
cmdlineUsage(argv[0]);
|
||||||
LOG_E("No command provided");
|
LOG_E("No command provided");
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nsjconf->exec_file == NULL) {
|
if (nsjconf->exec_file == NULL) {
|
||||||
nsjconf->exec_file = nsjconf->argv[0];
|
nsjconf->exec_file = nsjconf->argv[0];
|
||||||
@ -835,19 +850,21 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
|
|||||||
LOG_E(
|
LOG_E(
|
||||||
"Your nsjail is compiled without support for the execveat() syscall, yet you "
|
"Your nsjail is compiled without support for the execveat() syscall, yet you "
|
||||||
"specified the --execute_fd flag");
|
"specified the --execute_fd flag");
|
||||||
return false;
|
return nullptr;
|
||||||
#endif /* !defined(__NR_execveat) */
|
#endif /* !defined(__NR_execveat) */
|
||||||
if ((nsjconf->exec_fd = open(nsjconf->exec_file, O_RDONLY | O_PATH | O_CLOEXEC)) ==
|
if ((nsjconf->exec_fd = open(nsjconf->exec_file, O_RDONLY | O_PATH | O_CLOEXEC)) ==
|
||||||
-1) {
|
-1) {
|
||||||
PLOG_W("Couldn't open '%s' file", nsjconf->exec_file);
|
PLOG_W("Couldn't open '%s' file", nsjconf->exec_file);
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sandboxPrepare(nsjconf)) {
|
if (!sandboxPrepare(nsjconf.get())) {
|
||||||
LOG_E("Couldn't prepare sandboxing setup");
|
LOG_E("Couldn't prepare sandboxing setup");
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return nsjconf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace cmdline
|
19
cmdline.h
19
cmdline.h
@ -22,23 +22,18 @@
|
|||||||
#ifndef NS_CMDLINE_H
|
#ifndef NS_CMDLINE_H
|
||||||
#define NS_CMDLINE_H
|
#define NS_CMDLINE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/time.h>
|
#include <memory>
|
||||||
|
|
||||||
#include "nsjail.h"
|
#include "nsjail.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
namespace cmdline {
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul);
|
uint64_t parseRLimit(int res, const char* optarg, unsigned long mul);
|
||||||
void cmdlineLogParams(struct nsjconf_t* nsjconf);
|
void logParams(struct nsjconf_t* nsjconf);
|
||||||
bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf);
|
std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
} // namespace cmdline
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _CMDLINE_H */
|
#endif /* _CMDLINE_H */
|
||||||
|
@ -26,11 +26,11 @@ extern "C" {
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/personality.h>
|
#include <sys/personality.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "caps.h"
|
#include "caps.h"
|
||||||
#include "cmdline.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
@ -38,6 +38,8 @@ extern "C" {
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "cmdline.h"
|
||||||
|
|
||||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||||
#include <google/protobuf/text_format.h>
|
#include <google/protobuf/text_format.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -54,10 +56,10 @@ static uint64_t configRLimit(
|
|||||||
return (val * mul);
|
return (val * mul);
|
||||||
}
|
}
|
||||||
if (rl == nsjail::RLimit::SOFT) {
|
if (rl == nsjail::RLimit::SOFT) {
|
||||||
return cmdlineParseRLimit(res, "soft", mul);
|
return cmdline::parseRLimit(res, "soft", mul);
|
||||||
}
|
}
|
||||||
if (rl == nsjail::RLimit::HARD) {
|
if (rl == nsjail::RLimit::HARD) {
|
||||||
return cmdlineParseRLimit(res, "hard", mul);
|
return cmdline::parseRLimit(res, "hard", mul);
|
||||||
}
|
}
|
||||||
if (rl == nsjail::RLimit::INF) {
|
if (rl == nsjail::RLimit::INF) {
|
||||||
return RLIM64_INFINITY;
|
return RLIM64_INFINITY;
|
||||||
|
18
nsjail.cc
18
nsjail.cc
@ -157,28 +157,28 @@ static int nsjailStandaloneMode(struct nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
struct nsjconf_t nsjconf;
|
std::unique_ptr<struct nsjconf_t> nsjconf = cmdline::parseArgs(argc, argv);
|
||||||
if (!cmdlineParse(argc, argv, &nsjconf)) {
|
if (!nsjconf) {
|
||||||
LOG_F("Couldn't parse cmdline options");
|
LOG_F("Couldn't parse cmdline options");
|
||||||
}
|
}
|
||||||
if (nsjconf.clone_newuser == false && geteuid() != 0) {
|
if (nsjconf->clone_newuser == false && geteuid() != 0) {
|
||||||
LOG_W("--disable_clone_newuser might require root() privs");
|
LOG_W("--disable_clone_newuser might require root() privs");
|
||||||
}
|
}
|
||||||
if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
|
if (nsjconf->daemonize && (daemon(0, 0) == -1)) {
|
||||||
PLOG_F("daemon");
|
PLOG_F("daemon");
|
||||||
}
|
}
|
||||||
cmdlineLogParams(&nsjconf);
|
cmdline::logParams(nsjconf.get());
|
||||||
if (nsjailSetSigHandlers() == false) {
|
if (nsjailSetSigHandlers() == false) {
|
||||||
LOG_F("nsjailSetSigHandlers() failed");
|
LOG_F("nsjailSetSigHandlers() failed");
|
||||||
}
|
}
|
||||||
if (nsjailSetTimer(&nsjconf) == false) {
|
if (nsjailSetTimer(nsjconf.get()) == false) {
|
||||||
LOG_F("nsjailSetTimer() failed");
|
LOG_F("nsjailSetTimer() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsjconf.mode == MODE_LISTEN_TCP) {
|
if (nsjconf->mode == MODE_LISTEN_TCP) {
|
||||||
nsjailListenMode(&nsjconf);
|
nsjailListenMode(nsjconf.get());
|
||||||
} else {
|
} else {
|
||||||
return nsjailStandaloneMode(&nsjconf);
|
return nsjailStandaloneMode(nsjconf.get());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user