Init cgroups from parent
This commit is contained in:
parent
c93d926189
commit
827e1a4e7d
3
Makefile
3
Makefile
@ -73,7 +73,8 @@ mount.o: mount.h common.h log.h
|
||||
net.o: net.h common.h log.h
|
||||
pid.o: pid.h common.h log.h
|
||||
sandbox.o: sandbox.h common.h log.h seccomp/bpf-helper.h
|
||||
subproc.o: subproc.h common.h contain.h log.h net.h sandbox.h user.h util.h
|
||||
subproc.o: subproc.h common.h cgroup.h contain.h log.h net.h sandbox.h user.h
|
||||
subproc.o: util.h
|
||||
user.o: user.h common.h log.h util.h
|
||||
util.o: util.h common.h log.h
|
||||
uts.o: uts.h common.h log.h
|
||||
|
50
cgroup.c
50
cgroup.c
@ -21,6 +21,7 @@
|
||||
|
||||
#include "cgroup.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -35,23 +36,17 @@
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
bool cgroupInitNs(struct nsjconf_t *nsjconf)
|
||||
bool cgroupInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid)
|
||||
{
|
||||
if (nsjconf->clone_newcgroup == false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) == -1) {
|
||||
PLOG_E("gettimeofday() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
char mem_cgroup_path[PATH_MAX];
|
||||
snprintf(mem_cgroup_path, sizeof(mem_cgroup_path), "%s/%s/NSJAIL.%lx.%lx",
|
||||
nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_parent, (unsigned long)tv.tv_sec,
|
||||
(unsigned long)tv.tv_usec);
|
||||
if (mkdir(mem_cgroup_path, 0700) == -1) {
|
||||
snprintf(mem_cgroup_path, sizeof(mem_cgroup_path), "%s/%s/NSJAIL.%d",
|
||||
nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_parent, (int)pid);
|
||||
LOG_D("Create '%s' for PID=%d", mem_cgroup_path, (int)pid);
|
||||
if (mkdir(mem_cgroup_path, 0700) == -1 && errno != EEXIST) {
|
||||
PLOG_E("mkdir('%s', 0711) failed", mem_cgroup_path);
|
||||
return false;
|
||||
}
|
||||
@ -61,7 +56,7 @@ bool cgroupInitNs(struct nsjconf_t *nsjconf)
|
||||
char mem_max_str[512];
|
||||
snprintf(mem_max_str, sizeof(mem_max_str), "%zu", nsjconf->cgroup_mem_max);
|
||||
snprintf(fname, sizeof(fname), "%s/memory.limit_in_bytes", mem_cgroup_path);
|
||||
LOG_D("Setting %s/memory.limit_in_bytes to '%s'", mem_cgroup_path, mem_max_str);
|
||||
LOG_D("Setting '%s/memory.limit_in_bytes' to '%s'", mem_cgroup_path, mem_max_str);
|
||||
if (utilWriteBufToFile(fname, mem_max_str, strlen(mem_max_str), O_WRONLY) == false) {
|
||||
LOG_E("Could not update memory cgroup max limit");
|
||||
return false;
|
||||
@ -69,19 +64,34 @@ bool cgroupInitNs(struct nsjconf_t *nsjconf)
|
||||
}
|
||||
|
||||
char pid_str[512];
|
||||
snprintf(pid_str, sizeof(pid_str), "%ld", syscall(__NR_getpid));
|
||||
snprintf(pid_str, sizeof(pid_str), "%d", (int)pid);
|
||||
snprintf(fname, sizeof(fname), "%s/tasks", mem_cgroup_path);
|
||||
LOG_D("Adding PID='%s' to %s/tasks", pid_str, mem_cgroup_path);
|
||||
LOG_D("Adding PID='%s' to '%s/tasks'", pid_str, mem_cgroup_path);
|
||||
if (utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY) == false) {
|
||||
LOG_E("Could not update memory cgroup task list");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_D("Unmounting '%s'", nsjconf->cgroup_mem_mount);
|
||||
if (umount2(nsjconf->cgroup_mem_mount, MNT_DETACH) == -1) {
|
||||
PLOG_E("Could not umount2('%s', MNT_DETACH)", nsjconf->cgroup_mem_mount);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid)
|
||||
{
|
||||
if (nsjconf->clone_newcgroup == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
char mem_cgroup_path[PATH_MAX];
|
||||
snprintf(mem_cgroup_path, sizeof(mem_cgroup_path), "%s/%s/NSJAIL.%d",
|
||||
nsjconf->cgroup_mem_mount, nsjconf->cgroup_mem_parent, (int)pid);
|
||||
LOG_D("Remove '%s'", mem_cgroup_path);
|
||||
if (rmdir(mem_cgroup_path) == -1) {
|
||||
PLOG_W("rmdir('%s') failed", mem_cgroup_path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool cgroupInitNs(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
4
cgroup.h
4
cgroup.h
@ -27,6 +27,8 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
bool cgroupInitNs(struct nsjconf_t * nsjconf);
|
||||
bool cgroupInitNsFromParent(struct nsjconf_t * nsjconf, pid_t pid);
|
||||
bool cgroupInitNs(void);
|
||||
void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid);
|
||||
|
||||
#endif /* _CGROUP_H */
|
||||
|
13
cmdline.c
13
cmdline.c
@ -291,7 +291,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
.max_conns_per_ip = 0,
|
||||
.tmpfs_size = 4 * (1024 * 1024),
|
||||
.mount_proc = true,
|
||||
.cgroup_mem_mount = "/cgroup_memory",
|
||||
.cgroup_mem_mount = "/sys/fs/cgroup/memory",
|
||||
.cgroup_mem_parent = "NSJAIL",
|
||||
.cgroup_mem_max = (size_t)0,
|
||||
.iface_no_lo = false,
|
||||
@ -376,7 +376,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
{{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax"},
|
||||
{{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
|
||||
{{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc in the jail"},
|
||||
{{"cgroup_mem_mount", required_argument, NULL, 0x0801}, "Where to mount memory cgroup FS (default: '/cgroup_memory'"},
|
||||
{{"cgroup_mem_mount", required_argument, NULL, 0x0801}, "Where to mount memory cgroup FS (default: '/sys/fs/cgroup/memory'"},
|
||||
{{"cgroup_mem_parent", required_argument, NULL, 0x0802}, "Which memory cgroup to use as parent (default: 'NSJAIL')"},
|
||||
{{"cgroup_mem_max", required_argument, NULL, 0x0803}, "Maximum number of bytes to use in the group"},
|
||||
{{"iface_no_lo", no_argument, NULL, 0x700}, "Don't bring up the 'lo' interface"},
|
||||
@ -630,15 +630,6 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
}
|
||||
}
|
||||
|
||||
if (nsjconf->clone_newcgroup) {
|
||||
struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
|
||||
p->src = NULL;
|
||||
p->dst = nsjconf->cgroup_mem_mount;
|
||||
p->flags = 0;
|
||||
p->options = "memory";
|
||||
p->fs_type = "cgroup";
|
||||
TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
|
||||
}
|
||||
if (nsjconf->mount_proc == true) {
|
||||
struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
|
||||
p->src = NULL;
|
||||
|
@ -65,9 +65,9 @@ static bool containInitUtsNs(struct nsjconf_t *nsjconf)
|
||||
return utsInitNs(nsjconf);
|
||||
}
|
||||
|
||||
static bool containInitCgroupNs(struct nsjconf_t *nsjconf)
|
||||
static bool containInitCgroupNs(void)
|
||||
{
|
||||
return cgroupInitNs(nsjconf);
|
||||
return cgroupInitNs();
|
||||
}
|
||||
|
||||
static bool containDropPrivs(struct nsjconf_t *nsjconf)
|
||||
@ -324,7 +324,7 @@ bool containContain(struct nsjconf_t * nsjconf)
|
||||
if (containInitUtsNs(nsjconf) == false) {
|
||||
return false;
|
||||
}
|
||||
if (containInitCgroupNs(nsjconf) == false) {
|
||||
if (containInitCgroupNs() == false) {
|
||||
return false;
|
||||
}
|
||||
if (containDropPrivs(nsjconf) == false) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "cgroup.h"
|
||||
#include "contain.h"
|
||||
#include "log.h"
|
||||
#include "net.h"
|
||||
@ -57,7 +58,7 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int
|
||||
|
||||
if (pipefd == -1) {
|
||||
if (userInitNsFromParent(nsjconf, syscall(__NR_getpid)) == false) {
|
||||
LOG_E("Couldn't initialize user namespaces");
|
||||
LOG_E("Couldn't initialize net user namespace");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
@ -227,6 +228,7 @@ int subprocReap(struct nsjconf_t *nsjconf)
|
||||
si.si_pid, WTERMSIG(status), subprocCount(nsjconf));
|
||||
rv = 100 + WTERMSIG(status);
|
||||
}
|
||||
cgroupFinishFromParent(nsjconf, si.si_pid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,6 +268,10 @@ static bool subprocInitParent(struct nsjconf_t *nsjconf, pid_t pid, int pipefd)
|
||||
LOG_E("Couldn't create and put MACVTAP interface into NS of PID '%d'", pid);
|
||||
return false;
|
||||
}
|
||||
if (cgroupInitNsFromParent(nsjconf, pid) == false) {
|
||||
LOG_E("Couldn't initialize cgroup user namespace");
|
||||
exit(1);
|
||||
}
|
||||
if (userInitNsFromParent(nsjconf, pid) == false) {
|
||||
LOG_E("Couldn't initialize user namespaces for pid %d", pid);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user