convert exec file and argv to string/vector
authorRobert Swiecki <robert@swiecki.net>
Mon, 12 Feb 2018 15:52:05 +0000 (16:52 +0100)
committerRobert Swiecki <robert@swiecki.net>
Mon, 12 Feb 2018 15:52:05 +0000 (16:52 +0100)
cmdline.cc
config.cc
nsjail.h
subproc.cc

index 5dcbf8c..97c491f 100644 (file)
@@ -231,7 +231,7 @@ void logParams(nsjconf_t* nsjconf) {
            "clone_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, "
            "clone_newipc:%s, clonew_newuts:%s, clone_newcgroup:%s, keep_caps:%s, "
            "tmpfs_size:%zu, disable_no_new_privs:%s, max_cpus:%zu",
-           nsjconf->hostname.c_str(), nsjconf->chroot.c_str(), nsjconf->argv[0],
+           nsjconf->hostname.c_str(), nsjconf->chroot.c_str(), nsjconf->argv[0].c_str(),
            nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->tlimit,
            nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
            logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns),
@@ -310,10 +310,8 @@ static std::string argByColon(const char* str, size_t pos) {
 std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        std::unique_ptr<nsjconf_t> nsjconf = std::make_unique<nsjconf_t>();
 
-       nsjconf->exec_file = NULL;
        nsjconf->use_execveat = false;
        nsjconf->exec_fd = -1;
-       nsjconf->argv = NULL;
        nsjconf->hostname = "NSJAIL";
        nsjconf->cwd = "/";
        nsjconf->port = 0;
@@ -792,15 +790,15 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                nsjconf->gids.push_back(gid);
        }
 
-       if (argv[optind]) {
-               nsjconf->argv = (const char**)&argv[optind];
+       for (size_t i = optind; optind < argc; i++) {
+               nsjconf->argv[i] = argv[optind];
        }
-       if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) {
+       if (nsjconf->argv.empty()) {
                cmdlineUsage(argv[0]);
                LOG_E("No command provided");
                return nullptr;
        }
-       if (nsjconf->exec_file == NULL) {
+       if (nsjconf->exec_file.empty()) {
                nsjconf->exec_file = nsjconf->argv[0];
        }
 
@@ -812,8 +810,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                return nullptr;
 #endif /* !defined(__NR_execveat) */
                if ((nsjconf->exec_fd = TEMP_FAILURE_RETRY(
-                        open(nsjconf->exec_file, O_RDONLY | O_PATH | O_CLOEXEC))) == -1) {
-                       PLOG_W("Couldn't open '%s' file", nsjconf->exec_file);
+                        open(nsjconf->exec_file.c_str(), O_RDONLY | O_PATH | O_CLOEXEC))) == -1) {
+                       PLOG_W("Couldn't open '%s' file", nsjconf->exec_file.c_str());
                        return nullptr;
                }
        }
index 14ca363..f231354 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -254,18 +254,14 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
        nsjconf->iface_vs_gw = njc.macvlan_vs_gw();
 
        if (njc.has_exec_bin()) {
-               static std::vector<const char*> argv;
-               if (njc.exec_bin().has_arg0()) {
-                       argv.push_back(njc.exec_bin().arg0().c_str());
-                       nsjconf->exec_file = njc.exec_bin().path().c_str();
-               } else {
-                       argv.push_back(njc.exec_bin().path().c_str());
-               }
+               nsjconf->exec_file = njc.exec_bin().path();
+               nsjconf->argv.push_back(njc.exec_bin().path());
                for (ssize_t i = 0; i < njc.exec_bin().arg().size(); i++) {
-                       argv.push_back(njc.exec_bin().arg(i).c_str());
+                       nsjconf->argv.push_back(njc.exec_bin().arg(i));
+               }
+               if (njc.exec_bin().has_arg0()) {
+                       nsjconf->argv[0] = njc.exec_bin().arg0();
                }
-               argv.push_back(nullptr);
-               nsjconf->argv = argv.data();
                nsjconf->use_execveat = njc.exec_bin().exec_fd();
        }
 
index 238f5c2..a7d180c 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -82,10 +82,10 @@ enum ns_mode_t {
 };
 
 struct nsjconf_t {
-       const char* exec_file;
+       std::string exec_file;
        bool use_execveat;
        int exec_fd;
-       const char** argv;
+       std::vector<std::string> argv;
        std::string hostname;
        std::string cwd;
        std::string chroot;
index dd453cc..c543fb9 100644 (file)
@@ -167,11 +167,14 @@ static int subprocNewProc(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err,
        }
 
        auto connstr = net::connToText(fd_in, /* remote= */ true, NULL);
-       LOG_I("Executing '%s' for '%s'", nsjconf->exec_file, connstr.c_str());
+       LOG_I("Executing '%s' for '%s'", nsjconf->exec_file.c_str(), connstr.c_str());
 
-       for (size_t i = 0; nsjconf->argv[i]; i++) {
-               LOG_D(" Arg[%zu]: '%s'", i, nsjconf->argv[i]);
+       std::vector<const char*> argv;
+       for (const auto& s : nsjconf->argv) {
+               argv.push_back(s.c_str());
+               LOG_D(" Arg: '%s'", s.c_str());
        }
+       argv.push_back(nullptr);
 
        /* Should be the last one in the sequence */
        if (!sandbox::applyPolicy(nsjconf)) {
@@ -180,16 +183,16 @@ static int subprocNewProc(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err,
 
        if (nsjconf->use_execveat) {
 #if defined(__NR_execveat)
-               syscall(__NR_execveat, (uintptr_t)nsjconf->exec_fd, "",
-                   (char* const*)&nsjconf->argv[0], environ, (uintptr_t)AT_EMPTY_PATH);
+               syscall(__NR_execveat, (uintptr_t)nsjconf->exec_fd, "", (char* const*)argv.data(),
+                   environ, (uintptr_t)AT_EMPTY_PATH);
 #else  /* defined(__NR_execveat) */
                LOG_F("Your system doesn't support execveat() syscall");
 #endif /* defined(__NR_execveat) */
        } else {
-               execv(nsjconf->exec_file, (char* const*)&nsjconf->argv[0]);
+               execv(nsjconf->exec_file.c_str(), (char* const*)argv.data());
        }
 
-       PLOG_E("execve('%s') failed", nsjconf->exec_file);
+       PLOG_E("execve('%s') failed", nsjconf->exec_file.c_str());
 
        _exit(0xff);
 }