nsjail: make nsjail.c nsjail.cc
authorRobert Swiecki <robert@swiecki.net>
Thu, 8 Feb 2018 14:24:17 +0000 (15:24 +0100)
committerRobert Swiecki <robert@swiecki.net>
Thu, 8 Feb 2018 14:24:17 +0000 (15:24 +0100)
Makefile
cmdline.h
log.h
net.h
nsjail.c [deleted file]
nsjail.cc [new file with mode: 0644]
nsjail.h
subproc.h
util.h

index f6b9abe4d5754c499366730cc20885f44750c699..98adb7d8a239e55577f4ffd8b0b4cc9a209fb323 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,8 +35,8 @@ LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs protobuf)
 
 BIN = nsjail
 LIBS = kafel/libkafel.a
-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_C = caps.c cmdline.c contain.c log.c cgroup.c mount.c net.c pid.c sandbox.c subproc.c user.c util.c uts.c cpu.c
+SRCS_CXX = nsjail.cc config.cc
 SRCS_PROTO = config.proto
 SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc)
 SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h)
@@ -60,7 +60,7 @@ endif
 .PHONY: all clean depend indent
 
 .c.o: %.c
-       $(CC) $(CFLAGS) $< -o $@
+       $(CXX) -xc $(CFLAGS) $< -o $@
 
 .cc.o: %.cc
        $(CXX) $(CXXFLAGS) $< -o $@
index 61dae5459fd3ac9162ad967b6f260d15c72c63a4..7fdf5ee64c5523c585c0a019f7d84f8f6cbb0754 100644 (file)
--- a/cmdline.h
+++ b/cmdline.h
 
 #include "nsjail.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 uint64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul);
 void cmdlineLogParams(struct nsjconf_t* nsjconf);
 bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* _CMDLINE_H */
diff --git a/log.h b/log.h
index 2d4fbc8a33e96a063066d9b99e3d7665909cdb2f..c265ac3c38be44af88b2f4a9bea0658b98049352 100644 (file)
--- a/log.h
+++ b/log.h
 #define PLOG_E(...) logLog(ERROR, __func__, __LINE__, true, __VA_ARGS__);
 #define PLOG_F(...) logLog(FATAL, __func__, __LINE__, true, __VA_ARGS__);
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool logInitLogFile(struct nsjconf_t* nsjconf);
 void logLog(enum llevel_t ll, const char* fn, int ln, bool perr, const char* fmt, ...)
     __attribute__((format(printf, 5, 6)));
 void logStop(int sig);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* NS_LOG_H */
diff --git a/net.h b/net.h
index 57d9c25bcb93c35fa1fd6831fc3dcd971430eae9..32c3416984947aa0c626d7b9472e27ecc07b124f 100644 (file)
--- a/net.h
+++ b/net.h
 
 #include "nsjail.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool netLimitConns(struct nsjconf_t* nsjconf, int connsock);
 int netGetRecvSocket(const char* bindhost, int port);
 int netAcceptConn(int listenfd);
