Init cgroups from parent

This commit is contained in:
Jagger 2016-06-19 15:50:25 +02:00
parent c93d926189
commit 827e1a4e7d
6 changed files with 47 additions and 37 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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) {

View File

@ -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;