"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),
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;
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];
}
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;
}
}
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();
}
};
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;
}
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)) {
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);
}