cmdline: move to C++
authorRobert Swiecki <robert@swiecki.net>
Fri, 9 Feb 2018 14:44:29 +0000 (15:44 +0100)
committerRobert Swiecki <robert@swiecki.net>
Fri, 9 Feb 2018 14:44:29 +0000 (15:44 +0100)
Makefile
cmdline.cc [moved from cmdline.c with 83% similarity]
cmdline.h
config.cc
nsjail.cc

index 98adb7d..2fa4837 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -30,13 +30,13 @@ COMMON_FLAGS += -O2 -c \
 CFLAGS += $(COMMON_FLAGS) \
        -std=gnu11
 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)
 
 BIN = nsjail
 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_CXX = nsjail.cc config.cc
+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 = cmdline.cc config.cc nsjail.cc
 SRCS_PROTO = config.proto
 SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc)
 SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h)
@@ -97,10 +97,7 @@ indent:
 
 # 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
-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
@@ -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
 uts.o: uts.h nsjail.h log.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
-config.o: util.h
+cmdline.o: cmdline.h nsjail.h caps.h common.h log.h mount.h sandbox.h user.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
similarity index 83%
rename from cmdline.c
rename to cmdline.cc
index 937ea36..d69ea3c 100644 (file)
--- a/cmdline.c
 #include <strings.h>
 #include <sys/mount.h>
 #include <sys/personality.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
