config: Initial work on converting config.c to c++ protobuf lib
authorRobert Swiecki <robert@swiecki.net>
Wed, 13 Sep 2017 20:03:21 +0000 (22:03 +0200)
committerRobert Swiecki <robert@swiecki.net>
Thu, 14 Sep 2017 19:17:38 +0000 (21:17 +0200)
config: Initial work on converting config.c to c++ protobuf lib #2

config: Initial work on converting config.c to c++ protobuf lib #3

config: Initial work on converting config.c to c++ protobuf lib #4

config: Initial work on converting config.c to c++ protobuf lib #5

config: Initial work on converting config.c to c++ protobuf lib #6

24 files changed:
.gitmodules
Makefile
caps.c
cmdline.c
common.h
config.c [deleted file]
config.cc [new file with mode: 0644]
config.h
config.proto
configs/apache.cfg
configs/bash-with-fake-geteuid.cfg
configs/demo-dont-use-chrome-with-net.cfg
configs/firefox-with-cloned-net.cfg
configs/firefox-with-net.cfg
configs/home-documents-with-xorg-no-net.cfg
configs/imagemagick-convert.cfg
log.c
mount.c
mount.h
net.c
nsjail.c
protobuf-c-text [deleted submodule]
subproc.c
user.c

index 53c4720..4c3ff73 100644 (file)
@@ -1,6 +1,3 @@
 [submodule "kafel"]
        path = kafel
        url = https://github.com/google/kafel.git
-[submodule "protobuf-c-text"]
-       path = protobuf-c-text
-       url = https://github.com/protobuf-c/protobuf-c-text.git
index 60d9b33..289a021 100644 (file)
--- a/Makefile
+++ b/Makefile
 #
 
 CC ?= gcc
+CXX ?= g++
 
-EXTRA_CFLAGS := $(CFLAGS)
-
-CFLAGS += -O2 -c -std=gnu11 \
+COMMON_FLAGS += -O2 -c \
        -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \
        -Wformat -Wformat=2 -Wformat-security -fPIE \
        -Wno-format-nonliteral \
        -Wall -Wextra -Werror \
        -Ikafel/include
 
-LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie -Wl,-z,noexecstack -lpthread -lcap
+CFLAGS += $(COMMON_FLAGS) -std=gnu11 
+CXXFLAGS += $(COMMON_FLAGS) $(shell pkg-config --cflags protobuf) -std=c++11 -Wno-unused
+
+LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie -Wl,-z,noexecstack -lpthread -lcap $(shell pkg-config --libs protobuf)
 
 BIN = nsjail
 LIBS = kafel/libkafel.a
-SRCS = nsjail.c caps.c cmdline.c config.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
-OBJS = $(SRCS:.c=.o)
+SRCS_C = nsjail.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 = config.cc
+SRCS_PB = config.proto
+OBJS = $(SRCS_C:.c=.o) $(SRCS_CXX:.cc=.o) $(SRCS_PB:.proto=.pb.o)
+PROTO_DEPS = config.pb.cc config.pb.h
 
 ifdef DEBUG
        CFLAGS += -g -ggdb -gdwarf-4
+       CXXFLAGS += -g -ggdb -gdwarf-4
 endif
 
 USE_NL3 ?= yes
@@ -48,58 +54,18 @@ ifeq ($(NL3_EXISTS), yes)
 endif
 endif
 
-USE_PROTOBUF ?= yes
-ifeq ($(USE_PROTOBUF), yes)
-ifeq ("$(shell which protoc-c)", "")
-       USE_PROTOBUF := no
-       PROTOC_WARNING := yes
-endif
-endif
-
-ifeq ($(USE_PROTOBUF), no)
-else ifeq ($(shell pkg-config --exists libprotobuf-c && echo yes), yes)
-       PROTO_DEPS = config.pb-c.h config.pb-c.c
-       SRCS += config.pb-c.c
-       CFLAGS += -DNSJAIL_WITH_PROTOBUF -Iprotobuf-c-text/protobuf-c-text $(shell pkg-config --cflags libprotobuf-c)
-       LIBS += protobuf-c-text/protobuf-c-text/.libs/libprotobuf-c-text.a
-       LDFLAGS += $(shell pkg-config --libs libprotobuf-c)
-else ifneq ("$(wildcard /usr/include/google/protobuf-c/protobuf-c.h)", "")
-       PROTO_DEPS = config.pb-c.h config.pb-c.c
-       SRCS += config.pb-c.c
-       CFLAGS += -DNSJAIL_WITH_PROTOBUF -Iprotobuf-c-text/protobuf-c-text -I/usr/include/google
-       LIBS += protobuf-c-text/protobuf-c-text/.libs/libprotobuf-c-text.a
-       LDFLAGS += -Wl,-lprotobuf-c
-else ifneq ("$(wildcard /usr/local/include/google/protobuf-c/protobuf-c.h)", "")
-       PROTO_DEPS = config.pb-c.h config.pb-c.c
-       SRCS += config.pb-c.c
-       CFLAGS += -DNSJAIL_WITH_PROTOBUF -Iprotobuf-c-text/protobuf-c-text -I/usr/local/include/google
-       LIBS += protobuf-c-text/protobuf-c-text/.libs/libprotobuf-c-text.a
-       LDFLAGS += -Wl,--library-path=/usr/local/lib -Wl,-lprotobuf-c
-else
-       USE_PROTOBUF := no
-endif
-
 .PHONY: all clear depend indent
 
 .c.o: %.c
        $(CC) $(CFLAGS) $< -o $@
 
+.cc.o: %.cc
+       $(CXX) $(CXXFLAGS) $< -o $@
+
 all: $(PROTO_DEPS) $(BIN)
-ifeq ($(PROTOC_WARNING), yes)
-       $(info *********************************************************)
-       $(info *        'protoc-c' is missing on your system           *)
-       $(info *  Install 'protobuf-c-compiler' or a similar package   *)
-       $(info *********************************************************)
-endif
-ifeq ($(USE_PROTOBUF), no)
-       $(info *********************************************************)
-       $(info * Code compiled without libprotobuf-c/libprotobuf-c-dev *)
-       $(info *  The --config commandline option will be unavailable  *)
-       $(info *********************************************************)
-endif
 
 $(BIN): $(LIBS) $(OBJS)
-       $(CC) -o $(BIN) $(OBJS) $(LIBS) $(LDFLAGS)
+       $(CXX) -o $(BIN) $(OBJS) $(LIBS) $(LDFLAGS)
 
 kafel/libkafel.a:
 ifeq ("$(wildcard kafel/Makefile)","")
@@ -107,39 +73,27 @@ ifeq ("$(wildcard kafel/Makefile)","")
 endif
        $(MAKE) -C kafel
 
-protobuf-c-text/protobuf-c-text/.libs/libprotobuf-c-text.a:
-ifeq ("$(wildcard protobuf-c-text/configure)","")
-       git submodule update --init
-endif
-ifeq ("$(wildcard protobuf-c-text/Makefile)","")
-       sh -c "cd protobuf-c-text; CFLAGS=\"-fPIC -I/usr/include/google $(EXTRA_CFLAGS)\" ./autogen.sh --enable-shared=no --disable-doxygen-doc;"
-endif
-       $(MAKE) -C protobuf-c-text
-
-$(PROTO_DEPS): config.proto
-       protoc-c --c_out=. config.proto
+$(PROTO_DEPS): $(SRCS_PB)
+       protoc --cpp_out=. $(SRCS_PB)
 
 clean:
        $(RM) core Makefile.bak $(OBJS) $(BIN) $(PROTO_DEPS)
 ifneq ("$(wildcard kafel/Makefile)","")
        $(MAKE) -C kafel clean
 endif
-ifneq ("$(wildcard protobuf-c-text/Makefile)","")
-       $(MAKE) -C protobuf-c-text clean
-endif
 
 depend:
-       makedepend -Y -Ykafel/include -- -- $(SRCS)
+       makedepend -Y -Ykafel/include -- -- $(SRCS_C) $(SRCS_CXX)
 
 indent:
+       clang-format --style=WebKit -i -sort-includes *.c *.h $(SRCS_CXX)
        indent -linux -l100 -lc100 *.c *.h; rm -f *~
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
 nsjail.o: nsjail.h common.h caps.h cmdline.h log.h net.h subproc.h util.h
 caps.o: caps.h common.h log.h util.h
-cmdline.o: cmdline.h common.h caps.h config.h log.h mount.h util.h user.h
-config.o: common.h caps.h config.h log.h mount.h user.h util.h
+cmdline.o: cmdline.h common.h caps.h config.h log.h mount.h user.h util.h
 contain.o: contain.h common.h caps.h cgroup.h cpu.h log.h mount.h net.h pid.h
 contain.o: user.h util.h uts.h
 log.o: log.h common.h
@@ -154,3 +108,4 @@ user.o: user.h common.h log.h subproc.h util.h
 util.o: util.h common.h log.h
 uts.o: uts.h common.h log.h
 cpu.o: cpu.h common.h log.h util.h
+config.o: common.h caps.h config.h log.h mount.h user.h util.h
diff --git a/caps.c b/caps.c
index 5a17ccb..774ede2 100644 (file)
--- a/caps.c
+++ b/caps.c
@@ -21,8 +21,8 @@
 
 #include "caps.h"
 
-#include <sys/capability.h>
 #include <string.h>
+#include <sys/capability.h>
 #include <sys/prctl.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include "log.h"
 #include "util.h"
 
