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(STDOUT_FILENO);
|
||||||
nsjconf->openfds.push_back(STDERR_FILENO);
|
nsjconf->openfds.push_back(STDERR_FILENO);
|
||||||
|
|
||||||
TAILQ_INIT(&nsjconf->pids);
|
|
||||||
TAILQ_INIT(&nsjconf->mountpts);
|
TAILQ_INIT(&nsjconf->mountpts);
|
||||||
|
|
||||||
static char cmdlineTmpfsSz[PATH_MAX] = "size=4194304";
|
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];
|
char cs_addr[64];
|
||||||
connToText(connsock, true /* remote */, cs_addr, sizeof(cs_addr), &addr);
|
connToText(connsock, true /* remote */, cs_addr, sizeof(cs_addr), &addr);
|
||||||
|
|
||||||
unsigned int cnt = 0;
|
unsigned cnt = 0;
|
||||||
struct pids_t* p;
|
for (const auto& pid : nsjconf->pids) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
|
if (memcmp(addr.sin6_addr.s6_addr, pid.remote_addr.sin6_addr.s6_addr,
|
||||||
if (memcmp(addr.sin6_addr.s6_addr, p->remote_addr.sin6_addr.s6_addr,
|
sizeof(pid.remote_addr.sin6_addr.s6_addr)) == 0) {
|
||||||
sizeof(p->remote_addr.sin6_addr.s6_addr)) == 0) {
|
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt >= nsjconf->max_conns_per_ip) {
|
if (cnt >= nsjconf->max_conns_per_ip) {
|
||||||
LOG_W("Rejecting connection from '%s', max_conns_per_ip limit reached: %u", cs_addr,
|
LOG_W("Rejecting connection from '%s', max_conns_per_ip limit reached: %u", cs_addr,
|
||||||
nsjconf->max_conns_per_ip);
|
nsjconf->max_conns_per_ip);
|
||||||
|
3
nsjail.h
3
nsjail.h
@ -173,10 +173,9 @@ struct nsjconf_t {
|
|||||||
struct sock_fprog seccomp_fprog;
|
struct sock_fprog seccomp_fprog;
|
||||||
long num_cpus;
|
long num_cpus;
|
||||||
uid_t orig_uid;
|
uid_t orig_uid;
|
||||||
TAILQ_HEAD(pidslist, pids_t)
|
|
||||||
pids;
|
|
||||||
TAILQ_HEAD(mountptslist, mounts_t)
|
TAILQ_HEAD(mountptslist, mounts_t)
|
||||||
mountpts;
|
mountpts;
|
||||||
|
std::vector<pids_t> pids;
|
||||||
std::vector<idmap_t> uids;
|
std::vector<idmap_t> uids;
|
||||||
std::vector<idmap_t> gids;
|
std::vector<idmap_t> gids;
|
||||||
std::vector<std::string> envs;
|
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) {
|
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)));
|
struct pids_t p;
|
||||||
p->pid = pid;
|
p.pid = pid;
|
||||||
p->start = time(NULL);
|
p.start = time(NULL);
|
||||||
|
|
||||||
net::connToText(
|
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];
|
char fname[PATH_MAX];
|
||||||
snprintf(fname, sizeof(fname), "/proc/%d/syscall", (int)pid);
|
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,
|
LOG_D("Added pid '%d' with start time '%u' to the queue for IP: '%s'", p.pid,
|
||||||
(unsigned int)p->start, p->remote_txt);
|
(unsigned int)p.start, p.remote_txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeProc(struct nsjconf_t* nsjconf, pid_t pid) {
|
static void removeProc(struct nsjconf_t* nsjconf, pid_t pid) {
|
||||||
struct pids_t* p;
|
for (auto p = nsjconf->pids.begin(); p != nsjconf->pids.end(); ++p) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
|
|
||||||
if (p->pid == pid) {
|
if (p->pid == pid) {
|
||||||
LOG_D("Removing pid '%d' from the queue (IP:'%s', start time:'%s')", p->pid,
|
LOG_D("Removing pid '%d' from the queue (IP:'%s', start time:'%s')", p->pid,
|
||||||
p->remote_txt, util::timeToStr(p->start));
|
p->remote_txt, util::timeToStr(p->start));
|
||||||
close(p->pid_syscall_fd);
|
close(p->pid_syscall_fd);
|
||||||
TAILQ_REMOVE(&nsjconf->pids, p, pointers);
|
nsjconf->pids.erase(p);
|
||||||
free(p);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_W("PID: %d not found (?)", pid);
|
LOG_W("PID: %d not found (?)", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int countProc(struct nsjconf_t* nsjconf) {
|
int countProc(struct nsjconf_t* nsjconf) { return nsjconf->pids.size(); }
|
||||||
int cnt = 0;
|
|
||||||
struct pids_t* p;
|
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) { cnt++; }
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void displayProc(struct nsjconf_t* nsjconf) {
|
void displayProc(struct nsjconf_t* nsjconf) {
|
||||||
LOG_I("Total number of spawned namespaces: %d", countProc(nsjconf));
|
LOG_I("Total number of spawned namespaces: %d", countProc(nsjconf));
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct pids_t* p;
|
for (const auto& pid : nsjconf->pids) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
|
time_t diff = now - pid.start;
|
||||||
time_t diff = now - p->start;
|
|
||||||
time_t left = nsjconf->tlimit ? nsjconf->tlimit - diff : 0;
|
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,
|
LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", pid.pid,
|
||||||
p->remote_txt, (long)diff, (long)left);
|
pid.remote_txt, (long)diff, (long)left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pids_t* getPidElem(struct nsjconf_t* nsjconf, pid_t pid) {
|
static const struct pids_t* getPidElem(struct nsjconf_t* nsjconf, pid_t pid) {
|
||||||
struct pids_t* p;
|
for (const auto& p : nsjconf->pids) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
|
if (p.pid == pid) {
|
||||||
if (p->pid == pid) {
|
return &p;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
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) {
|
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);
|
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) {
|
if (p == NULL) {
|
||||||
LOG_W("PID:%d SiSyscall: %d, SiCode: %d, SiErrno: %d", (int)si->si_pid,
|
LOG_W("PID:%d SiSyscall: %d, SiCode: %d, SiErrno: %d", (int)si->si_pid,
|
||||||
si->si_syscall, si->si_code, si->si_errno);
|
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);
|
cgroup::finishFromParent(nsjconf, si.si_pid);
|
||||||
|
|
||||||
const char* remote_txt = "[UNKNOWN]";
|
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) {
|
if (elem) {
|
||||||
remote_txt = elem->remote_txt;
|
remote_txt = elem->remote_txt;
|
||||||
}
|
}
|
||||||
@ -344,16 +336,15 @@ int reapProc(struct nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct pids_t* p;
|
for (const auto& p : nsjconf->pids) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
|
|
||||||
if (nsjconf->tlimit == 0) {
|
if (nsjconf->tlimit == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pid_t pid = p->pid;
|
pid_t pid = p.pid;
|
||||||
time_t diff = now - p->start;
|
time_t diff = now - p.start;
|
||||||
if (diff >= nsjconf->tlimit) {
|
if (diff >= nsjconf->tlimit) {
|
||||||
LOG_I("PID: %d run time >= time limit (%ld >= %ld) (%s). Killing it", pid,
|
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
|
* Probably a kernel bug - some processes cannot be killed with KILL if
|
||||||
* they're namespaced, and in a stopped state
|
* they're namespaced, and in a stopped state
|
||||||
@ -368,8 +359,9 @@ int reapProc(struct nsjconf_t* nsjconf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void killAll(struct nsjconf_t* nsjconf) {
|
void killAll(struct nsjconf_t* nsjconf) {
|
||||||
struct pids_t* p;
|
for (const auto& p : nsjconf->pids) {
|
||||||
TAILQ_FOREACH(p, &nsjconf->pids, pointers) { kill(p->pid, SIGKILL); }
|
kill(p.pid, SIGKILL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool initParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd) {
|
static bool initParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd) {
|
||||||
|
Loading…
Reference in New Issue
Block a user