+
+extern "C" {
 #include "caps.h"
 #include "common.h"
-#include "config.h"
 #include "log.h"
 #include "mount.h"
 #include "sandbox.h"
 #include "user.h"
 #include "util.h"
+}
+
+#include "config.h"
+
+namespace cmdline {
 
 struct custom_option {
        struct option opt;
@@ -194,7 +202,7 @@ static void cmdlineUsage(const char* pname) {
        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) {
        case 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) {
                return RLIM64_INFINITY;
        }
@@ -315,71 +323,71 @@ static char* cmdlineSplitStrByColon(char* spec) {
        }
 }
 
-bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
-       (*nsjconf) = (const struct nsjconf_t){
-           .exec_file = NULL,
-           .use_execveat = false,
-           .exec_fd = -1,
-           .argv = NULL,
-           .hostname = "NSJAIL",
-           .cwd = "/",
-           .chroot = NULL,
-           .port = 0,
-           .bindhost = "::",
-           .log_fd = STDERR_FILENO,
-           .logfile = NULL,
-           .loglevel = INFO,
-           .daemonize = false,
-           .tlimit = 0,
-           .max_cpus = 0,
-           .keep_caps = false,
-           .disable_no_new_privs = false,
-           .rl_as = 512 * (1024 * 1024),
-           .rl_core = 0,
-           .rl_cpu = 600,
-           .rl_fsize = 1 * (1024 * 1024),
-           .rl_nofile = 32,
-           .rl_nproc = cmdlineParseRLimit(RLIMIT_NPROC, "soft", 1),
-           .rl_stack = cmdlineParseRLimit(RLIMIT_STACK, "soft", 1),
-           .personality = 0,
-           .clone_newnet = true,
-           .clone_newuser = true,
-           .clone_newns = true,
-           .clone_newpid = true,
-           .clone_newipc = true,
-           .clone_newuts = true,
-           .clone_newcgroup = true,
-           .mode = MODE_STANDALONE_ONCE,
-           .is_root_rw = false,
-           .is_silent = false,
-           .skip_setsid = false,
-           .max_conns_per_ip = 0,
-           .tmpfs_size = 4 * (1024 * 1024),
-           .mount_proc = true,
-           .proc_path = "/proc",
-           .is_proc_rw = false,
-           .cgroup_mem_mount = "/sys/fs/cgroup/memory",
-           .cgroup_mem_parent = "NSJAIL",
-           .cgroup_mem_max = (size_t)0,
-           .cgroup_pids_mount = "/sys/fs/cgroup/pids",
-           .cgroup_pids_parent = "NSJAIL",
-           .cgroup_pids_max = 0U,
-           .cgroup_net_cls_mount = "/sys/fs/cgroup/net_cls",
-           .cgroup_net_cls_parent = "NSJAIL",
-           .cgroup_net_cls_classid = 0U,
-           .cgroup_cpu_mount = "/sys/fs/cgroup/cpu",
-           .cgroup_cpu_parent = "NSJAIL",
-           .cgroup_cpu_ms_per_sec = 0U,
-           .iface_no_lo = false,
-           .iface_vs = NULL,
-           .iface_vs_ip = "0.0.0.0",
-           .iface_vs_nm = "255.255.255.0",
-           .iface_vs_gw = "0.0.0.0",
-           .kafel_file_path = NULL,
-           .kafel_string = NULL,
-           .orig_uid = getuid(),
-           .num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
-       };
+std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
+       std::unique_ptr<struct nsjconf_t> nsjconf = std::make_unique<struct nsjconf_t>();
+
+       nsjconf->exec_file = NULL;
+       nsjconf->use_execveat = false;
+       nsjconf->exec_fd = -1;
+       nsjconf->argv = NULL;
+       nsjconf->hostname = "NSJAIL";
+       nsjconf->cwd = "/";
+       nsjconf->chroot = NULL;
+       nsjconf->port = 0;
+       nsjconf->bindhost = "::";
+       nsjconf->log_fd = STDERR_FILENO;
+       nsjconf->logfile = NULL;
+       nsjconf->loglevel = INFO;
+       nsjconf->daemonize = false;
+       nsjconf->tlimit = 0;
+       nsjconf->max_cpus = 0;
+       nsjconf->keep_caps = false;
+       nsjconf->disable_no_new_privs = false;
+       nsjconf->rl_as = 512 * (1024 * 1024);
+       nsjconf->rl_core = 0;
+       nsjconf->rl_cpu = 600;
+       nsjconf->rl_fsize = 1 * (1024 * 1024);
+       nsjconf->rl_nofile = 32;
+       nsjconf->rl_nproc = parseRLimit(RLIMIT_NPROC, "soft", 1);
+       nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, "soft", 1);
+       nsjconf->personality = 0;
+       nsjconf->clone_newnet = true;
+       nsjconf->clone_newuser = true;
+       nsjconf->clone_newns = true;
+       nsjconf->clone_newpid = true;
+       nsjconf->clone_newipc = true;
+       nsjconf->clone_newuts = true;
+       nsjconf->clone_newcgroup = true;
+       nsjconf->mode = MODE_STANDALONE_ONCE;
+       nsjconf->is_root_rw = false;
+       nsjconf->is_silent = false;
+       nsjconf->skip_setsid = false;
+       nsjconf->max_conns_per_ip = 0;
+       nsjconf->tmpfs_size = 4 * (1024 * 1024);
+       nsjconf->mount_proc = true;
+       nsjconf->proc_path = "/proc";
+       nsjconf->is_proc_rw = false;
+       nsjconf->cgroup_mem_mount = "/sys/fs/cgroup/memory";
+       nsjconf->cgroup_mem_parent = "NSJAIL";
+       nsjconf->cgroup_mem_max = (size_t)0;
+       nsjconf->cgroup_pids_mount = "/sys/fs/cgroup/pids";
+       nsjconf->cgroup_pids_parent = "NSJAIL";
+       nsjconf->cgroup_pids_max = 0U;
+       nsjconf->cgroup_net_cls_mount = "/sys/fs/cgroup/net_cls";
+       nsjconf->cgroup_net_cls_parent = "NSJAIL";
+       nsjconf->cgroup_net_cls_classid = 0U;
+       nsjconf->cgroup_cpu_mount = "/sys/fs/cgroup/cpu";
+       nsjconf->cgroup_cpu_parent = "NSJAIL";
+       nsjconf->cgroup_cpu_ms_per_sec = 0U;
+       nsjconf->iface_no_lo = false;
+       nsjconf->iface_vs = NULL;
+       nsjconf->iface_vs_ip = "0.0.0.0";
+       nsjconf->iface_vs_nm = "255.255.255.0";
+       nsjconf->iface_vs_gw = "0.0.0.0";
+       nsjconf->kafel_file_path = NULL;
+       nsjconf->kafel_string = NULL;
+       nsjconf->orig_uid = getuid();
+       nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 
        TAILQ_INIT(&nsjconf->pids);
        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";
 
        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;
        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;
        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;
        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;
                        break;
                case 'C':
