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_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, "
"clone_newipc:%s, clonew_newuts:%s, clone_newcgroup:%s, keep_caps:%s, " "clone_newipc:%s, clonew_newuts:%s, clone_newcgroup:%s, keep_caps:%s, "
"tmpfs_size:%zu, disable_no_new_privs:%s, max_cpus:%zu", "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->bindhost.c_str(), nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->tlimit,
nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet), nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns), 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> parseArgs(int argc, char* argv[]) {
std::unique_ptr<nsjconf_t> nsjconf = std::make_unique<nsjconf_t>(); std::unique_ptr<nsjconf_t> nsjconf = std::make_unique<nsjconf_t>();
nsjconf->exec_file = NULL;
nsjconf->use_execveat = false; nsjconf->use_execveat = false;
nsjconf->exec_fd = -1; nsjconf->exec_fd = -1;
nsjconf->argv = NULL;
nsjconf->hostname = "NSJAIL"; nsjconf->hostname = "NSJAIL";
nsjconf->cwd = "/"; nsjconf->cwd = "/";
nsjconf->port = 0; nsjconf->port = 0;
@ -792,15 +790,15 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
nsjconf->gids.push_back(gid); nsjconf->gids.push_back(gid);
} }
if (argv[optind]) { for (size_t i = optind; optind < argc; i++) {
nsjconf->argv = (const char**)&argv[optind]; nsjconf->argv[i] = argv[optind];
} }
if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) { if (nsjconf->argv.empty()) {
cmdlineUsage(argv[0]); cmdlineUsage(argv[0]);
LOG_E("No command provided"); LOG_E("No command provided");
return nullptr; return nullptr;
} }
if (nsjconf->exec_file == NULL) { if (nsjconf->exec_file.empty()) {
nsjconf->exec_file = nsjconf->argv[0]; nsjconf->exec_file = nsjconf->argv[0];
} }
@ -812,8 +810,8 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
return nullptr; return nullptr;
#endif /* !defined(__NR_execveat) */ #endif /* !defined(__NR_execveat) */
if ((nsjconf->exec_fd = TEMP_FAILURE_RETRY( if ((nsjconf->exec_fd = TEMP_FAILURE_RETRY(
open(nsjconf->exec_file, O_RDONLY | O_PATH | O_CLOEXEC))) == -1) { open(nsjconf->exec_file.c_str(), O_RDONLY | O_PATH | O_CLOEXEC))) == -1) {
PLOG_W("Couldn't open '%s' file", nsjconf->exec_file); PLOG_W("Couldn't open '%s' file", nsjconf->exec_file.c_str());
return nullptr; 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(); nsjconf->iface_vs_gw = njc.macvlan_vs_gw();
if (njc.has_exec_bin()) { if (njc.has_exec_bin()) {
static std::vector<const char*> argv; nsjconf->exec_file = njc.exec_bin().path();
if (njc.exec_bin().has_arg0()) { nsjconf->argv.push_back(njc.exec_bin().path());
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());
}
for (ssize_t i = 0; i < njc.exec_bin().arg().size(); i++) { 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(); nsjconf->use_execveat = njc.exec_bin().exec_fd();
} }

View File

@ -82,10 +82,10 @@ enum ns_mode_t {
}; };
struct nsjconf_t { struct nsjconf_t {
const char* exec_file; std::string exec_file;
bool use_execveat; bool use_execveat;
int exec_fd; int exec_fd;
const char** argv; std::vector<std::string> argv;
std::string hostname; std::string hostname;
std::string cwd; std::string cwd;
std::string chroot; 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); 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++) { std::vector<const char*> argv;
LOG_D(" Arg[%zu]: '%s'", i, nsjconf->argv[i]); 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 */ /* Should be the last one in the sequence */
if (!sandbox::applyPolicy(nsjconf)) { 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 (nsjconf->use_execveat) {
#if defined(__NR_execveat) #if defined(__NR_execveat)
syscall(__NR_execveat, (uintptr_t)nsjconf->exec_fd, "", syscall(__NR_execveat, (uintptr_t)nsjconf->exec_fd, "", (char* const*)argv.data(),
(char* const*)&nsjconf->argv[0], environ, (uintptr_t)AT_EMPTY_PATH); environ, (uintptr_t)AT_EMPTY_PATH);
#else /* defined(__NR_execveat) */ #else /* defined(__NR_execveat) */
LOG_F("Your system doesn't support execveat() syscall"); LOG_F("Your system doesn't support execveat() syscall");
#endif /* defined(__NR_execveat) */ #endif /* defined(__NR_execveat) */
} else { } 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); _exit(0xff);
} }