-#define VALSTR_STRUCT(x) { x, #x }
+#define VALSTR_STRUCT(x) \
+    {                    \
+        x, #x            \
+    }
 
 /*  *INDENT-OFF* */
 static struct {
-       const int val;
-       const char* const name;
+    const int val;
+    const char* const name;
 } const capNames[] = {
     VALSTR_STRUCT(CAP_CHOWN),
     VALSTR_STRUCT(CAP_DAC_OVERRIDE),
@@ -76,7 +79,7 @@ static struct {
     VALSTR_STRUCT(CAP_BLOCK_SUSPEND),
 #if defined(CAP_AUDIT_READ)
     VALSTR_STRUCT(CAP_AUDIT_READ),
-#endif  /* defined(CAP_AUDIT_READ) */
+#endif /* defined(CAP_AUDIT_READ) */
 };
 /*  *INDENT-ON* */
 
@@ -209,7 +212,8 @@ bool capsInitNs(struct nsjconf_t *nsjconf)
                        }
                        if (prctl
                            (PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)capNames[i].val,
-                            0UL, 0UL) == -1) {
+                            0UL, 0UL)
+                           == -1) {
                                PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)",
                                       capNames[i].name);
                        } else {
@@ -219,9 +223,9 @@ bool capsInitNs(struct nsjconf_t *nsjconf)
        } else {
                struct ints_t *p;
                TAILQ_FOREACH(p, &nsjconf->caps, pointers) {
-                       if (prctl
-                           (PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)p->val, 0UL,
-                            0UL) == -1) {
+                       if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)p->val, 0UL,
+                                 0UL)
+                           == -1) {
                                PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)",
                                       capsValToStr(p->val));
                        } else {
index a3ac216..66f758e 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -45,8 +45,8 @@
 #include "config.h"
 #include "log.h"
 #include "mount.h"
-#include "util.h"
 #include "user.h"
+#include "util.h"
 
 struct custom_option {
        struct option opt;
@@ -55,91 +55,91 @@ struct custom_option {
 
 /* *INDENT-OFF* */
 struct custom_option custom_opts[] = {
-    {{"help", no_argument, NULL, 'h'}, "Help plz.."},
-    {{"mode", required_argument, NULL, 'M'},
-     "Execution mode (default: o [MODE_STANDALONE_ONCE]):\n"
-     "\tl: Wait for connections on a TCP port (specified with --port) "
-     "[MODE_LISTEN_TCP]\n"
-     "\to: Immediately launch a single process on the console using "
-     "clone/execve [MODE_STANDALONE_ONCE]\n"
-     "\te: Immediately launch a single process on the console using execve "
-     "[MODE_STANDALONE_EXECVE]\n"
-     "\tr: Immediately launch a single process on the console, keep doing it "
-     "forever [MODE_STANDALONE_RERUN]"},
-    {{"config", required_argument, NULL, 'C'}, "Configuration file in the config.proto ProtoBuf format"},
-    {{"exec_file", required_argument, NULL, 'x'}, "File to exec (default: argv[0])"},
-    {{"chroot", required_argument, NULL, 'c'}, "Directory containing / of the jail (default: none)"},
-    {{"rw", no_argument, NULL, 0x601}, "Mount / and /proc as RW (default: RO)"},
-    {{"user", required_argument, NULL, 'u'}, "Username/uid of processess inside the jail (default: your current uid). You can also use inside_ns_uid:outside_ns_uid:count convention here. Can be specified multiple times"},
-    {{"group", required_argument, NULL, 'g'}, "Groupname/gid of processess inside the jail (default: your current gid). You can also use inside_ns_gid:global_ns_gid:count convention here. Can be specified multiple times"},
-    {{"hostname", required_argument, NULL, 'H'}, "UTS name (hostname) of the jail (default: 'NSJAIL')"},
-    {{"cwd", required_argument, NULL, 'D'}, "Directory in the namespace the process will run (default: '/')"},
-    {{"port", required_argument, NULL, 'p'}, "TCP port to bind to (enables MODE_LISTEN_TCP) (default: 0)"},
-    {{"bindhost", required_argument, NULL, 0x604}, "IP address to bind the port to (only in [MODE_LISTEN_TCP]), (default: '::')"},
-    {{"max_conns_per_ip", required_argument, NULL, 'i'}, "Maximum number of connections per one IP (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited))"},
-    {{"log", required_argument, NULL, 'l'}, "Log file (default: use log_fd)"},
-    {{"log_fd", required_argument, NULL, 'L'}, "Log FD (default: 2)"},
-    {{"time_limit", required_argument, NULL, 't'}, "Maximum time that a jail can exist, in seconds (default: 600)"},
-    {{"max_cpus", required_argument, NULL, 0x508}, "Maximum number of CPUs a single jailed process can use (default: 0 'no limit')"},
-    {{"daemon", no_argument, NULL, 'd'}, "Daemonize after start"},
-    {{"verbose", no_argument, NULL, 'v'}, "Verbose output"},
-    {{"quiet", no_argument, NULL, 'q'}, "Only output warning and more important messages"},
-    {{"keep_env", no_argument, NULL, 'e'}, "Should all environment variables be passed to the child?"},
-    {{"env", required_argument, NULL, 'E'}, "Environment variable (can be used multiple times)"},
-    {{"keep_caps", no_argument, NULL, 0x0501}, "Don't drop capabilities in the local namespace"},
-    {{"silent", no_argument, NULL, 0x0502}, "Redirect child's fd:0/1/2 to /dev/null"},
-    {{"skip_setsid", no_argument, NULL, 0x0504}, "Don't call setsid(), allows for terminal signal handling in the sandboxed process"},
-    {{"pass_fd", required_argument, NULL, 0x0505}, "Don't close this FD before executing child (can be specified multiple times), by default: 0/1/2 are kept open"},
-    {{"disable_no_new_privs", no_argument, NULL, 0x0507}, "Don't set the prctl(NO_NEW_PRIVS, 1) (DANGEROUS)"},
-    {{"cap", required_argument, NULL, 0x0509}, "Retain this capability in local namespace (e.g. CAP_PTRACE). Can be specified multiple times"},
-    {{"rlimit_as", required_argument, NULL, 0x0201}, "RLIMIT_AS in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 512)"},
-    {{"rlimit_core", required_argument, NULL, 0x0202}, "RLIMIT_CORE in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 0)"},
-    {{"rlimit_cpu", required_argument, NULL, 0x0203}, "RLIMIT_CPU, 'max' for RLIM_INFINITY, 'def' for the current value (default: 600)"},
-    {{"rlimit_fsize", required_argument, NULL, 0x0204}, "RLIMIT_FSIZE in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 1)"},
-    {{"rlimit_nofile", required_argument, NULL, 0x0205}, "RLIMIT_NOFILE, 'max' for RLIM_INFINITY, 'def' for the current value (default: 32)"},
-    {{"rlimit_nproc", required_argument, NULL, 0x0206}, "RLIMIT_NPROC, 'max' for RLIM_INFINITY, 'def' for the current value (default: 'def')"},
-    {{"rlimit_stack", required_argument, NULL, 0x0207}, "RLIMIT_STACK in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 'def')"},
-    {{"persona_addr_compat_layout", no_argument, NULL, 0x0301}, "personality(ADDR_COMPAT_LAYOUT)"},
-    {{"persona_mmap_page_zero", no_argument, NULL, 0x0302}, "personality(MMAP_PAGE_ZERO)"},
-    {{"persona_read_implies_exec", no_argument, NULL, 0x0303}, "personality(READ_IMPLIES_EXEC)"},
-    {{"persona_addr_limit_3gb", no_argument, NULL, 0x0304}, "personality(ADDR_LIMIT_3GB)"},
-    {{"persona_addr_no_randomize", no_argument, NULL, 0x0305}, "personality(ADDR_NO_RANDOMIZE)"},
-    {{"disable_clone_newnet", no_argument, NULL, 'N'}, "Don't use CLONE_NEWNET. Enable networking inside the jail"},
-    {{"disable_clone_newuser", no_argument, NULL, 0x0402}, "Don't use CLONE_NEWUSER. Requires euid==0"},
-    {{"disable_clone_newns", no_argument, NULL, 0x0403}, "Don't use CLONE_NEWNS"},
-    {{"disable_clone_newpid", no_argument, NULL, 0x0404}, "Don't use CLONE_NEWPID"},
-    {{"disable_clone_newipc", no_argument, NULL, 0x0405}, "Don't use CLONE_NEWIPC"},
-    {{"disable_clone_newuts", no_argument, NULL, 0x0406}, "Don't use CLONE_NEWUTS"},
-    {{"enable_clone_newcgroup", no_argument, NULL, 0x0407}, "Use CLONE_NEWCGROUP"},
-    {{"uid_mapping", required_argument, NULL, 'U'}, "Add a custom uid mapping of the form inside_uid:outside_uid:count. Setting this requires newuidmap to be present"},
-    {{"gid_mapping", required_argument, NULL, 'G'}, "Add a custom gid mapping of the form inside_gid:outside_gid:count. Setting this requires newgidmap to be present"},
-    {{"bindmount_ro", required_argument, NULL, 'R'}, "List of mountpoints to be mounted --bind (ro) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'"},
-    {{"bindmount", required_argument, NULL, 'B'}, "List of mountpoints to be mounted --bind (rw) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'"},
-    {{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax"},
-    {{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
-    {{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc in the jail"},
-    {{"seccomp_policy", required_argument, NULL, 'P'}, "Path to file containing seccomp-bpf policy (see kafel/)"},
-    {{"seccomp_string", required_argument, NULL, 0x0901}, "String with kafel seccomp-bpf policy (see kafel/)"},
-    {{"cgroup_mem_max", required_argument, NULL, 0x0801}, "Maximum number of bytes to use in the group (default: '0' - disabled)"},
-    {{"cgroup_mem_mount", required_argument, NULL, 0x0802}, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')"},
-    {{"cgroup_mem_parent", required_argument, NULL, 0x0803}, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')"},
-    {{"cgroup_pids_max", required_argument, NULL, 0x0811}, "Maximum number of pids in a cgroup (default: '0' - disabled)"},
-    {{"cgroup_pids_mount", required_argument, NULL, 0x0812}, "Location of pids cgroup FS (default: '/sys/fs/cgroup/pids')"},
-    {{"cgroup_pids_parent", required_argument, NULL, 0x0813}, "Which pre-existing pids cgroup to use as a parent (default: 'NSJAIL')"},
-    {{"iface_no_lo", no_argument, NULL, 0x700}, "Don't bring up the 'lo' interface"},
-    {{"macvlan_iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'"},
-    {{"macvlan_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface (e.g. \"192.168.0.1\")"},
-    {{"macvlan_vs_nm", required_argument, NULL, 0x702}, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")"},
-    {{"macvlan_vs_gw", required_argument, NULL, 0x703}, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")"},
+    { { "help", no_argument, NULL, 'h' }, "Help plz.." },
+    { { "mode", required_argument, NULL, 'M' },
+        "Execution mode (default: o [MODE_STANDALONE_ONCE]):\n"
+        "\tl: Wait for connections on a TCP port (specified with --port) "
+        "[MODE_LISTEN_TCP]\n"
+        "\to: Immediately launch a single process on the console using "
+        "clone/execve [MODE_STANDALONE_ONCE]\n"
+        "\te: Immediately launch a single process on the console using execve "
+        "[MODE_STANDALONE_EXECVE]\n"
+        "\tr: Immediately launch a single process on the console, keep doing it "
+        "forever [MODE_STANDALONE_RERUN]" },
+    { { "config", required_argument, NULL, 'C' }, "Configuration file in the config.proto ProtoBuf format" },
+    { { "exec_file", required_argument, NULL, 'x' }, "File to exec (default: argv[0])" },
+    { { "chroot", required_argument, NULL, 'c' }, "Directory containing / of the jail (default: none)" },
+    { { "rw", no_argument, NULL, 0x601 }, "Mount / and /proc as RW (default: RO)" },
+    { { "user", required_argument, NULL, 'u' }, "Username/uid of processess inside the jail (default: your current uid). You can also use inside_ns_uid:outside_ns_uid:count convention here. Can be specified multiple times" },
+    { { "group", required_argument, NULL, 'g' }, "Groupname/gid of processess inside the jail (default: your current gid). You can also use inside_ns_gid:global_ns_gid:count convention here. Can be specified multiple times" },
+    { { "hostname", required_argument, NULL, 'H' }, "UTS name (hostname) of the jail (default: 'NSJAIL')" },
+    { { "cwd", required_argument, NULL, 'D' }, "Directory in the namespace the process will run (default: '/')" },
+    { { "port", required_argument, NULL, 'p' }, "TCP port to bind to (enables MODE_LISTEN_TCP) (default: 0)" },
+    { { "bindhost", required_argument, NULL, 0x604 }, "IP address to bind the port to (only in [MODE_LISTEN_TCP]), (default: '::')" },
+    { { "max_conns_per_ip", required_argument, NULL, 'i' }, "Maximum number of connections per one IP (only in [MODE_LISTEN_TCP]), (default: 0 (unlimited))" },
+    { { "log", required_argument, NULL, 'l' }, "Log file (default: use log_fd)" },
+    { { "log_fd", required_argument, NULL, 'L' }, "Log FD (default: 2)" },
+    { { "time_limit", required_argument, NULL, 't' }, "Maximum time that a jail can exist, in seconds (default: 600)" },
+    { { "max_cpus", required_argument, NULL, 0x508 }, "Maximum number of CPUs a single jailed process can use (default: 0 'no limit')" },
+    { { "daemon", no_argument, NULL, 'd' }, "Daemonize after start" },
+    { { "verbose", no_argument, NULL, 'v' }, "Verbose output" },
+    { { "quiet", no_argument, NULL, 'q' }, "Only output warning and more important messages" },
+    { { "keep_env", no_argument, NULL, 'e' }, "Should all environment variables be passed to the child?" },
+    { { "env", required_argument, NULL, 'E' }, "Environment variable (can be used multiple times)" },
+    { { "keep_caps", no_argument, NULL, 0x0501 }, "Don't drop capabilities in the local namespace" },
+    { { "silent", no_argument, NULL, 0x0502 }, "Redirect child's fd:0/1/2 to /dev/null" },
+    { { "skip_setsid", no_argument, NULL, 0x0504 }, "Don't call setsid(), allows for terminal signal handling in the sandboxed process" },
+    { { "pass_fd", required_argument, NULL, 0x0505 }, "Don't close this FD before executing child (can be specified multiple times), by default: 0/1/2 are kept open" },
+    { { "disable_no_new_privs", no_argument, NULL, 0x0507 }, "Don't set the prctl(NO_NEW_PRIVS, 1) (DANGEROUS)" },
+    { { "cap", required_argument, NULL, 0x0509 }, "Retain this capability in local namespace (e.g. CAP_PTRACE). Can be specified multiple times" },
+    { { "rlimit_as", required_argument, NULL, 0x0201 }, "RLIMIT_AS in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 512)" },
+    { { "rlimit_core", required_argument, NULL, 0x0202 }, "RLIMIT_CORE in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 0)" },
+    { { "rlimit_cpu", required_argument, NULL, 0x0203 }, "RLIMIT_CPU, 'max' for RLIM_INFINITY, 'def' for the current value (default: 600)" },
+    { { "rlimit_fsize", required_argument, NULL, 0x0204 }, "RLIMIT_FSIZE in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 1)" },
+    { { "rlimit_nofile", required_argument, NULL, 0x0205 }, "RLIMIT_NOFILE, 'max' for RLIM_INFINITY, 'def' for the current value (default: 32)" },
+    { { "rlimit_nproc", required_argument, NULL, 0x0206 }, "RLIMIT_NPROC, 'max' for RLIM_INFINITY, 'def' for the current value (default: 'def')" },
+    { { "rlimit_stack", required_argument, NULL, 0x0207 }, "RLIMIT_STACK in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 'def')" },
+    { { "persona_addr_compat_layout", no_argument, NULL, 0x0301 }, "personality(ADDR_COMPAT_LAYOUT)" },
+    { { "persona_mmap_page_zero", no_argument, NULL, 0x0302 }, "personality(MMAP_PAGE_ZERO)" },
+    { { "persona_read_implies_exec", no_argument, NULL, 0x0303 }, "personality(READ_IMPLIES_EXEC)" },
+    { { "persona_addr_limit_3gb", no_argument, NULL, 0x0304 }, "personality(ADDR_LIMIT_3GB)" },
+    { { "persona_addr_no_randomize", no_argument, NULL, 0x0305 }, "personality(ADDR_NO_RANDOMIZE)" },
+    { { "disable_clone_newnet", no_argument, NULL, 'N' }, "Don't use CLONE_NEWNET. Enable networking inside the jail" },
+    { { "disable_clone_newuser", no_argument, NULL, 0x0402 }, "Don't use CLONE_NEWUSER. Requires euid==0" },
+    { { "disable_clone_newns", no_argument, NULL, 0x0403 }, "Don't use CLONE_NEWNS" },
+    { { "disable_clone_newpid", no_argument, NULL, 0x0404 }, "Don't use CLONE_NEWPID" },
+    { { "disable_clone_newipc", no_argument, NULL, 0x0405 }, "Don't use CLONE_NEWIPC" },
+    { { "disable_clone_newuts", no_argument, NULL, 0x0406 }, "Don't use CLONE_NEWUTS" },
+    { { "enable_clone_newcgroup", no_argument, NULL, 0x0407 }, "Use CLONE_NEWCGROUP" },
+    { { "uid_mapping", required_argument, NULL, 'U' }, "Add a custom uid mapping of the form inside_uid:outside_uid:count. Setting this requires newuidmap to be present" },
+    { { "gid_mapping", required_argument, NULL, 'G' }, "Add a custom gid mapping of the form inside_gid:outside_gid:count. Setting this requires newgidmap to be present" },
+    { { "bindmount_ro", required_argument, NULL, 'R' }, "List of mountpoints to be mounted --bind (ro) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'" },
+    { { "bindmount", required_argument, NULL, 'B' }, "List of mountpoints to be mounted --bind (rw) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'" },
+    { { "tmpfsmount", required_argument, NULL, 'T' }, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax" },
+    { { "tmpfs_size", required_argument, NULL, 0x0602 }, "Number of bytes to allocate for tmpfsmounts (default: 4194304)" },
+    { { "disable_proc", no_argument, NULL, 0x0603 }, "Disable mounting /proc in the jail" },
+    { { "seccomp_policy", required_argument, NULL, 'P' }, "Path to file containing seccomp-bpf policy (see kafel/)" },
+    { { "seccomp_string", required_argument, NULL, 0x0901 }, "String with kafel seccomp-bpf policy (see kafel/)" },
+    { { "cgroup_mem_max", required_argument, NULL, 0x0801 }, "Maximum number of bytes to use in the group (default: '0' - disabled)" },
+    { { "cgroup_mem_mount", required_argument, NULL, 0x0802 }, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')" },
+    { { "cgroup_mem_parent", required_argument, NULL, 0x0803 }, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')" },
+    { { "cgroup_pids_max", required_argument, NULL, 0x0811 }, "Maximum number of pids in a cgroup (default: '0' - disabled)" },
+    { { "cgroup_pids_mount", required_argument, NULL, 0x0812 }, "Location of pids cgroup FS (default: '/sys/fs/cgroup/pids')" },
+    { { "cgroup_pids_parent", required_argument, NULL, 0x0813 }, "Which pre-existing pids cgroup to use as a parent (default: 'NSJAIL')" },
+    { { "iface_no_lo", no_argument, NULL, 0x700 }, "Don't bring up the 'lo' interface" },
+    { { "macvlan_iface", required_argument, NULL, 'I' }, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'" },
+    { { "macvlan_vs_ip", required_argument, NULL, 0x701 }, "IP of the 'vs' interface (e.g. \"192.168.0.1\")" },
+    { { "macvlan_vs_nm", required_argument, NULL, 0x702 }, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")" },
+    { { "macvlan_vs_gw", required_argument, NULL, 0x703 }, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")" },
 };
 
 struct custom_option deprecated_opts[] = {
     // Compatibilty flags for MACVLAN.
     // TODO(rswiecki): Remove this at some point.
-    {{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'"},
-    {{"iface_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface (e.g. \"192.168.0.1\")"},
-    {{"iface_vs_nm", required_argument, NULL, 0x702}, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")"},
-    {{"iface_vs_gw", required_argument, NULL, 0x703}, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")"},
+    { { "iface", required_argument, NULL, 'I' }, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'" },
+    { { "iface_vs_ip", required_argument, NULL, 0x701 }, "IP of the 'vs' interface (e.g. \"192.168.0.1\")" },
+    { { "iface_vs_nm", required_argument, NULL, 0x702 }, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")" },
+    { { "iface_vs_gw", required_argument, NULL, 0x703 }, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")" },
 };
 /*  *INDENT-ON* */
 
@@ -306,61 +306,61 @@ static char *cmdlineSplitStrByColon(char *spec)
 
 bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
 {
-  /*  *INDENT-OFF* */
-  (*nsjconf) = (const struct nsjconf_t){
-      .exec_file = NULL,
-      .hostname = "NSJAIL",
-      .cwd = "/",
-      .chroot = NULL,
-      .argv = 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, "def", 1),
-      .rl_stack = cmdlineParseRLimit(RLIMIT_STACK, "def", 1),
-      .personality = 0,
-      .clone_newnet = true,
-      .clone_newuser = true,
-      .clone_newns = true,
-      .clone_newpid = true,
-      .clone_newipc = true,
-      .clone_newuts = true,
-      .clone_newcgroup = false,
-      .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,
-      .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 = (size_t)0,
-      .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 = NULL,
-      .kafel_string = NULL,
-      .num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
-  };
-  /*  *INDENT-ON* */
+    /*  *INDENT-OFF* */
+    (*nsjconf) = (const struct nsjconf_t){
+        .exec_file = NULL,
+        .hostname = "NSJAIL",
+        .cwd = "/",
+        .chroot = NULL,
+        .argv = 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, "def", 1),
+        .rl_stack = cmdlineParseRLimit(RLIMIT_STACK, "def", 1),
+        .personality = 0,
+        .clone_newnet = true,
+        .clone_newuser = true,
+        .clone_newns = true,
+        .clone_newpid = true,
+        .clone_newipc = true,
+        .clone_newuts = true,
+        .clone_newcgroup = false,
+        .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,
+        .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 = (size_t)0,
+        .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 = NULL,
+        .kafel_string = NULL,
+        .num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
+    };
+    /*  *INDENT-ON* */
 
        TAILQ_INIT(&nsjconf->pids);
        TAILQ_INIT(&nsjconf->mountpts);
@@ -576,12 +576,13 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                char *i_id = optarg;
                                char *o_id = cmdlineSplitStrByColon(i_id);
                                char *cnt = cmdlineSplitStrByColon(o_id);
-                               size_t count = (cnt == NULL
-                                               || strlen(cnt) == 0) ? 1U : (size_t) strtoull(cnt,
-                                                                                             NULL,
-                                                                                             0);
+                               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 */ ,
-                                               false /* is_newidmap */ ) == false) {
+                                               false /* is_newidmap */ )
+                                   == false) {
                                        return false;
                                }
                        }
@@ -590,12 +591,13 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                char *i_id = optarg;
                                char *o_id = cmdlineSplitStrByColon(i_id);
                                char *cnt = cmdlineSplitStrByColon(o_id);
-                               size_t count = (cnt == NULL
-                                               || strlen(cnt) == 0) ? 1U : (size_t) strtoull(cnt,
-                                                                                             NULL,
-                                                                                             0);
+                               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 */ ,
-                                               false /* is_newidmap */ ) == false) {
+                                               false /* is_newidmap */ )
+                                   == false) {
                                        return false;
                                }
                        }
@@ -604,12 +606,13 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                char *i_id = optarg;
                                char *o_id = cmdlineSplitStrByColon(i_id);
                                char *cnt = cmdlineSplitStrByColon(o_id);
-                               size_t count = (cnt == NULL
-                                               || strlen(cnt) == 0) ? 1U : (size_t) strtoull(cnt,
-                                                                                             NULL,
-                                                                                             0);
+                               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 */ ,
-                                               true /* is_newidmap */ ) == false) {
+                                               true /* is_newidmap */ )
+                                   == false) {
                                        return false;
                                }
                        }
@@ -618,12 +621,13 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                char *i_id = optarg;
                                char *o_id = cmdlineSplitStrByColon(i_id);
                                char *cnt = cmdlineSplitStrByColon(o_id);
-                               size_t count = (cnt == NULL
-                                               || strlen(cnt) == 0) ? 1U : (size_t) strtoull(cnt,
-                                                                                             NULL,
-                                                                                             0);
+                               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 */ ,
-                                               true /* is_newidmap */ ) == false) {
+                                               true /* is_newidmap */ )
+                                   == false) {
                                        return false;
                                }
                        }
index cf7191b..cdbdd38 100644 (file)
--- a/common.h
+++ b/common.h
@@ -47,10 +47,10 @@ static void __attribute__ ((unused)) __clang_cleanup_func(void (^*dfunc) (void))
 #define defer void (^_STRMERGE(__defer_f_, __COUNTER__))(void) __attribute__((cleanup(__clang_cleanup_func))) __attribute__((unused)) = ^
 #else
 #define __block
-#define _DEFER(a, count) \
-    auto void _STRMERGE(__defer_f_, count)(void *_defer_arg __attribute__((unused))); \
+#define _DEFER(a, count)                                                                                               \
+    auto void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused)));                                  \
     int _STRMERGE(__defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) __attribute__((unused)); \
-    void _STRMERGE(__defer_f_, count)(void *_defer_arg __attribute__((unused)))
+    void _STRMERGE(__defer_f_, count)(void_defer_arg __attribute__((unused)))
 #define defer _DEFER(a, __COUNTER__)
 #endif
 #endif
@@ -61,7 +61,8 @@ struct pids_t {
        char remote_txt[64];
        struct sockaddr_in6 remote_addr;
        int pid_syscall_fd;
-        TAILQ_ENTRY(pids_t) pointers;
+        TAILQ_ENTRY(pids_t)
+        pointers;
 };
 
 struct mounts_t {
@@ -75,7 +76,8 @@ struct mounts_t {
        bool isDir;
        bool isSymlink;
        bool mandatory;
-        TAILQ_ENTRY(mounts_t) pointers;
+        TAILQ_ENTRY(mounts_t)
+        pointers;
 };
 
 struct idmap_t {
@@ -83,12 +85,14 @@ struct idmap_t {
        uid_t outside_id;
        size_t count;
        bool is_newidmap;
-        TAILQ_ENTRY(idmap_t) pointers;
+        TAILQ_ENTRY(idmap_t)
+        pointers;
 };
 
 struct ints_t {
        int val;
-        TAILQ_ENTRY(ints_t) pointers;
+        TAILQ_ENTRY(ints_t)
+        pointers;
 };
 
 enum ns_mode_t {
@@ -100,7 +104,8 @@ enum ns_mode_t {
 
 struct charptr_t {
        char *val;
-        TAILQ_ENTRY(charptr_t) pointers;
+        TAILQ_ENTRY(charptr_t)
+        pointers;
 };
 
 enum llevel_t {
@@ -167,13 +172,20 @@ struct nsjconf_t {
        char *kafel_string;
        uid_t orig_euid;
        long num_cpus;
-        TAILQ_HEAD(udmaplist, idmap_t) uids;
-        TAILQ_HEAD(gdmaplist, idmap_t) gids;
-        TAILQ_HEAD(envlist, charptr_t) envs;
-        TAILQ_HEAD(pidslist, pids_t) pids;
-        TAILQ_HEAD(mountptslist, mounts_t) mountpts;
-        TAILQ_HEAD(fdslistt, ints_t) open_fds;
-        TAILQ_HEAD(capslistt, ints_t) caps;
+        TAILQ_HEAD(udmaplist, idmap_t)
+        uids;
+        TAILQ_HEAD(gdmaplist, idmap_t)
+        gids;
+        TAILQ_HEAD(envlist, charptr_t)
+        envs;
+        TAILQ_HEAD(pidslist, pids_t)
+        pids;
+        TAILQ_HEAD(mountptslist, mounts_t)
+        mountpts;
+        TAILQ_HEAD(fdslistt, ints_t)
+        open_fds;
+        TAILQ_HEAD(capslistt, ints_t)
+        caps;
 };
 
 #endif                         /* NS_COMMON_H */
diff --git a/config.c b/config.c
deleted file mode 100644 (file)
index b899c14..0000000
--- a/config.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-
-   nsjail - config parsing
-   -----------------------------------------
-
-   Copyright 2017 Google Inc. All Rights Reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-*/
-
-#include "common.h"
-
-#include <stdio.h>
-#include <sys/mount.h>
-#include <sys/personality.h>
-
-#include "caps.h"
-#include "config.h"
-#include "log.h"
-#include "mount.h"
-#include "user.h"
-#include "util.h"
-
-#if !defined(NSJAIL_WITH_PROTOBUF)
-bool configParse(struct nsjconf_t * nsjconf UNUSED, const char *file UNUSED)
-{
-       LOG_W("nsjail was not compiled with the protobuf-c library");
-       return false;
-}
-#else                          /* !defined(NSJAIL_WITH_PROTOBUF) */
-
-#include "config.pb-c.h"
-#include "protobuf-c-text.h"
-
-static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig * njc)
-{
-       switch (njc->mode) {
-       case NSJAIL__MODE__LISTEN:
-               nsjconf->mode = MODE_LISTEN_TCP;
-               break;
-       case NSJAIL__MODE__ONCE:
-               nsjconf->mode = MODE_STANDALONE_ONCE;
-               break;
-       case NSJAIL__MODE__RERUN:
-               nsjconf->mode = MODE_STANDALONE_RERUN;
-               break;
-       case NSJAIL__MODE__EXECVE:
-               nsjconf->mode = MODE_STANDALONE_EXECVE;
-               break;
-       default:
-               LOG_E("Uknown running mode: %d", njc->mode);
-               return false;
-       }
-       nsjconf->chroot = utilStrDup(njc->chroot_dir);
-       nsjconf->is_root_rw = njc->is_root_rw;
-       nsjconf->hostname = utilStrDup(njc->hostname);
-       nsjconf->cwd = utilStrDup(njc->cwd);
-       nsjconf->port = njc->port;
-       nsjconf->bindhost = utilStrDup(njc->bindhost);
-       nsjconf->max_conns_per_ip = njc->max_conns_per_ip;
-       nsjconf->tlimit = njc->time_limit;
-       nsjconf->max_cpus = njc->max_cpus;
-       nsjconf->daemonize = njc->daemon;
-
-       if (njc->has_log_fd) {
-               nsjconf->log_fd = njc->log_fd;
-       }
-       nsjconf->logfile = utilStrDup(njc->log_file);
-       if (njc->has_log_level) {
-               switch (njc->log_level) {
-               case NSJAIL__LOG_LEVEL__DEBUG:
-                       nsjconf->loglevel = DEBUG;
-                       break;
-               case NSJAIL__LOG_LEVEL__INFO:
-                       nsjconf->loglevel = INFO;
-                       break;
-               case NSJAIL__LOG_LEVEL__WARNING:
-                       nsjconf->loglevel = WARNING;
-                       break;
-               case NSJAIL__LOG_LEVEL__ERROR:
-                       nsjconf->loglevel = ERROR;
-                       break;
-               case NSJAIL__LOG_LEVEL__FATAL:
-                       nsjconf->loglevel = FATAL;
-                       break;
-               default:
-                       LOG_E("Unknown log_level: %d", njc->log_level);
-                       return false;
-               }
-       }
-
-       if (njc->has_log_fd || njc->log_file || njc->has_log_level) {
-               if (logInitLogFile(nsjconf) == false) {
-                       return false;
-               }
-       }
-
-       nsjconf->keep_env = njc->keep_env;
-       for (size_t i = 0; i < njc->n_envar; i++) {
-               struct charptr_t *p = utilMalloc(sizeof(struct charptr_t));
-               p->val = utilStrDup(njc->envar[i]);
-               TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
-       }
-
-       nsjconf->keep_caps = njc->keep_caps;
-       for (size_t i = 0; i < njc->n_cap; i++) {
-               struct ints_t *f = utilMalloc(sizeof(struct ints_t));
-               f->val = capsNameToVal(njc->cap[i]);
-               if (f->val == -1) {
-                       return false;
-               }
-               TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
-       }
-
-       nsjconf->is_silent = njc->silent;
-       nsjconf->skip_setsid = njc->skip_setsid;
-
-       for (size_t i = 0; i < njc->n_pass_fd; i++) {
-               struct ints_t *f = utilMalloc(sizeof(struct ints_t));
-               f->val = njc->pass_fd[i];
-               TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
-       }
-
-       nsjconf->disable_no_new_privs = njc->disable_no_new_privs;
-
-       nsjconf->rl_as = njc->rlimit_as * 1024ULL * 1024ULL;
-       nsjconf->rl_core = njc->rlimit_core * 1024ULL * 1024ULL;
-       nsjconf->rl_cpu = njc->rlimit_cpu;
-       nsjconf->rl_fsize = njc->rlimit_fsize * 1024ULL * 1024ULL;
-       nsjconf->rl_nofile = njc->rlimit_nofile;
-       if (njc->has_rlimit_nproc) {
-               nsjconf->rl_nproc = njc->rlimit_nproc;
-       }
-       if (njc->has_rlimit_stack) {
-               nsjconf->rl_stack = njc->rlimit_stack * 1024ULL * 1024ULL;
-       }
-
-       if (njc->persona_addr_compat_layout) {
-               nsjconf->personality |= ADDR_COMPAT_LAYOUT;
-       }
-       if (njc->persona_mmap_page_zero) {
-               nsjconf->personality |= MMAP_PAGE_ZERO;
-       }
-       if (njc->persona_read_implies_exec) {
-               nsjconf->personality |= READ_IMPLIES_EXEC;
-       }
-       if (njc->persona_addr_limit_3gb) {
-               nsjconf->personality |= ADDR_LIMIT_3GB;
-       }
-       if (njc->persona_addr_no_randomize) {
-               nsjconf->personality |= ADDR_NO_RANDOMIZE;
-       }
-
-       nsjconf->clone_newnet = njc->clone_newnet;
-       nsjconf->clone_newuser = njc->clone_newuser;
-       nsjconf->clone_newns = njc->clone_newns;
-       nsjconf->clone_newpid = njc->clone_newpid;
-       nsjconf->clone_newipc = njc->clone_newipc;
-       nsjconf->clone_newuts = njc->clone_newuts;
-       nsjconf->clone_newcgroup = njc->clone_newcgroup;
-
-       for (size_t i = 0; i < njc->n_uidmap; i++) {
-               if (userParseId
-                   (nsjconf, njc->uidmap[i]->inside_id, njc->uidmap[i]->outside_id,
-                    njc->uidmap[i]->count, false /* is_gid */ ,
-                    njc->uidmap[i]->use_newidmap) == false) {
-                       return false;
-               }
-       }
-       for (size_t i = 0; i < njc->n_gidmap; i++) {
-               if (userParseId
-                   (nsjconf, njc->gidmap[i]->inside_id, njc->gidmap[i]->outside_id,
-                    njc->gidmap[i]->count, true /* is_gid */ ,
-                    njc->gidmap[i]->use_newidmap) == false) {
-                       return false;
-               }
-       }
-
-       nsjconf->mount_proc = njc->mount_proc;
-       for (size_t i = 0; i < njc->n_mount; i++) {
-               const char *src = njc->mount[i]->src;
-               const char *src_env = njc->mount[i]->prefix_src_env;
-               const char *dst = njc->mount[i]->dst;
-               const char *dst_env = njc->mount[i]->prefix_dst_env;
-               const char *fstype = njc->mount[i]->fstype;
-               const char *options = njc->mount[i]->options;
-
-               uintptr_t flags = (njc->mount[i]->rw == false) ? MS_RDONLY : 0;
-               flags |= njc->mount[i]->is_bind ? (MS_BIND | MS_REC) : 0;
-               bool mandatory = njc->mount[i]->mandatory;
-
-               const bool *isDir =
-                   (njc->mount[i]->has_is_dir) ? (const bool *)&njc->mount[i]->is_dir : NULL;
-
-               uint8_t *src_content = NULL;
-               size_t src_content_len = 0;
-               if (njc->mount[i]->has_src_content) {
-                       src_content = njc->mount[i]->src_content.data;
-                       src_content_len = njc->mount[i]->src_content.len;
-               }
-
-               if (mountAddMountPt
-                   (nsjconf, src, dst, fstype, options, flags, isDir, mandatory, src_env,
-                    dst_env, src_content, src_content_len, njc->mount[i]->is_symlink) == false) {
-                       LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
-                       return false;
-               }
-       }
-
-       if (njc->seccomp_policy_file) {
-               if ((nsjconf->kafel_file = fopen(njc->seccomp_policy_file, "rb")) == NULL) {
-                       PLOG_W("Couldn't open file with seccomp policy '%s'",
-                              njc->seccomp_policy_file);
-                       return false;
-               }
-       }
-       nsjconf->kafel_string = utilStrDup(njc->seccomp_string);
-
-       nsjconf->cgroup_mem_max = njc->cgroup_mem_max;
-       nsjconf->cgroup_mem_mount = utilStrDup(njc->cgroup_mem_mount);
-       nsjconf->cgroup_mem_parent = utilStrDup(njc->cgroup_mem_parent);
-
-       nsjconf->cgroup_pids_max = njc->cgroup_pids_max;
-       nsjconf->cgroup_pids_mount = utilStrDup(njc->cgroup_pids_mount);
-       nsjconf->cgroup_pids_parent = utilStrDup(njc->cgroup_pids_parent);
-
-       nsjconf->iface_no_lo = njc->iface_no_lo;
-       nsjconf->iface_vs = utilStrDup(njc->macvlan_iface);
-       nsjconf->iface_vs_ip = utilStrDup(njc->macvlan_vs_ip);
-       nsjconf->iface_vs_nm = utilStrDup(njc->macvlan_vs_nm);
-       nsjconf->iface_vs_gw = utilStrDup(njc->macvlan_vs_gw);
-
-       if (njc->exec_bin) {
-               char **argv = utilCalloc(sizeof(const char *) * (njc->exec_bin->n_arg + 2));
-               if (njc->exec_bin->arg0) {
-                       argv[0] = utilStrDup(njc->exec_bin->arg0);
-               } else {
-                       argv[0] = utilStrDup(njc->exec_bin->path);
-               }
-               for (size_t i = 0; i < njc->exec_bin->n_arg; i++) {
-                       argv[i + 1] = utilStrDup(njc->exec_bin->arg[i]);
-               }
-               argv[njc->exec_bin->n_arg + 1] = NULL;
-               nsjconf->exec_file = utilStrDup(njc->exec_bin->path);
-               nsjconf->argv = argv;
-       }
-
-       return true;
-}
-
-bool configParse(struct nsjconf_t * nsjconf, const char *file)
-{
-       LOG_I("Parsing configuration from '%s'", file);
-
-       FILE *f = fopen(file, "rb");
-       if (f == NULL) {
-               PLOG_W("Couldn't open '%s' for reading", file);
-               return false;
-       }
-
-       ProtobufCTextError error;
-       Nsjail__NsJailConfig *njc =
-           (Nsjail__NsJailConfig *) protobuf_c_text_from_file(&nsjail__ns_jail_config__descriptor,
-                                                              f, &error, NULL);
-       if (njc == NULL) {
-               LOG_W("Couldn't parse config from '%s': %s", file, error.error_txt);
-               fclose(f);
-               return false;
-       }
-
-       bool ret = configParseInternal(nsjconf, njc);
-
-       char *config_str = protobuf_c_text_to_string((ProtobufCMessage *) njc, NULL);
-       if (config_str) {
-               LOG_D("Parsed config:\n%s", config_str);
-               free(config_str);
-       }
-
-       fclose(f);
-       return ret;
-}
-#endif                         /* !defined(NSJAIL_WITH_PROTOBUF) */
diff --git a/config.cc b/config.cc
new file mode 100644 (file)
index 0000000..8110320
--- /dev/null
+++ b/config.cc
@@ -0,0 +1,326 @@
+/*
+
+   nsjail - config parsing
+   -----------------------------------------
+
+   Copyright 2017 Google Inc. All Rights Reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+extern "C" {
+#include "common.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/personality.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "caps.h"
+#include "config.h"
+#include "log.h"
+#include "mount.h"
+#include "user.h"
+#include "util.h"
+}
+
+#include <fstream>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/text_format.h>
+#include <string>
+
+#include "config.pb.h"
+
+static bool configParseInternal(struct nsjconf_t* nsjconf,
+    const nsjail::NsJailConfig& njc)
+{
+    switch (njc.mode()) {
+    case nsjail::Mode::LISTEN:
+        nsjconf->mode = MODE_LISTEN_TCP;
+        break;
+    case nsjail::Mode::ONCE:
+        nsjconf->mode = MODE_STANDALONE_ONCE;
+        break;
+    case nsjail::Mode::RERUN:
+        nsjconf->mode = MODE_STANDALONE_RERUN;
+        break;
+    case nsjail::Mode::EXECVE:
+        nsjconf->mode = MODE_STANDALONE_EXECVE;
+        break;
+    default:
+        LOG_E("Uknown running mode: %d", njc.mode());
+        return false;
+    }
+    nsjconf->chroot = njc.has_chroot_dir() ? utilStrDup(njc.chroot_dir().c_str()) : NULL;
+    nsjconf->is_root_rw = njc.is_root_rw();
+    nsjconf->hostname = njc.has_hostname() ? utilStrDup(njc.hostname().c_str()) : NULL;
+    nsjconf->cwd = njc.has_cwd() ? utilStrDup(njc.cwd().c_str()) : NULL;
+    nsjconf->port = njc.port();
+    nsjconf->bindhost = njc.has_bindhost() ? utilStrDup(njc.bindhost().c_str()) : NULL;
+    nsjconf->max_conns_per_ip = njc.max_conns_per_ip();
+    nsjconf->tlimit = njc.time_limit();
+    nsjconf->max_cpus = njc.max_cpus();
+    nsjconf->daemonize = njc.daemon();
+
+    if (njc.has_log_fd()) {
+        nsjconf->log_fd = njc.log_fd();
+    }
+    nsjconf->logfile = njc.has_log_file() ? utilStrDup(njc.log_file().c_str()) : NULL;
+    if (njc.has_log_level()) {
+        switch (njc.log_level()) {
+        case nsjail::LogLevel::DEBUG:
+            nsjconf->loglevel = DEBUG;
+            break;
+        case nsjail::LogLevel::INFO:
+            nsjconf->loglevel = INFO;
+            break;
+        case nsjail::LogLevel::WARNING:
+            nsjconf->loglevel = WARNING;
+            break;
+        case nsjail::LogLevel::ERROR:
+            nsjconf->loglevel = ERROR;
+            break;
+        case nsjail::LogLevel::FATAL:
+            nsjconf->loglevel = FATAL;
+            break;
+        default:
+            LOG_E("Unknown log_level: %d", njc.log_level());
+            return false;
+        }
+    }
+
+    if (njc.has_log_fd() || njc.has_log_file() || njc.has_log_level()) {
+        if (logInitLogFile(nsjconf) == false) {
+            return false;
+        }
+    }
+
+    nsjconf->keep_env = njc.keep_env();
+    for (ssize_t i = 0; i < njc.envar_size(); i++) {
+        struct charptr_t* p = reinterpret_cast<charptr_t*>(utilMalloc(sizeof(struct charptr_t)));
+        p->val = utilStrDup(njc.envar(i).c_str());
+        TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
+    }
+
+    nsjconf->keep_caps = njc.keep_caps();
+    for (ssize_t i = 0; i < njc.cap_size(); i++) {
+        struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
+        f->val = capsNameToVal(njc.cap(i).c_str());
+        if (f->val == -1) {
+            return false;
+        }
+        TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
+    }
+
+    nsjconf->is_silent = njc.silent();
+    nsjconf->skip_setsid = njc.skip_setsid();
+
+    for (ssize_t i = 0; i < njc.pass_fd_size(); i++) {
+        struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
+        f->val = njc.pass_fd(i);
+        TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
+    }
+
+    nsjconf->disable_no_new_privs = njc.disable_no_new_privs();
+
+    nsjconf->rl_as = njc.rlimit_as() * 1024ULL * 1024ULL;
+    nsjconf->rl_core = njc.rlimit_core() * 1024ULL * 1024ULL;
+    nsjconf->rl_cpu = njc.rlimit_cpu();
+    nsjconf->rl_fsize = njc.rlimit_fsize() * 1024ULL * 1024ULL;
+    nsjconf->rl_nofile = njc.rlimit_nofile();
+    if (njc.has_rlimit_nproc()) {
+        nsjconf->rl_nproc = njc.rlimit_nproc();
+    }
+    if (njc.has_rlimit_stack()) {
+        nsjconf->rl_stack = njc.rlimit_stack() * 1024ULL * 1024ULL;
+    }
+
+    if (njc.persona_addr_compat_layout()) {
+        nsjconf->personality |= ADDR_COMPAT_LAYOUT;
+    }
+    if (njc.persona_mmap_page_zero()) {
+        nsjconf->personality |= MMAP_PAGE_ZERO;
+    }
+    if (njc.persona_read_implies_exec()) {
+        nsjconf->personality |= READ_IMPLIES_EXEC;
+    }
+    if (njc.persona_addr_limit_3gb()) {
+        nsjconf->personality |= ADDR_LIMIT_3GB;
+    }
+    if (njc.persona_addr_no_randomize()) {
+        nsjconf->personality |= ADDR_NO_RANDOMIZE;
+    }
+
+    nsjconf->clone_newnet = njc.clone_newnet();
+    nsjconf->clone_newuser = njc.clone_newuser();
+    nsjconf->clone_newns = njc.clone_newns();
+    nsjconf->clone_newpid = njc.clone_newpid();
+    nsjconf->clone_newipc = njc.clone_newipc();
+    nsjconf->clone_newuts = njc.clone_newuts();
+    nsjconf->clone_newcgroup = njc.clone_newcgroup();
+
+    for (ssize_t i = 0; i < njc.uidmap_size(); i++) {
+        if (userParseId(
+                nsjconf,
+                njc.uidmap(i).has_inside_id() ? njc.uidmap(i).inside_id().c_str()
+                                              : NULL,
+                njc.uidmap(i).has_outside_id() ? njc.uidmap(i).outside_id().c_str()
+                                               : NULL,
+                njc.uidmap(i).count(), false /* is_gid */,
+                njc.uidmap(i).use_newidmap())
+            == false) {
+            return false;
+        }
+    }
+    for (ssize_t i = 0; i < njc.gidmap_size(); i++) {
+        if (userParseId(
+                nsjconf,
+                njc.gidmap(i).has_inside_id() ? njc.gidmap(i).inside_id().c_str()
+                                              : NULL,
+                njc.gidmap(i).has_outside_id() ? njc.gidmap(i).outside_id().c_str()
+                                               : NULL,
+                njc.gidmap(i).count(), true /* is_gid */,
+                njc.gidmap(i).use_newidmap())
+            == false) {
+            return false;
+        }
+    }
+
+    nsjconf->mount_proc = njc.mount_proc();
+    for (ssize_t i = 0; i < njc.mount_size(); i++) {
+        const char* src = (njc.mount(i).has_src()) ? njc.mount(i).src().c_str() : NULL;
+        const char* src_env = (njc.mount(i).has_prefix_src_env()) ? njc.mount(i).prefix_src_env().c_str() : NULL;
+        const char* dst = (njc.mount(i).has_dst()) ? njc.mount(i).dst().c_str() : NULL;
+        const char* dst_env = (njc.mount(i).has_prefix_dst_env()) ? njc.mount(i).prefix_dst_env().c_str() : NULL;
+        const char* fstype = (njc.mount(i).has_fstype()) ? njc.mount(i).fstype().c_str() : NULL;
+        const char* options = (njc.mount(i).has_options()) ? njc.mount(i).options().c_str() : NULL;
+
+        uintptr_t flags = (njc.mount(i).rw() == false) ? MS_RDONLY : 0;
+        flags |= njc.mount(i).is_bind() ? (MS_BIND | MS_REC) : 0;
+        bool mandatory = njc.mount(i).mandatory();
+
+        const bool isDir = (njc.mount(i).has_is_dir() && njc.mount(i).is_dir()) ? true : false;
+        const bool* isDirPtr = (njc.mount(i).has_is_dir()) ? &isDir : NULL;
+
+        const char* src_content = NULL;
+        size_t src_content_len = 0;
+        if (njc.mount(i).has_src_content()) {
+            src_content = njc.mount(i).src_content().data();
+            src_content_len = njc.mount(i).src_content().size();
+        }
+
+        if (mountAddMountPt(nsjconf, src, dst, fstype, options, flags, isDirPtr,
+                mandatory, src_env, dst_env, src_content,
+                src_content_len, njc.mount(i).is_symlink())
+            == false) {
+            LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
+            return false;
+        }
+    }
+
+    if (njc.has_seccomp_policy_file()) {
+        if ((nsjconf->kafel_file = fopen(njc.seccomp_policy_file().c_str(), "rb")) == NULL) {
+            PLOG_W("Couldn't open file with seccomp policy '%s'",
+                njc.seccomp_policy_file().c_str());
+            return false;
+        }
+    }
+
+    std::string kafel_string;
+    for (ssize_t i = 0; i < njc.seccomp_string().size(); i++) {
+        kafel_string += njc.seccomp_string(i);
+    }
+    nsjconf->kafel_string = njc.seccomp_string().size() > 0
+        ? utilStrDup(kafel_string.c_str())
+        : NULL;
+
+    nsjconf->cgroup_mem_max = njc.cgroup_mem_max();
+    nsjconf->cgroup_mem_mount = njc.has_cgroup_mem_mount()
+        ? utilStrDup(njc.cgroup_mem_mount().c_str())
+        : NULL;
+    nsjconf->cgroup_mem_parent = njc.has_cgroup_mem_parent()
+        ? utilStrDup(njc.cgroup_mem_parent().c_str())
+        : NULL;
+
+    nsjconf->cgroup_pids_max = njc.cgroup_pids_max();
+    nsjconf->cgroup_pids_mount = njc.has_cgroup_pids_mount()
+        ? utilStrDup(njc.cgroup_pids_mount().c_str())
+        : NULL;
+    nsjconf->cgroup_pids_parent = njc.has_cgroup_pids_parent()
+        ? utilStrDup(njc.cgroup_pids_parent().c_str())
+        : NULL;
+
+    nsjconf->iface_no_lo = njc.iface_no_lo();
+    nsjconf->iface_vs = njc.has_macvlan_iface() ? utilStrDup(njc.macvlan_iface().c_str()) : NULL;
+    nsjconf->iface_vs_ip = njc.has_macvlan_vs_ip() ? utilStrDup(njc.macvlan_vs_ip().c_str()) : NULL;
+    nsjconf->iface_vs_nm = njc.has_macvlan_vs_nm() ? utilStrDup(njc.macvlan_vs_nm().c_str()) : NULL;
+    nsjconf->iface_vs_gw = njc.has_macvlan_vs_gw() ? utilStrDup(njc.macvlan_vs_gw().c_str()) : NULL;
+
+    if (njc.has_exec_bin()) {
+        char** argv = reinterpret_cast<char**>(utilCalloc(sizeof(const char*) * (njc.exec_bin().arg().size() + 2)));
+        if (njc.exec_bin().has_arg0()) {
+            argv[0] = utilStrDup(njc.exec_bin().arg0().c_str());
+        } else {
+            argv[0] = utilStrDup(njc.exec_bin().path().c_str());
+        }
+        for (ssize_t i = 0; i < njc.exec_bin().arg().size(); i++) {
+            argv[i + 1] = utilStrDup(njc.exec_bin().arg(i).c_str());
+        }
+        argv[njc.exec_bin().arg().size() + 1] = NULL;
+        nsjconf->exec_file = njc.exec_bin().has_path()
+            ? utilStrDup(njc.exec_bin().path().c_str())
+            : NULL;
+        nsjconf->argv = argv;
+    }
+
+    return true;
+}
+
+static void LogHandler(google::protobuf::LogLevel level, const char* filename, int line, const std::string& message)
+{
+    LOG_W("config.cc: '%s'", message.c_str());
+}
+
+extern "C" bool configParse(struct nsjconf_t* nsjconf, const char* file)
+{
+    LOG_I("Parsing configuration from '%s'", file);
+
+    int fd = open(file, O_RDONLY);
+    if (fd == -1) {
+        PLOG_W("Couldn't open config file '%s'", file);
+        return false;
+    }
+
+    SetLogHandler(LogHandler);
+    google::protobuf::io::FileInputStream input(fd);
+    input.SetCloseOnDelete(true);
+
+    nsjail::NsJailConfig nsc;
+
+    auto parser = google::protobuf::TextFormat::Parser();
+
+    if (!parser.Parse(&input, &nsc)) {
+        LOG_W("Couldn't parse file '%s' from Text into ProtoBuf", file);
+        return false;
+    }
+    if (!configParseInternal(nsjconf, nsc)) {
+        LOG_W("Couldn't parse the ProtoBuf");
+        return false;
+    }
+    LOG_D("Parsed config:\n'%s'", nsc.DebugString().c_str());
+
+    return true;
+}
index 1dfd98b..4b00bc3 100644 (file)
--- a/config.h
+++ b/config.h
 #ifndef NS_CONFIG_H
 #define NS_CONFIG_H
 
-#include "common.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-bool configParse(struct nsjconf_t *nsjconf, const char *file);
+#include "common.h"
+       bool configParse(struct nsjconf_t *nsjconf, const char *file);
 
+#ifdef __cplusplus
+}                              // extern "C"
+#endif
 #endif                         /*  NS_CONFIG_H */