@@ -34,4 +38,8 @@ void netConnToText(int fd, bool remote, char* buf, size_t s, struct sockaddr_in6
 bool netInitNsFromParent(struct nsjconf_t* nsjconf, int pid);
 bool netInitNsFromChild(struct nsjconf_t* nsjconf);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* _NET_H */
diff --git a/nsjail.c b/nsjail.c
deleted file mode 100644 (file)
index 3fbd372..0000000
--- a/nsjail.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-
-   nsjail
-   -----------------------------------------
-
-   Copyright 2014 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 "nsjail.h"
-
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include "cmdline.h"
-#include "common.h"
-#include "log.h"
-#include "net.h"
-#include "subproc.h"
-#include "util.h"
-
-static __thread int nsjailSigFatal = 0;
-static __thread bool nsjailShowProc = false;
-
-static void nsjailSig(int sig) {
-       if (sig == SIGALRM) {
-               return;
-       }
-       if (sig == SIGCHLD) {
-               return;
-       }
-       if (sig == SIGUSR1 || sig == SIGQUIT) {
-               nsjailShowProc = true;
-               return;
-       }
-       nsjailSigFatal = sig;
-}
-
-static bool nsjailSetSigHandler(int sig) {
-       LOG_D("Setting sighandler for signal %s (%d)", utilSigName(sig), sig);
-
-       sigset_t smask;
-       sigemptyset(&smask);
-       struct sigaction sa = {
-           .sa_handler = nsjailSig,
-           .sa_mask = smask,
-           .sa_flags = 0,
-           .sa_restorer = NULL,
-       };
-       if (sigaction(sig, &sa, NULL) == -1) {
-               PLOG_E("sigaction(%d)", sig);
-               return false;
-       }
-       return true;
-}
-
-static bool nsjailSetSigHandlers(void) {
-       for (size_t i = 0; i < ARRAYSIZE(nssigs); i++) {
-               if (!nsjailSetSigHandler(nssigs[i])) {
-                       return false;
-               }
-       }
-       return true;
-}
-
-static bool nsjailSetTimer(struct nsjconf_t* nsjconf) {
-       if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
-               return true;
-       }
-
-       struct itimerval it = {
-           .it_value =
-               {
-                   .tv_sec = 1,
-                   .tv_usec = 0,
-               },
-           .it_interval =
-               {
-                   .tv_sec = 1,
-                   .tv_usec = 0,
-               },
-       };
-       if (setitimer(ITIMER_REAL, &it, NULL) == -1) {
-               PLOG_E("setitimer(ITIMER_REAL)");
-               return false;
-       }
-       return true;
-}
-
-static void nsjailListenMode(struct nsjconf_t* nsjconf) {
-       int listenfd = netGetRecvSocket(nsjconf->bindhost, nsjconf->port);
-       if (listenfd == -1) {
-               return;
-       }
-       for (;;) {
-               if (nsjailSigFatal > 0) {
-                       subprocKillAll(nsjconf);
-                       logStop(nsjailSigFatal);
-                       close(listenfd);
-                       return;
-               }
-               if (nsjailShowProc) {
-                       nsjailShowProc = false;
-                       subprocDisplay(nsjconf);
-               }
-               int connfd = netAcceptConn(listenfd);
-               if (connfd >= 0) {
-                       subprocRunChild(nsjconf, connfd, connfd, connfd);
-                       close(connfd);
-               }
-               subprocReap(nsjconf);
-       }
-}
-
-static int nsjailStandaloneMode(struct nsjconf_t* nsjconf) {
-       subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
-       for (;;) {
-               int child_status = subprocReap(nsjconf);
-
-               if (subprocCount(nsjconf) == 0) {
-                       if (nsjconf->mode == MODE_STANDALONE_ONCE) {
-                               return child_status;
-                       }
-                       subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
-                       continue;
-               }
-               if (nsjailShowProc) {
-                       nsjailShowProc = false;
-                       subprocDisplay(nsjconf);
-               }
-               if (nsjailSigFatal > 0) {
-                       subprocKillAll(nsjconf);
-                       logStop(nsjailSigFatal);
-                       return -1;
-               }
-
-               pause();
-       }
-       // not reached
-}
-
-int main(int argc, char* argv[]) {
-       struct nsjconf_t nsjconf;
-       if (!cmdlineParse(argc, argv, &nsjconf)) {
-               LOG_F("Couldn't parse cmdline options");
-       }
-       if (nsjconf.clone_newuser == false && geteuid() != 0) {
-               LOG_W("--disable_clone_newuser might require root() privs");
-       }
-       if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
-               PLOG_F("daemon");
-       }
-       cmdlineLogParams(&nsjconf);
-       if (nsjailSetSigHandlers() == false) {
-               LOG_F("nsjailSetSigHandlers() failed");
-       }
-       if (nsjailSetTimer(&nsjconf) == false) {
-               LOG_F("nsjailSetTimer() failed");
-       }
-
-       if (nsjconf.mode == MODE_LISTEN_TCP) {
-               nsjailListenMode(&nsjconf);
-       } else {
-               return nsjailStandaloneMode(&nsjconf);
-       }
-       return 0;
-}
diff --git a/nsjail.cc b/nsjail.cc
new file mode 100644 (file)
index 0000000..3e92b50
--- /dev/null
+++ b/nsjail.cc
@@ -0,0 +1,184 @@
+/*
+
+   nsjail
+   -----------------------------------------
+
+   Copyright 2014 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 "nsjail.h"
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "cmdline.h"
+#include "common.h"
+#include "log.h"
+#include "net.h"
+#include "subproc.h"
+#include "util.h"
+
+static __thread int nsjailSigFatal = 0;
+static __thread bool nsjailShowProc = false;
+
+static void nsjailSig(int sig) {
+       if (sig == SIGALRM) {
+               return;
+       }
+       if (sig == SIGCHLD) {
+               return;
+       }
+       if (sig == SIGUSR1 || sig == SIGQUIT) {
+               nsjailShowProc = true;
+               return;
+       }
+       nsjailSigFatal = sig;
+}
+
+static bool nsjailSetSigHandler(int sig) {
+       LOG_D("Setting sighandler for signal %s (%d)", utilSigName(sig), sig);
+
+       sigset_t smask;
+       sigemptyset(&smask);
+
+       struct sigaction sa;
+       sa.sa_handler = nsjailSig;
+       sa.sa_mask = smask;
+       sa.sa_flags = 0;
+       sa.sa_restorer = NULL;
+       if (sigaction(sig, &sa, NULL) == -1) {
+               PLOG_E("sigaction(%d)", sig);
+               return false;
+       }
+       return true;
+}
+
+static bool nsjailSetSigHandlers(void) {
+       for (size_t i = 0; i < ARRAYSIZE(nssigs); i++) {
+               if (!nsjailSetSigHandler(nssigs[i])) {
+                       return false;
+               }
+       }
+       return true;
+}
+
+static bool nsjailSetTimer(struct nsjconf_t* nsjconf) {
+       if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
+               return true;
+       }
+
+       struct itimerval it = {
+           .it_interval =
+               {
+                   .tv_sec = 1,
+                   .tv_usec = 0,
+               },
+           .it_value =
+               {
+                   .tv_sec = 1,
+                   .tv_usec = 0,
+               },
+       };
+       if (setitimer(ITIMER_REAL, &it, NULL) == -1) {
+               PLOG_E("setitimer(ITIMER_REAL)");
+               return false;
+       }
+       return true;
+}
+
+static void nsjailListenMode(struct nsjconf_t* nsjconf) {
+       int listenfd = netGetRecvSocket(nsjconf->bindhost, nsjconf->port);
+       if (listenfd == -1) {
+               return;
+       }
+       for (;;) {
+               if (nsjailSigFatal > 0) {
+                       subprocKillAll(nsjconf);
+                       logStop(nsjailSigFatal);
+                       close(listenfd);
+                       return;
+               }
+               if (nsjailShowProc) {
+                       nsjailShowProc = false;
+                       subprocDisplay(nsjconf);
+               }
+               int connfd = netAcceptConn(listenfd);
+               if (connfd >= 0) {
+                       subprocRunChild(nsjconf, connfd, connfd, connfd);
+                       close(connfd);
+               }
+               subprocReap(nsjconf);
+       }
+}
+
+static int nsjailStandaloneMode(struct nsjconf_t* nsjconf) {
+       subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
+       for (;;) {
+               int child_status = subprocReap(nsjconf);
+
+               if (subprocCount(nsjconf) == 0) {
+                       if (nsjconf->mode == MODE_STANDALONE_ONCE) {
+                               return child_status;
+                       }
+                       subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
+                       continue;
+               }
+               if (nsjailShowProc) {
+                       nsjailShowProc = false;
+                       subprocDisplay(nsjconf);
+               }
+               if (nsjailSigFatal > 0) {
+                       subprocKillAll(nsjconf);
+                       logStop(nsjailSigFatal);
+                       return -1;
+               }
+
+               pause();
+       }
+       // not reached
+}
+
+int main(int argc, char* argv[]) {
+       struct nsjconf_t nsjconf;
+       if (!cmdlineParse(argc, argv, &nsjconf)) {
+               LOG_F("Couldn't parse cmdline options");
+       }
+       if (nsjconf.clone_newuser == false && geteuid() != 0) {
+               LOG_W("--disable_clone_newuser might require root() privs");
+       }
+       if (nsjconf.daemonize && (daemon(0, 0) == -1)) {
+               PLOG_F("daemon");
+       }
+       cmdlineLogParams(&nsjconf);
+       if (nsjailSetSigHandlers() == false) {
+               LOG_F("nsjailSetSigHandlers() failed");
+       }
+       if (nsjailSetTimer(&nsjconf) == false) {
+               LOG_F("nsjailSetTimer() failed");
+       }
+
+       if (nsjconf.mode == MODE_LISTEN_TCP) {
+               nsjailListenMode(&nsjconf);
+       } else {
+               return nsjailStandaloneMode(&nsjconf);
+       }
+       return 0;
+}
index 2b7161d6465880e1928c5f97c61d2c5ad6158a05..9b8ebf999e1971eb48a858259d533f905e41ff42 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
        }))
 #endif /* !defined(TEMP_FAILURE_RETRY) */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 static const int nssigs[] = {
     SIGINT,
     SIGQUIT,
@@ -198,4 +202,8 @@ struct nsjconf_t {
        caps;
 };
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* _NSJAIL_H */
index a0cc38549279fc4358d81986844dbc2ba2e92b7c..d601cdc5acfa852beec2556f07dc8786fb783fde 100644 (file)
--- a/subproc.h
+++ b/subproc.h
 
 #include "nsjail.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 void subprocRunChild(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err);
 int subprocCount(struct nsjconf_t* nsjconf);
 void subprocDisplay(struct nsjconf_t* nsjconf);
@@ -39,4 +43,8 @@ void subprocCloneFlags(struct nsjconf_t* nsjconf);
 /* Returns the exit code of the first failing subprocess, or 0 if none fail */
 int subprocReap(struct nsjconf_t* nsjconf);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* NS_PROC_H */
diff --git a/util.h b/util.h
index 2c23ddc025a3bc7bf19ba78652b000aede66c940..2a2e4a5d5f15595aa42f4753578f0d9109d7b5c6 100644 (file)
--- a/util.h
+++ b/util.h
 
 #include "nsjail.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 void* utilMalloc(size_t sz);
 void* utilCalloc(size_t sz);
 char* utilStrDup(const char* str);
@@ -43,4 +47,8 @@ uint64_t utilRnd64(void);
 const char* utilSigName(int signo);
 const char* utilTimeToStr(time_t t);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* NS_UTIL_H */