-                       if (configParse(nsjconf, optarg) == false) {
+                       if (configParse(nsjconf.get(), optarg) == false) {
                                LOG_F("Couldn't parse configuration from '%s' file", optarg);
                        }
                        break;
@@ -452,14 +460,14 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        break;
                case 'l':
                        nsjconf->logfile = optarg;
-                       if (logInitLogFile(nsjconf) == false) {
-                               return false;
+                       if (logInitLogFile(nsjconf.get()) == false) {
+                               return nullptr;
                        }
                        break;
                case 'L':
                        nsjconf->log_fd = strtol(optarg, NULL, 0);
-                       if (logInitLogFile(nsjconf) == false) {
-                               return false;
+                       if (logInitLogFile(nsjconf.get()) == false) {
+                               return nullptr;
                        }
                        break;
                case 'd':
@@ -467,20 +475,20 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        break;
                case 'v':
                        nsjconf->loglevel = DEBUG;
-                       if (logInitLogFile(nsjconf) == false) {
-                               return false;
+                       if (logInitLogFile(nsjconf.get()) == false) {
+                               return nullptr;
                        }
                        break;
                case 'q':
                        nsjconf->loglevel = WARNING;
-                       if (logInitLogFile(nsjconf) == false) {
-                               return false;
+                       if (logInitLogFile(nsjconf.get()) == false) {
+                               return nullptr;
                        }
                        break;
                case 'Q':
                        nsjconf->loglevel = FATAL;
-                       if (logInitLogFile(nsjconf) == false) {
-                               return false;
+                       if (logInitLogFile(nsjconf.get()) == false) {
+                               return nullptr;
                        }
                        break;
                case 'e':
@@ -494,25 +502,25 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        exit(0);
                        break;
                case 0x0201:
-                       nsjconf->rl_as = cmdlineParseRLimit(RLIMIT_AS, optarg, (1024 * 1024));
+                       nsjconf->rl_as = parseRLimit(RLIMIT_AS, optarg, (1024 * 1024));
                        break;
                case 0x0202:
-                       nsjconf->rl_core = cmdlineParseRLimit(RLIMIT_CORE, optarg, (1024 * 1024));
+                       nsjconf->rl_core = parseRLimit(RLIMIT_CORE, optarg, (1024 * 1024));
                        break;
                case 0x0203:
-                       nsjconf->rl_cpu = cmdlineParseRLimit(RLIMIT_CPU, optarg, 1);
+                       nsjconf->rl_cpu = parseRLimit(RLIMIT_CPU, optarg, 1);
                        break;
                case 0x0204:
-                       nsjconf->rl_fsize = cmdlineParseRLimit(RLIMIT_FSIZE, optarg, (1024 * 1024));
+                       nsjconf->rl_fsize = parseRLimit(RLIMIT_FSIZE, optarg, (1024 * 1024));
                        break;
                case 0x0205:
-                       nsjconf->rl_nofile = cmdlineParseRLimit(RLIMIT_NOFILE, optarg, 1);
+                       nsjconf->rl_nofile = parseRLimit(RLIMIT_NOFILE, optarg, 1);
                        break;
                case 0x0206:
-                       nsjconf->rl_nproc = cmdlineParseRLimit(RLIMIT_NPROC, optarg, 1);
+                       nsjconf->rl_nproc = parseRLimit(RLIMIT_NPROC, optarg, 1);
                        break;
                case 0x0207:
-                       nsjconf->rl_stack = cmdlineParseRLimit(RLIMIT_STACK, optarg, (1024 * 1024));
+                       nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, optarg, (1024 * 1024));
                        break;
                case 0x0301:
                        nsjconf->personality |= ADDR_COMPAT_LAYOUT;
@@ -564,7 +572,7 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        break;
                case 0x0505: {
                        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);
                        TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
                } break;
@@ -575,10 +583,11 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        nsjconf->max_cpus = strtoul(optarg, NULL, 0);
                        break;
                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);
                        if (f->val == -1) {
-                               return false;
+                               return nullptr;
                        }
                        TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
                } break;
@@ -603,7 +612,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        nsjconf->use_execveat = true;
                        break;
                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;
                        TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
                } break;
@@ -613,9 +623,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        char* cnt = cmdlineSplitStrByColon(o_id);
                        size_t count =
                            (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) {
-                               return false;
+                               return nullptr;
                        }
                } break;
                case 'g': {
@@ -624,9 +634,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        char* cnt = cmdlineSplitStrByColon(o_id);
                        size_t count =
                            (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) {
-                               return false;
+                               return nullptr;
                        }
                } break;
                case 'U': {
@@ -635,9 +645,9 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        char* cnt = cmdlineSplitStrByColon(o_id);
                        size_t count =
                            (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) {
-                               return false;
+                               return nullptr;
                        }
                } break;
                case 'G': {
@@ -646,38 +656,40 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        char* cnt = cmdlineSplitStrByColon(o_id);
                        size_t count =
                            (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) {
-                               return false;
+                               return nullptr;
                        }
                } break;
                case 'R': {
                        const char* dst = cmdlineSplitStrByColon(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,
                                /* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
                                0, /* is_symlink= */ false)) {
-                               return false;
+                               return nullptr;
                        }
                }; break;
                case 'B': {
                        const char* dst = cmdlineSplitStrByColon(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,
                                /* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL,
                                0, /* is_symlink= */ false)) {
-                               return false;
+                               return nullptr;
                        }
                }; break;
                case 'T': {
-                       if (!mountAddMountPtTail(nsjconf, /* src= */ NULL, optarg, "tmpfs",
+                       if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, optarg, "tmpfs",
                                /* options= */ cmdlineTmpfsSz, /* flags= */ 0,
                                /* isDir= */ NS_DIR_YES,
                                /* mandatory= */ true, NULL, NULL, NULL, 0,
                                /* is_symlink= */ false)) {
-                               return false;
+                               return nullptr;
                        }
                }; break;
                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 e - MODE_STANDALONE_EXECVE");
                                cmdlineUsage(argv[0]);
