nsjail: move pids queue to a vector
This commit is contained in:
parent
5f3267e745
commit
381e6a1af7
@ -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";
|
||||
|
10
net.cc
10
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);
|
||||
|
3
nsjail.h
3
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;
|
||||
|
66
subproc.cc
66
subproc.cc
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user