convert exec file and argv to string/vector

This commit is contained in:
Robert Swiecki 2018-02-12 16:52:05 +01:00
parent ff43c5b44b
commit 8a22a4abb6
4 changed files with 25 additions and 28 deletions

View 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;
}
}

View File

@ -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();
}

View File

@ -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;

View 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);
}