-                               return false;
+                               return nullptr;
                                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) {
                                PLOG_E("kafel config file '%s' cannot be opened for reading",
                                    nsjconf->kafel_file_path);
-                               return false;
+                               return nullptr;
                        }
                        break;
                case 0x0901:
@@ -768,37 +780,39 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                        break;
                default:
                        cmdlineUsage(argv[0]);
-                       return false;
+                       return nullptr;
                        break;
                }
        }
 
        if (nsjconf->mount_proc) {
-               if (!mountAddMountPtTail(nsjconf, /* src= */ NULL, nsjconf->proc_path, "proc", "",
-                       nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
+               if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, nsjconf->proc_path, "proc",
+                       "", nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
                        /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
-                       return false;
+                       return nullptr;
                }
        }
        if (nsjconf->chroot) {
-               if (!mountAddMountPtHead(nsjconf, nsjconf->chroot, "/", /* fs_type= */ "",
+               if (!mountAddMountPtHead(nsjconf.get(), nsjconf->chroot, "/", /* fs_type= */ "",
                        /* options= */ "",
                        nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE)
                                            : (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
                        /* isDir= */ NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0,
                        /* is_symlink= */ false)) {
-                       return false;
+                       return nullptr;
                }
        } else {
-               if (!mountAddMountPtHead(nsjconf, /* src= */ NULL, "/", "tmpfs", /* options= */ "",
-                       nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES,
+               if (!mountAddMountPtHead(nsjconf.get(), /* src= */ NULL, "/", "tmpfs",
+                       /* options= */ "", nsjconf->is_root_rw ? 0 : MS_RDONLY,
+                       /* isDir= */ NS_DIR_YES,
                        /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
-                       return false;
+                       return nullptr;
                }
        }
 
        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->outside_id = getuid();
                p->count = 1U;
@@ -806,7 +820,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                TAILQ_INSERT_HEAD(&nsjconf->uids, p, pointers);
        }
        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->outside_id = getgid();
                p->count = 1U;
@@ -814,8 +829,8 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                TAILQ_INSERT_HEAD(&nsjconf->gids, p, pointers);
        }
 
-       if (logInitLogFile(nsjconf) == false) {
-               return false;
+       if (logInitLogFile(nsjconf.get()) == false) {
+               return nullptr;
        }
 
        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) {
                cmdlineUsage(argv[0]);
                LOG_E("No command provided");
-               return false;
+               return nullptr;
        }
        if (nsjconf->exec_file == NULL) {
                nsjconf->exec_file = nsjconf->argv[0];
@@ -835,19 +850,21 @@ bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf) {
                LOG_E(
                    "Your nsjail is compiled without support for the execveat() syscall, yet you "
                    "specified the --execute_fd flag");
-               return false;
+               return nullptr;
 #endif /* !defined(__NR_execveat) */
                if ((nsjconf->exec_fd = open(nsjconf->exec_file, O_RDONLY | O_PATH | O_CLOEXEC)) ==
                    -1) {
                        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");
-               return false;
+               return nullptr;
        }
 
-       return true;
+       return nsjconf;
 }
+
+}  // namespace cmdline
index 7fdf5ee..22b4e89 100644 (file)
--- a/cmdline.h
+++ b/cmdline.h
 #ifndef NS_CMDLINE_H
 #define NS_CMDLINE_H
 
-#include <stdbool.h>
 #include <stdint.h>
-#include <sys/resource.h>
-#include <sys/time.h>
+
+#include <memory>
 
 #include "nsjail.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+namespace cmdline {
 
-uint64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul);
-void cmdlineLogParams(struct nsjconf_t* nsjconf);
-bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf);
+uint64_t parseRLimit(int res, const char* optarg, unsigned long mul);
+void logParams(struct nsjconf_t* nsjconf);
+std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]);
 
