nsjail: move pids queue to a vector
authorRobert Swiecki <robert@swiecki.net>
Sat, 10 Feb 2018 04:13:25 +0000 (05:13 +0100)
committerRobert Swiecki <robert@swiecki.net>
Sat, 10 Feb 2018 04:13:25 +0000 (05:13 +0100)
cmdline.cc
net.cc
nsjail.h
subproc.cc

index e800228da220dd422752e2cb6b4183aaee973dc1..3c185f97d142f282d4ad59e34f709d001840a7f3 100644 (file)
@@ -388,7 +388,6 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
        nsjconf->openfds.push_back(STDOUT_FILENO);
        nsjconf->openfds.push_back(STDERR_FILENO);
 
-       TAILQ_INIT(&nsjconf->pids);
        TAILQ_INIT(&nsjconf->mountpts);
 
        static char cmdlineTmpfsSz[PATH_MAX] = "size=4194304";
diff --git a/net.cc b/net.cc
index e96b40f80d90a466f5345e3f7982c72283e7d332..2e046a0ed9b6c350c4e3104f2adbf0cb335d9e89 100644 (file)
--- a/net.cc
+++ b/net.cc
@@ -164,15 +164,13 @@ bool limitConns(struct nsjconf_t* nsjconf, int connsock) {
        char cs_addr[64];
        connToText(connsock, true /* remote */, cs_addr, sizeof(cs_addr), &addr);
 
-       unsigned int cnt = 0;
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
-               if (memcmp(addr.sin6_addr.s6_addr, p->remote_addr.sin6_addr.s6_addr,
-                       sizeof(p->remote_addr.sin6_addr.s6_addr)) == 0) {
+       unsigned cnt = 0;
+       for (const auto& pid : nsjconf->pids) {
+               if (memcmp(addr.sin6_addr.s6_addr, pid.remote_addr.sin6_addr.s6_addr,
+                       sizeof(pid.remote_addr.sin6_addr.s6_addr)) == 0) {
                        cnt++;
                }
        }
-
        if (cnt >= nsjconf->max_conns_per_ip) {
                LOG_W("Rejecting connection from '%s', max_conns_per_ip limit reached: %u", cs_addr,
                    nsjconf->max_conns_per_ip);
index 39dd4ca5aa4ae320537e73452c043bd60779bb8d..995a79e66ac3b2488a6858f8d4cc7f986f42266d 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -173,10 +173,9 @@ struct nsjconf_t {
        struct sock_fprog seccomp_fprog;
        long num_cpus;
        uid_t orig_uid;
-       TAILQ_HEAD(pidslist, pids_t)
-       pids;
        TAILQ_HEAD(mountptslist, mounts_t)
        mountpts;
+       std::vector<pids_t> pids;
        std::vector<idmap_t> uids;
        std::vector<idmap_t> gids;
        std::vector<std::string> envs;
index b1d88d4a5a0e9e5bf2dd7dd690681fd8c060cd74..5692edaaf207ef8588b0d892df14a078986d1c59 100644 (file)
@@ -197,61 +197,53 @@ static int subprocNewProc(
 }
 
 static void addProc(struct nsjconf_t* nsjconf, pid_t pid, int sock) {
-       struct pids_t* p = reinterpret_cast<struct pids_t*>(util::memAlloc(sizeof(struct pids_t)));
-       p->pid = pid;
-       p->start = time(NULL);
+       struct pids_t p;
+       p.pid = pid;
+       p.start = time(NULL);
+
        net::connToText(
-           sock, true /* remote */, p->remote_txt, sizeof(p->remote_txt), &p->remote_addr);
+           sock, true /* remote */, p.remote_txt, sizeof(p.remote_txt), &p.remote_addr);
 
        char fname[PATH_MAX];
        snprintf(fname, sizeof(fname), "/proc/%d/syscall", (int)pid);
-       p->pid_syscall_fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
+       p.pid_syscall_fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
 
-       TAILQ_INSERT_HEAD(&nsjconf->pids, p, pointers);
+       nsjconf->pids.push_back(p);
 
-       LOG_D("Added pid '%d' with start time '%u' to the queue for IP: '%s'", pid,
-           (unsigned int)p->start, p->remote_txt);
+       LOG_D("Added pid '%d' with start time '%u' to the queue for IP: '%s'", p.pid,
+           (unsigned int)p.start, p.remote_txt);
 }
 
 static void removeProc(struct nsjconf_t* nsjconf, pid_t pid) {
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+       for (auto p = nsjconf->pids.begin(); p != nsjconf->pids.end(); ++p) {
                if (p->pid == pid) {
                        LOG_D("Removing pid '%d' from the queue (IP:'%s', start time:'%s')", p->pid,
                            p->remote_txt, util::timeToStr(p->start));
                        close(p->pid_syscall_fd);
-                       TAILQ_REMOVE(&nsjconf->pids, p, pointers);
-                       free(p);
+                       nsjconf->pids.erase(p);
                        return;
                }
        }
        LOG_W("PID: %d not found (?)", pid);
 }
 
-int countProc(struct nsjconf_t* nsjconf) {
-       int cnt = 0;
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) { cnt++; }
-       return cnt;
-}
+int countProc(struct nsjconf_t* nsjconf) { return nsjconf->pids.size(); }
 
 void displayProc(struct nsjconf_t* nsjconf) {
        LOG_I("Total number of spawned namespaces: %d", countProc(nsjconf));
        time_t now = time(NULL);
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
-               time_t diff = now - p->start;
+       for (const auto& pid : nsjconf->pids) {
+               time_t diff = now - pid.start;
                time_t left = nsjconf->tlimit ? nsjconf->tlimit - diff : 0;
-               LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", p->pid,
-                   p->remote_txt, (long)diff, (long)left);
+               LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", pid.pid,
+                   pid.remote_txt, (long)diff, (long)left);
        }
 }
 