index 7010d35..42a9485 100644 (file)
@@ -19,12 +19,12 @@ enum LogLevel {
 message IdMap
 {
     /* Empty string means "current uid/gid" */
-    required string inside_id = 1 [ default = "" ];
-    required string outside_id = 2 [ default = "" ];
+    optional string inside_id = 1 [ default = "" ];
+    optional string outside_id = 2 [ default = "" ];
     /* See 'man user_namespaces' for the meaning of count */
-    required uint32 count = 3 [ default = 1 ];
+    optional uint32 count = 3 [ default = 1 ];
     /* Does this map use /usr/bin/new[u|g]idmap binary? */
-    required bool use_newidmap = 4 [ default = false ];
+    optional bool use_newidmap = 4 [ default = false ];
 }
 message MountPt
 {
@@ -41,18 +41,18 @@ message MountPt
     /* Can be empty for mount --bind mounts */
     optional string fstype = 6 [ default = "" ];
     /* E.g. size=5000000 for 'tmpfs' */
-    required string options = 7 [ default = "" ];
+    optional string options = 7 [ default = "" ];
     /* Is it 'mount --bind src dst' type of mount */
-    required bool is_bind = 8 [ default = false ];
+    optional bool is_bind = 8 [ default = false ];
     /* It it R/W mount */
-    required bool rw = 9 [ default = false ];
+    optional bool rw = 9 [ default = false ];
     /* Is it directory? If not specified an internal
        heuristics will be used to determine that */
     optional bool is_dir = 10;
     /* Should the sandboxing fail if we cannot mount this resource? */
-    required bool mandatory = 11 [ default = true ];
+    optional bool mandatory = 11 [ default = true ];
        /* Is it a symlink (instead of real mount point)? */
-       required bool is_symlink = 12 [ default = false ];
+       optional bool is_symlink = 12 [ default = false ];
 }
 message Exe
 {
@@ -67,32 +67,32 @@ message NsJailConfig
 {
     /* Optional name and description for this config */
     optional string name = 1 [ default = "" ];
-    optional string description = 2 [ default = "" ];
+    repeated string description = 2;
 
     /* Execution mode: see 'msg Mode' description for more */
-    required Mode mode = 3 [ default = ONCE ];
+    optional Mode mode = 3 [ default = ONCE ];
     /* Equivalent to a bind mount with dst='/' */
     optional string chroot_dir = 4;
     /* Applies both to the chroot_dir and to /proc mounts */
-    required bool is_root_rw = 5 [ default = false ];
+    optional bool is_root_rw = 5 [ default = false ];
     /* Hostname inside jail */
-    required string hostname = 8 [ default = "NSJAIL" ];
+    optional string hostname = 8 [ default = "NSJAIL" ];
     /* Initial current working directory for the binary */
-    required string cwd = 9 [ default = "/" ];
+    optional string cwd = 9 [ default = "/" ];
 
     /* TCP port to listen to. Valid with mode=LISTEN only */
-    required uint32 port = 10 [ default = 0 ];
+    optional uint32 port = 10 [ default = 0 ];
     /* Host to bind to for mode=LISTEN. Must be in IPv6 format */
-    required string bindhost = 11 [ default = "::" ];
+    optional string bindhost = 11 [ default = "::" ];
     /* For mode=LISTEN, maximum number of connections from a single IP */
-    required uint32 max_conns_per_ip = 12 [ default = 0 ];
+    optional uint32 max_conns_per_ip = 12 [ default = 0 ];
 
     /* Wall-time time limit for commands */
-    required uint32 time_limit = 13 [ default = 600 ];
+    optional uint32 time_limit = 13 [ default = 600 ];
     /* Should nsjail go into background? */
-    required bool daemon = 14 [ default = false ];
+    optional bool daemon = 14 [ default = false ];
     /* Maximum number of CPUs to use: 0 - no limit */
-    required uint32 max_cpus = 15;
+    optional uint32 max_cpus = 15 [ default = 0 ];
 
     /* FD to log to. */
     optional int32 log_fd = 16;
@@ -104,52 +104,52 @@ message NsJailConfig
 
     /* Should the current environment variables be kept
        when executing the binary */
-    required bool keep_env = 19 [ default = false ];
+    optional bool keep_env = 19 [ default = false ];
     /* EnvVars to be set before executing binaries */
     repeated string envar = 20;
 
     /* Should capabilities be preserved or dropped */
-    required bool keep_caps = 21 [ default = false ];
+    optional bool keep_caps = 21 [ default = false ];
     /* Which capabilities should be preserved if keep_caps == false.
        Format: "CAP_SYS_PTRACE" */
        repeated string cap = 63;
     /* Should nsjail close FD=0,1,2 before executing the process */
-    required bool silent = 22 [ default = false ];
+    optional bool silent = 22 [ default = false ];
     /* Should the child process have control over terminal?
        Can be useful to allow /bin/sh to provide
        job control / signals */
-    required bool skip_setsid = 23 [ default = false ];
+    optional bool skip_setsid = 23 [ default = false ];
     /* Which FDs should be passed to the newly executed process
        By default only FD=0,1,2 are passed */
     repeated int32 pass_fd = 24;
     /* Setting it to true will allow to have set-uid binaries
        inside the jail */
-    required bool disable_no_new_privs = 25 [ default = false ];
+    optional bool disable_no_new_privs = 25 [ default = false ];
 
-    required uint64 rlimit_as = 26 [ default = 512 ]; /* In MiB */
-    required uint64 rlimit_core = 27 [ default = 0 ]; /* In MiB */
-    required uint64 rlimit_cpu = 28 [ default = 600 ]; /* In seconds */
-    required uint64 rlimit_fsize = 29 [ default = 1 ]; /* In MiB */
-    required uint64 rlimit_nofile = 30 [ default = 32 ];
+    optional uint64 rlimit_as = 26 [ default = 512 ]; /* In MiB */
+    optional uint64 rlimit_core = 27 [ default = 0 ]; /* In MiB */
+    optional uint64 rlimit_cpu = 28 [ default = 600 ]; /* In seconds */
+    optional uint64 rlimit_fsize = 29 [ default = 1 ]; /* In MiB */
+    optional uint64 rlimit_nofile = 30 [ default = 32 ];
     optional uint64 rlimit_nproc = 31; /* This is system-wide: tricky to use */
     optional uint64 rlimit_stack = 32; /* In MiB */
 
     /* See 'man personality' for more */
-    required bool persona_addr_compat_layout = 33 [ default = false ];
-    required bool persona_mmap_page_zero = 34 [ default = false ];
-    required bool persona_read_implies_exec = 35 [ default = false ];
-    required bool persona_addr_limit_3gb = 36 [ default = false ];
-    required bool persona_addr_no_randomize = 37 [ default = false ];
+    optional bool persona_addr_compat_layout = 33 [ default = false ];
+    optional bool persona_mmap_page_zero = 34 [ default = false ];
+    optional bool persona_read_implies_exec = 35 [ default = false ];
+    optional bool persona_addr_limit_3gb = 36 [ default = false ];
+    optional bool persona_addr_no_randomize = 37 [ default = false ];
 
     /* Which name-spaces should be used? */
-    required bool clone_newnet = 38 [ default = true ];
-    required bool clone_newuser = 39 [ default = true ];
-    required bool clone_newns = 40 [ default = true ];
-    required bool clone_newpid = 41 [ default = true ];
-    required bool clone_newipc = 42 [ default = true ];
-    required bool clone_newuts = 43 [ default = true ];
+    optional bool clone_newnet = 38 [ default = true ];
+    optional bool clone_newuser = 39 [ default = true ];
+    optional bool clone_newns = 40 [ default = true ];
+    optional bool clone_newpid = 41 [ default = true ];
+    optional bool clone_newipc = 42 [ default = true ];
+    optional bool clone_newuts = 43 [ default = true ];
     /* It's only supported in newer kernels, hence disabled by default */
-    required bool clone_newcgroup = 44 [ default = false ];
+    optional bool clone_newcgroup = 44 [ default = false ];
 
     /* Mappings for UIDs and GIDs. See the description for 'msg IdMap'
        for more */
@@ -158,7 +158,7 @@ message NsJailConfig
 
     /* Should /proc be mounted (R/O)? This can also be added in the 'mount'
        section below */
-    required bool mount_proc = 47 [ default = false ];
+    optional bool mount_proc = 47 [ default = false ];
     /* Mount points inside the jail. See the description for 'msg MountPt'
        for more */
     repeated MountPt mount = 48;
@@ -166,30 +166,30 @@ message NsJailConfig
     /* Kafel seccomp-bpf policy file or a string:
        Homepage of the project: https://github.com/google/kafel */
     optional string seccomp_policy_file = 49;
-    optional string seccomp_string = 50;
+    repeated string seccomp_string = 50;
 
     /* If > 0, maximum cumulative size of RAM used inside any jail */
-    required uint64 cgroup_mem_max = 51 [ default = 0 ]; /* In MiB */
+    optional uint64 cgroup_mem_max = 51 [ default = 0 ]; /* In MiB */
     /* Mount point for cgroups-memory in your system */
-    required string cgroup_mem_mount = 52 [ default = "/sys/fs/cgroup/memory" ];
+    optional string cgroup_mem_mount = 52 [ default = "/sys/fs/cgroup/memory" ];
     /* Writeable directory (for the nsjail user) under cgroup_mem_mount */
-    required string cgroup_mem_parent = 53 [ default = "NSJAIL" ];
+    optional string cgroup_mem_parent = 53 [ default = "NSJAIL" ];
 
     /* If > 0, maximum number of PIDs (threads/processes) inside jail */
-    required uint64 cgroup_pids_max = 54 [ default = 0 ];
+    optional uint64 cgroup_pids_max = 54 [ default = 0 ];
     /* Mount point for cgroups-pids in your system */
-    required string cgroup_pids_mount = 55 [ default = "/sys/fs/cgroup/pids" ];
+    optional string cgroup_pids_mount = 55 [ default = "/sys/fs/cgroup/pids" ];
     /* Writeable directory (for the nsjail user) under cgroup_pids_mount */
-    required string cgroup_pids_parent = 56 [ default = "NSJAIL" ];
+    optional string cgroup_pids_parent = 56 [ default = "NSJAIL" ];
 
     /* Should the 'lo' interface be brought up (active) inside this jail? */
-    required bool iface_no_lo = 57 [ default = false ];
+    optional bool iface_no_lo = 57 [ default = false ];
 
     /* Parameters for the cloned MACVLAN interface inside jail */
     optional string macvlan_iface = 58; /* Interface to be cloned, eg 'eth0' */
-    required string macvlan_vs_ip = 59 [ default = "192.168.0.2" ];
-    required string macvlan_vs_nm = 60 [ default = "255.255.255.0" ];
-    required string macvlan_vs_gw = 61 [ default = "192.168.0.1" ];
+    optional string macvlan_vs_ip = 59 [ default = "192.168.0.2" ];
+    optional string macvlan_vs_nm = 60 [ default = "255.255.255.0" ];
+    optional string macvlan_vs_gw = 61 [ default = "192.168.0.1" ];
 
     /* Binary path (with arguments) to be executed. If not specified here, it
        can be specified with cmd-line as "-- /path/to/command arg1 arg2" */
index 4735ed6..e7162ff 100644 (file)
@@ -1,21 +1,15 @@
 name: "apache-with-cloned-net"
-description: "
-Tested under Ubuntu 17.04. Other Linux distros might use different
-locations for the Apache's HTTPD configuration files and system
-libraries.
-
-On the basis of (GitHub's) @farconada work in:
-https://github.com/google/nsjail/issues/31
-
-Run as: sudo ./nsjail --config configs/apache.cfg
-"
+description: "Tested under Ubuntu 17.04. Other Linux distros might "
+description: "use different locations for the Apache's HTTPD configuration "
+description: "files and system libraries"
+description: "Run as: sudo ./nsjail --config configs/apache.cfg"
 
 mode: ONCE
 hostname: "APACHE-NSJ"
 
 rlimit_as: 1024
 rlimit_fsize: 1024
-rlimit_cpu: -1
+rlimit_cpu: 18446744073709551615
 rlimit_nofile: 64
 
 time_limit: 0
@@ -123,16 +117,15 @@ mount {
        is_bind: true
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "seccomp_string: "
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
 
 macvlan_iface: "enp0s31f6"
 macvlan_vs_ip: "192.168.10.223"
index 74af795..d647a04 100644 (file)
@@ -1,13 +1,11 @@
 name: "bash-with-fake-geteuid"
-description:
-"An example/demo policy which allows to execute /bin/bash and other commands in
-a fairly restricted jail containing only some directories from the main
-system, and with blocked __NR_syslog syscall. Also, __NR_geteuid returns -1337
-value, which /usr/bin/id will show as euid=4294965959, and ptrace is blocked
-but returns success, hence strange behavior of the strace command.
-
-This is an example/demo policy, hence it repeats many default values from the
-https://github.com/google/nsjail/blob/master/config.proto PB schema"
+description: "An example/demo policy which allows to execute /bin/bash and other commands in "
+description: "a fairly restricted jail containing only some directories from the main "
+description: "system, and with blocked __NR_syslog syscall. Also, __NR_geteuid returns -1337 "
+description: "value, which /usr/bin/id will show as euid=4294965959, and ptrace is blocked "
+description: "but returns success, hence strange behavior of the strace command. "
+description: "This is an example/demo policy, hence it repeats many default values from the "
+description: "https://github.com/google/nsjail/blob/master/config.proto PB schema "
 
 mode: ONCE
 hostname: "JAILED-BASH"
@@ -169,14 +167,13 @@ mount {
        mandatory: false
 }
 
-seccomp_string: "
-       POLICY example {
-               ERRNO(1337) { geteuid },
-               KILL { syslog },
-               ERRNO(0) { ptrace }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "POLICY example {              "
+seccomp_string:        "       ERRNO(1337) { geteuid },   "
+seccomp_string: "                              "
+seccomp_string: "              KILL { syslog },       "
+seccomp_string:        "       ERRNO(0) { ptrace }        "
+seccomp_string:        "}                             "
+seccomp_string:        "USE example DEFAULT ALLOW     "
 
 exec_bin {
        path: "/bin/bash"
index 1414cb4..9a17f33 100644 (file)
@@ -1,26 +1,25 @@
 name: "chrome-with-net"
-description: "
-Don't use for anything serious - this is just a demo policy. See notes
-at the end of this description for more.
 
-This policy allows to run Chrome inside a jail. Access to networking is
-permitted with this setup (clone_newnet: false).
-
-The only permitted home directory is $HOME/.mozilla and $HOME/Documents.
-The rest of available on the FS files/dires are libs and X-related files/dirs.
-
-Run as:
-
-./nsjail --config configs/chrome-with-net.cfg
-
-You can then go to https://uploadfiles.io/ and try to upload a file in order
-to see how your local directory (also, all system directories) look like.
-
-Note: Using this profile for anything serious is *A VERY BAD* idea. Chrome
-provides excellent FS&syscall sandbox for Linux, as this profile disables
-this sandboxing with --no-sandbox and substitutes Chrome's syscall/ns policy
-with more relaxed namespacing.
-"
+description: "Don't use for anything serious - this is just a demo policy. See notes"
+description: "at the end of this description for more."
+description: ""
+description: "This policy allows to run Chrome inside a jail. Access to networking is"
+description: "permitted with this setup (clone_newnet: false)."
+description: ""
+description: "The only permitted home directory is $HOME/.mozilla and $HOME/Documents."
+description: "The rest of available on the FS files/dires are libs and X-related files/dirs."
+description: ""
+description: "Run as:"
+description: ""
+description: "./nsjail --config configs/chrome-with-net.cfg"
+description: ""
+description: "You can then go to https://uploadfiles.io/ and try to upload a file in order"
+description: "to see how your local directory (also, all system directories) look like."
+description: ""
+description: "Note: Using this profile for anything serious is *A VERY BAD* idea. Chrome"
+description: "provides excellent FS&syscall sandbox for Linux, as this profile disables"
+description: "this sandboxing with --no-sandbox and substitutes Chrome's syscall/ns policy"
+description: "with more relaxed namespacing."
 
 mode: ONCE
 hostname: "CHROME"
@@ -166,16 +165,14 @@ mount {
        is_bind: true
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
 
 exec_bin {
         path: "/opt/google/chrome/google-chrome"
index ebe730c..39b774f 100644 (file)
@@ -1,26 +1,25 @@
 name: "firefox-with-cloned-net"
-description: "
-This policy allows to run firefox inside a jail on a separate eth interface.
-A separate networking context separates process from the global \"lo\", and
-from global abstract socket namespace.
 
-The only permitted home directory is $HOME/.mozilla and $HOME/Documents.
-The rest of available on the FS files/dires are libs and X-related files/dirs.
-
-As this needs to be run as root, you will have to set-up correct uid&gid
-mappings (here: 'jagger'), name of your local interface (here: 'enp0s31f6'),
-and correct IPv4 addresses.
-
-IPv6 should work out-of-the-box, given that your local IPv6 discovery is set
-up correctly.
-
-Run as:
-
-sudo ./nsjail --config configs/firefox-with-cloned-net.cfg
-
-You can then go to https://uploadfiles.io/ and try to upload a file in order
-to see how your local directory (also, all system directories) look like.
-"
+description: "This policy allows to run firefox inside a jail on a separate eth interface."
+description: "A separate networking context separates process from the global \"lo\", and"
+description: "from global abstract socket namespace."
+description: ""
+description: "The only permitted home directory is $HOME/.mozilla and $HOME/Documents."
+description: "The rest of available on the FS files/dires are libs and X-related files/dirs."
+description: ""
+description: "As this needs to be run as root, you will have to set-up correct uid&gid"
+description: "mappings (here: 'jagger'), name of your local interface (here: 'enp0s31f6'),"
+description: "and correct IPv4 addresses."
+description: ""
+description: "IPv6 should work out-of-the-box, given that your local IPv6 discovery is set"
+description: "up correctly."
+description: ""
+description: "Run as:"
+description: ""
+description: "sudo ./nsjail --config configs/firefox-with-cloned-net.cfg"
+description: ""
+description: "You can then go to https://uploadfiles.io/ and try to upload a file in order"
+description: "to see how your local directory (also, all system directories) look like."
 
 mode: ONCE
 hostname: "FF-MACVTAP"
@@ -152,16 +151,14 @@ mount {
        is_bind: true
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
 
 macvlan_iface: "enp0s31f6"
 macvlan_vs_ip: "192.168.10.223"
index efa71dc..dc8f4fd 100644 (file)
@@ -1,18 +1,17 @@
 name: "firefox-with-net"
-description: "
-This policy allows to run firefox inside a jail. Access to networking is
-permitted with this setup (clone_newnet: false).
 
-The only permitted home directory is $HOME/.mozilla and $HOME/Documents.
-The rest of available on the FS files/dires are libs and X-related files/dirs.
-
-Run as:
-
-./nsjail --config configs/firefox-with-net.cfg
-
-You can then go to https://uploadfiles.io/ and try to upload a file in order
-to see how your local directory (also, all system directories) look like.
-"
+description: "This policy allows to run firefox inside a jail. Access to networking is"
+description: "permitted with this setup (clone_newnet: false)."
+description: ""
+description: "The only permitted home directory is $HOME/.mozilla and $HOME/Documents."
+description: "The rest of available on the FS files/dires are libs and X-related files/dirs."
+description: ""
+description: "Run as:"
+description: ""
+description: "./nsjail --config configs/firefox-with-net.cfg"
+description: ""
+description: "You can then go to https://uploadfiles.io/ and try to upload a file in order"
+description: "to see how your local directory (also, all system directories) look like."
 
 mode: ONCE
 hostname: "FIREFOX"
@@ -138,16 +137,14 @@ mount {
        is_bind: true
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
 
 exec_bin {
         path: "/usr/lib/firefox/firefox"
index 0c73623..4363e36 100644 (file)
@@ -1,13 +1,12 @@
 name: "documents-with-xorg"
-description: "
-This policy allows to run many X-org based tool, which are allowed
-to access $HOME/Documents directory only. An example of use is:
 
-./nsjail --config configs/documents-with-xorg.cfg -- \\
-   /usr/bin/geeqie /user/Documents/
-
-What is more, this policy doesn't allow to access networking.
-"
+description: "This policy allows to run many X-org based tool, which are allowed"
+description: "to access $HOME/Documents directory only. An example of use is:"
+description: ""
+description: "./nsjail --config configs/documents-with-xorg.cfg -- \\"
+description: "   /usr/bin/geeqie /user/Documents/"
+description: ""
+description: "What is more, this policy doesn't allow to access networking."
 
 mode: ONCE
 hostname: "NSJAIL"
@@ -127,13 +126,11 @@ mount {
        is_bind: true
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
index 4bc910e..bd50500 100644 (file)
@@ -1,13 +1,12 @@
 name: "imagemagick-convert"
-description: "
-This policy allows to run ImageMagick's convert inside a jail.
-Your $HOME's Documents will be mapped as /user/Documents
 
-Run as:
-
-./nsjail --config imagemagick-convert.cfg -- /usr/bin/convert \\
-       jpg:/user/Documents/input.jpg png:/user/Documents/output.png
-"
+description: "This policy allows to run ImageMagick's convert inside a jail."
+description: "Your $HOME's Documents will be mapped as /user/Documents"
+description: ""
+description: "Run as:"
+description: ""
+description: "./nsjail --config imagemagick-convert.cfg -- /usr/bin/convert \\"
+description: " jpg:/user/Documents/input.jpg png:/user/Documents/output.png"
 
 mode: ONCE
 hostname: "IM-CONVERT"
@@ -77,13 +76,11 @@ mount {
        mandatory: false
 }
 
-seccomp_string: "
-       POLICY example {
-               KILL {
-                       ptrace,
-                       process_vm_readv,
-                       process_vm_writev
-               }
-       }
-       USE example DEFAULT ALLOW
-"
+seccomp_string: "      POLICY example {"
+seccomp_string: "              KILL {"
+seccomp_string: "                      ptrace,"
+seccomp_string: "                      process_vm_readv,"
+seccomp_string: "                      process_vm_writev"
+seccomp_string: "              }"
+seccomp_string: "      }"
+seccomp_string: "      USE example DEFAULT ALLOW"
diff --git a/log.c b/log.c
index 3c9b98a..7782a9b 100644 (file)
--- a/log.c
+++ b/log.c
@@ -29,8 +29,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <sys/syscall.h>
+#include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
 
diff --git a/mount.c b/mount.c
index 0771738..854809d 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -25,8 +25,8 @@
 #include <fcntl.h>
 #include <linux/sched.h>
 #include <sched.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include "subproc.h"
 #include "util.h"
 
-#define VALSTR_STRUCT(x) { x, #x }
+#define VALSTR_STRUCT(x) \
+    {                    \
+        x, #x            \
+    }
 
 #if !defined(MS_LAZYTIME)
-#define MS_LAZYTIME (1<<25)
+#define MS_LAZYTIME (1 << 25)
 #endif                         /* if !defined(MS_LAZYTIME) */
 
 const char *mountFlagsToStr(uintptr_t flags)
@@ -51,37 +54,37 @@ const char *mountFlagsToStr(uintptr_t flags)
        static __thread char mountFlagsStr[1024];
        mountFlagsStr[0] = '\0';
 
-       /*  *INDENT-OFF* */
-       static struct {
-               const uintptr_t flag;
-               const char* const name;
-       } const mountFlags[] = {
-                       VALSTR_STRUCT(MS_RDONLY),
-                       VALSTR_STRUCT(MS_NOSUID),
-                       VALSTR_STRUCT(MS_NODEV),
-                       VALSTR_STRUCT(MS_NOEXEC),
-                       VALSTR_STRUCT(MS_SYNCHRONOUS),
-                       VALSTR_STRUCT(MS_REMOUNT),
-                       VALSTR_STRUCT(MS_MANDLOCK),
-                       VALSTR_STRUCT(MS_DIRSYNC),
-                       VALSTR_STRUCT(MS_NOATIME),
-                       VALSTR_STRUCT(MS_NODIRATIME),
-                       VALSTR_STRUCT(MS_BIND),
-                       VALSTR_STRUCT(MS_MOVE),
-                       VALSTR_STRUCT(MS_REC),
-                       VALSTR_STRUCT(MS_SILENT),
-                       VALSTR_STRUCT(MS_POSIXACL),
-                       VALSTR_STRUCT(MS_UNBINDABLE),
-                       VALSTR_STRUCT(MS_PRIVATE),
-                       VALSTR_STRUCT(MS_SLAVE),
-                       VALSTR_STRUCT(MS_SHARED),
-                       VALSTR_STRUCT(MS_RELATIME),
-                       VALSTR_STRUCT(MS_KERNMOUNT),
-                       VALSTR_STRUCT(MS_I_VERSION),
-                       VALSTR_STRUCT(MS_STRICTATIME),
-                       VALSTR_STRUCT(MS_LAZYTIME),
-       };
-       /*  *INDENT-ON* */
+    /*  *INDENT-OFF* */
+    static struct {
+        const uintptr_t flag;
+        const char* const name;
+    } const mountFlags[] = {
+        VALSTR_STRUCT(MS_RDONLY),
+        VALSTR_STRUCT(MS_NOSUID),
+        VALSTR_STRUCT(MS_NODEV),
+        VALSTR_STRUCT(MS_NOEXEC),
+        VALSTR_STRUCT(MS_SYNCHRONOUS),
+        VALSTR_STRUCT(MS_REMOUNT),
+        VALSTR_STRUCT(MS_MANDLOCK),
+        VALSTR_STRUCT(MS_DIRSYNC),
+        VALSTR_STRUCT(MS_NOATIME),
+        VALSTR_STRUCT(MS_NODIRATIME),
+        VALSTR_STRUCT(MS_BIND),
+        VALSTR_STRUCT(MS_MOVE),
+        VALSTR_STRUCT(MS_REC),
+        VALSTR_STRUCT(MS_SILENT),
+        VALSTR_STRUCT(MS_POSIXACL),
+        VALSTR_STRUCT(MS_UNBINDABLE),
+        VALSTR_STRUCT(MS_PRIVATE),
+        VALSTR_STRUCT(MS_SLAVE),
+        VALSTR_STRUCT(MS_SHARED),
+        VALSTR_STRUCT(MS_RELATIME),
+        VALSTR_STRUCT(MS_KERNMOUNT),
+        VALSTR_STRUCT(MS_I_VERSION),
+        VALSTR_STRUCT(MS_STRICTATIME),
+        VALSTR_STRUCT(MS_LAZYTIME),
+    };
+    /*  *INDENT-ON* */
 
        for (size_t i = 0; i < ARRAYSIZE(mountFlags); i++) {
                if (flags & mountFlags[i].flag) {
@@ -387,7 +390,7 @@ bool mountInitNs(struct nsjconf_t * nsjconf)
 bool mountAddMountPt(struct nsjconf_t * nsjconf, const char *src, const char *dst,
                     const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
                     bool mandatory, const char *src_env, const char *dst_env,
-                    const uint8_t * src_content, size_t src_content_len, bool is_symlink)
+                    const char *src_content, size_t src_content_len, bool is_symlink)
 {
        struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
 
@@ -455,7 +458,7 @@ bool mountAddMountPt(struct nsjconf_t * nsjconf, const char *src, const char *ds
                }
        }
 
-       p->src_content = utilMemDup(src_content, src_content_len);
+       p->src_content = utilMemDup((const uint8_t *)src_content, src_content_len);
        p->src_content_len = src_content_len;
 
        TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
diff --git a/mount.h b/mount.h
index a7fd948..be9633f 100644 (file)
--- a/mount.h
+++ b/mount.h
@@ -32,7 +32,7 @@ bool mountInitNs(struct nsjconf_t *nsjconf);
 bool mountAddMountPt(struct nsjconf_t *nsjconf, const char *src, const char *dst,
                     const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
                     bool mandatory, const char *src_env, const char *dst_env,
-                    const uint8_t * src_content, size_t src_content_len, bool is_symlink);
+                    const char *src_content, size_t src_content_len, bool is_symlink);
 const char *mountDescribeMountPt(struct mounts_t *mpt);
 
 #endif                         /* NS_MOUNT_H */
diff --git a/net.c b/net.c
index 5802b14..9b5c09e 100644 (file)
--- a/net.c
+++ b/net.c
@@ -28,8 +28,8 @@
 #include <netinet/ip6.h>
 #include <netinet/tcp.h>
 #include <sched.h>
-#include <stdio.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
@@ -171,9 +171,9 @@ bool netLimitConns(struct nsjconf_t * nsjconf, int connsock)
        unsigned int cnt = 0;
        struct pids_t *p;
        TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
-               if (memcmp
-                   (addr.sin6_addr.s6_addr, p->remote_addr.sin6_addr.s6_addr,
-                    sizeof(*p->remote_addr.sin6_addr.s6_addr)) == 0) {
+               if (memcmp(addr.sin6_addr.s6_addr, p->remote_addr.sin6_addr.s6_addr,
+                          sizeof(*p->remote_addr.sin6_addr.s6_addr))
+                   == 0) {
                        cnt++;
                }
        }
index 2930138..90c496d 100644 (file)
--- a/nsjail.c
+++ b/nsjail.c
@@ -24,8 +24,8 @@
 #include <errno.h>
 #include <signal.h>
 #include <stdbool.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
 #include <unistd.h>
diff --git a/protobuf-c-text b/protobuf-c-text
deleted file mode 160000 (submodule)
index 198cfc0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 198cfc0dbe159c75026600055f28e8b797bdac3b
index 060432c..bfc1c35 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -29,8 +29,8 @@
 #include <sched.h>
 #include <setjmp.h>
 #include <signal.h>
-#include <stdio.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/prctl.h>
@@ -41,8 +41,8 @@
 #include <time.h>
 #include <unistd.h>
 
-#include "common.h"
 #include "cgroup.h"
+#include "common.h"
 #include "contain.h"
 #include "log.h"
 #include "net.h"
 
 static const char subprocDoneChar = 'D';
 
-#define VALSTR_STRUCT(x) { x, #x }
+#define VALSTR_STRUCT(x) \
+    {                    \
+        x, #x            \
+    }
 
 #if !defined(CLONE_NEWCGROUP)
 #define CLONE_NEWCGROUP 0x02000000
@@ -63,36 +66,36 @@ static const char *subprocCloneFlagsToStr(uintptr_t flags)
        static __thread char cloneFlagName[1024];
        cloneFlagName[0] = '\0';
 
-       /*  *INDENT-OFF* */
-       static struct {
-               const uintptr_t flag;
-               const char* const name;
-       } const cloneFlags[] = {
-               VALSTR_STRUCT(CLONE_VM),
-               VALSTR_STRUCT(CLONE_FS),
-               VALSTR_STRUCT(CLONE_FILES),
-               VALSTR_STRUCT(CLONE_SIGHAND),
-               VALSTR_STRUCT(CLONE_PTRACE),
-               VALSTR_STRUCT(CLONE_VFORK),
-               VALSTR_STRUCT(CLONE_PARENT),
-               VALSTR_STRUCT(CLONE_THREAD),
-               VALSTR_STRUCT(CLONE_NEWNS),
-               VALSTR_STRUCT(CLONE_SYSVSEM),
-               VALSTR_STRUCT(CLONE_SETTLS),
-               VALSTR_STRUCT(CLONE_PARENT_SETTID),
-               VALSTR_STRUCT(CLONE_CHILD_CLEARTID),
-               VALSTR_STRUCT(CLONE_DETACHED),
-               VALSTR_STRUCT(CLONE_UNTRACED),
-               VALSTR_STRUCT(CLONE_CHILD_SETTID),
-               VALSTR_STRUCT(CLONE_NEWCGROUP),
-               VALSTR_STRUCT(CLONE_NEWUTS),
-               VALSTR_STRUCT(CLONE_NEWIPC),
-               VALSTR_STRUCT(CLONE_NEWUSER),
-               VALSTR_STRUCT(CLONE_NEWPID),
-               VALSTR_STRUCT(CLONE_NEWNET),
-               VALSTR_STRUCT(CLONE_IO),
-       };
-       /*  *INDENT-ON* */
+    /*  *INDENT-OFF* */
+    static struct {
+        const uintptr_t flag;
+        const char* const name;
+    } const cloneFlags[] = {
+        VALSTR_STRUCT(CLONE_VM),
+        VALSTR_STRUCT(CLONE_FS),
+        VALSTR_STRUCT(CLONE_FILES),
+        VALSTR_STRUCT(CLONE_SIGHAND),
+        VALSTR_STRUCT(CLONE_PTRACE),
+        VALSTR_STRUCT(CLONE_VFORK),
+        VALSTR_STRUCT(CLONE_PARENT),
+        VALSTR_STRUCT(CLONE_THREAD),
+        VALSTR_STRUCT(CLONE_NEWNS),
+        VALSTR_STRUCT(CLONE_SYSVSEM),
+        VALSTR_STRUCT(CLONE_SETTLS),
+        VALSTR_STRUCT(CLONE_PARENT_SETTID),
+        VALSTR_STRUCT(CLONE_CHILD_CLEARTID),
+        VALSTR_STRUCT(CLONE_DETACHED),
+        VALSTR_STRUCT(CLONE_UNTRACED),
+        VALSTR_STRUCT(CLONE_CHILD_SETTID),
+        VALSTR_STRUCT(CLONE_NEWCGROUP),
+        VALSTR_STRUCT(CLONE_NEWUTS),
+        VALSTR_STRUCT(CLONE_NEWIPC),
+        VALSTR_STRUCT(CLONE_NEWUSER),
+        VALSTR_STRUCT(CLONE_NEWPID),
+        VALSTR_STRUCT(CLONE_NEWNET),
+        VALSTR_STRUCT(CLONE_IO),
+    };
+    /*  *INDENT-ON* */
 
        for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) {
                if (flags & cloneFlags[i].flag) {
diff --git a/user.c b/user.c
index d4d7074..c4fdeac 100644 (file)
--- a/user.c
+++ b/user.c
@@ -265,19 +265,17 @@ bool userInitNsFromChild(struct nsjconf_t * nsjconf)
        }
        LOG_D("setresgid(%d, %d, %d)", TAILQ_FIRST(&nsjconf->gids)->inside_id,
              TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id);
-       if (syscall
-           (__NR_setresgid, TAILQ_FIRST(&nsjconf->gids)->inside_id,
-            TAILQ_FIRST(&nsjconf->gids)->inside_id,
-            TAILQ_FIRST(&nsjconf->gids)->inside_id) == -1) {
+       if (syscall(__NR_setresgid, TAILQ_FIRST(&nsjconf->gids)->inside_id,
+                   TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id)
+           == -1) {
                PLOG_E("setresgid(%u)", TAILQ_FIRST(&nsjconf->gids)->inside_id);
                return false;
        }
        LOG_D("setresuid(%d, %d, %d)", TAILQ_FIRST(&nsjconf->uids)->inside_id,
              TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id);
-       if (syscall
-           (__NR_setresuid, TAILQ_FIRST(&nsjconf->uids)->inside_id,
-            TAILQ_FIRST(&nsjconf->uids)->inside_id,
-            TAILQ_FIRST(&nsjconf->uids)->inside_id) == -1) {
+       if (syscall(__NR_setresuid, TAILQ_FIRST(&nsjconf->uids)->inside_id,
+                   TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id)
+           == -1) {
                PLOG_E("setresuid(%u)", TAILQ_FIRST(&nsjconf->uids)->inside_id);
                return false;
        }