-#ifdef __cplusplus
-}  // extern "C"
-#endif
+}  // namespace cmdline
 
 #endif /* _CMDLINE_H */
index 97cb698..5d0d8d6 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -26,11 +26,11 @@ extern "C" {
 #include <stdio.h>
 #include <sys/mount.h>
 #include <sys/personality.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
 #include "caps.h"
-#include "cmdline.h"
 #include "config.h"
 #include "log.h"
 #include "mount.h"
@@ -38,6 +38,8 @@ extern "C" {
 #include "util.h"
 }
 
+#include "cmdline.h"
+
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/text_format.h>
 #include <fstream>
@@ -54,10 +56,10 @@ static uint64_t configRLimit(
                return (val * mul);
        }
        if (rl == nsjail::RLimit::SOFT) {
-               return cmdlineParseRLimit(res, "soft", mul);
+               return cmdline::parseRLimit(res, "soft", mul);
        }
        if (rl == nsjail::RLimit::HARD) {
-               return cmdlineParseRLimit(res, "hard", mul);
+               return cmdline::parseRLimit(res, "hard", mul);
        }
        if (rl == nsjail::RLimit::INF) {
                return RLIM64_INFINITY;
index 3e92b50..5a5b926 100644 (file)
--- a/nsjail.cc
+++ b/nsjail.cc
@@ -157,28 +157,28 @@ static int nsjailStandaloneMode(struct nsjconf_t* nsjconf) {
 }
 
 int main(int argc, char* argv[]) {
-       struct nsjconf_t nsjconf;
-       if (!cmdlineParse(argc, argv, &nsjconf)) {
+       std::unique_ptr<struct nsjconf_t> nsjconf = cmdline::parseArgs(argc, argv);
+       if (!nsjconf) {
                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");
        }
-       if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
+       if (nsjconf->daemonize && (daemon(0, 0) == -1)) {
                PLOG_F("daemon");
        }
-       cmdlineLogParams(&nsjconf);
+       cmdline::logParams(nsjconf.get());
        if (nsjailSetSigHandlers() == false) {
                LOG_F("nsjailSetSigHandlers() failed");
        }
-       if (nsjailSetTimer(&nsjconf) == false) {
+       if (nsjailSetTimer(nsjconf.get()) == false) {
                LOG_F("nsjailSetTimer() failed");
        }
 
-       if (nsjconf.mode == MODE_LISTEN_TCP) {
-               nsjailListenMode(&nsjconf);
+       if (nsjconf->mode == MODE_LISTEN_TCP) {
+               nsjailListenMode(nsjconf.get());
        } else {
-               return nsjailStandaloneMode(&nsjconf);
+               return nsjailStandaloneMode(nsjconf.get());
        }
        return 0;
 }