-static struct pids_t* getPidElem(struct nsjconf_t* nsjconf, pid_t pid) {
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
-               if (p->pid == pid) {
-                       return p;
+static const struct pids_t* getPidElem(struct nsjconf_t* nsjconf, pid_t pid) {
+       for (const auto& p : nsjconf->pids) {
+               if (p.pid == pid) {
+                       return &p;
                }
        }
        return NULL;
@@ -260,7 +252,7 @@ static struct pids_t* getPidElem(struct nsjconf_t* nsjconf, pid_t pid) {
 static void seccompViolation(struct nsjconf_t* nsjconf, siginfo_t* si) {
        LOG_W("PID: %d commited a syscall/seccomp violation and exited with SIGSYS", si->si_pid);
 
-       struct pids_t* p = getPidElem(nsjconf, si->si_pid);
+       const struct pids_t* p = getPidElem(nsjconf, si->si_pid);
        if (p == NULL) {
                LOG_W("PID:%d SiSyscall: %d, SiCode: %d, SiErrno: %d", (int)si->si_pid,
                    si->si_syscall, si->si_code, si->si_errno);
@@ -317,7 +309,7 @@ int reapProc(struct nsjconf_t* nsjconf) {
                        cgroup::finishFromParent(nsjconf, si.si_pid);
 
                        const char* remote_txt = "[UNKNOWN]";
-                       struct pids_t* elem = getPidElem(nsjconf, si.si_pid);
+                       const struct pids_t* elem = getPidElem(nsjconf, si.si_pid);
                        if (elem) {
                                remote_txt = elem->remote_txt;
                        }
@@ -344,16 +336,15 @@ int reapProc(struct nsjconf_t* nsjconf) {
        }
 
        time_t now = time(NULL);
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+       for (const auto& p : nsjconf->pids) {
                if (nsjconf->tlimit == 0) {
                        continue;
                }
-               pid_t pid = p->pid;
-               time_t diff = now - p->start;
+               pid_t pid = p.pid;
+               time_t diff = now - p.start;
                if (diff >= nsjconf->tlimit) {
                        LOG_I("PID: %d run time >= time limit (%ld >= %ld) (%s). Killing it", pid,
-                           (long)diff, (long)nsjconf->tlimit, p->remote_txt);
+                           (long)diff, (long)nsjconf->tlimit, p.remote_txt);
                        /*
                         * Probably a kernel bug - some processes cannot be killed with KILL if
                         * they're namespaced, and in a stopped state
@@ -368,8 +359,9 @@ int reapProc(struct nsjconf_t* nsjconf) {
 }
 
 void killAll(struct nsjconf_t* nsjconf) {
-       struct pids_t* p;
-       TAILQ_FOREACH(p, &nsjconf->pids, pointers) { kill(p->pid, SIGKILL); }
+       for (const auto& p : nsjconf->pids) {
+               kill(p.pid, SIGKILL);
+       }
 }
 
 static bool initParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd) {