From: Robert Swiecki Date: Fri, 9 Feb 2018 17:13:17 +0000 (+0100) Subject: cgroup: move to C++ X-Git-Tag: 2.5~60 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=15170f9d6c04dcdbf6f7bde0807ea7c20d2c7b57;p=platform%2Fupstream%2Fnsjail.git cgroup: move to C++ --- diff --git a/Makefile b/Makefile index b77356b..eea405e 100644 --- a/Makefile +++ b/Makefile @@ -35,8 +35,8 @@ LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs protobuf) BIN = nsjail LIBS = kafel/libkafel.a -SRCS_C = log.c cgroup.c mount.c user.c util.c -SRCS_CXX = caps.cc cmdline.cc config.cc contain.cc cpu.cc net.cc nsjail.cc pid.cc sandbox.cc subproc.cc uts.cc +SRCS_C = log.c mount.c util.c +SRCS_CXX = caps.cc cgroup.cc cmdline.cc config.cc contain.cc cpu.cc net.cc nsjail.cc pid.cc sandbox.cc subproc.cc uts.cc user.cc SRCS_PROTO = config.proto SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc) SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h) @@ -98,21 +98,22 @@ indent: # DO NOT DELETE THIS LINE -- make depend depends on it. log.o: log.h nsjail.h -cgroup.o: cgroup.h nsjail.h log.h util.h mount.o: mount.h nsjail.h common.h log.h subproc.h util.h util.o: util.h nsjail.h common.h log.h caps.o: caps.h nsjail.h common.h log.h util.h +cgroup.o: cgroup.h nsjail.h log.h util.h cmdline.o: cmdline.h nsjail.h common.h log.h mount.h util.h caps.h config.h cmdline.o: sandbox.h user.h config.o: common.h config.h nsjail.h log.h mount.h util.h caps.h cmdline.h config.o: user.h -contain.o: contain.h nsjail.h cgroup.h log.h mount.h caps.h cpu.h net.h pid.h +contain.o: contain.h nsjail.h log.h mount.h caps.h cgroup.h cpu.h net.h pid.h contain.o: user.h uts.h cpu.o: cpu.h nsjail.h log.h util.h net.o: net.h nsjail.h log.h subproc.h nsjail.o: nsjail.h cmdline.h common.h log.h net.h subproc.h util.h pid.o: pid.h nsjail.h log.h subproc.h sandbox.o: sandbox.h nsjail.h kafel/include/kafel.h log.h -subproc.o: subproc.h nsjail.h contain.h net.h sandbox.h user.h cgroup.h +subproc.o: subproc.h nsjail.h cgroup.h contain.h net.h sandbox.h user.h subproc.o: common.h log.h util.h uts.o: uts.h nsjail.h log.h +user.o: user.h nsjail.h common.h log.h util.h subproc.h diff --git a/cgroup.c b/cgroup.c deleted file mode 100644 index 8ffd25a..0000000 --- a/cgroup.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - - nsjail - cgroup namespacing - ----------------------------------------- - - Copyright 2014 Google Inc. All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -#include "cgroup.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "util.h" - -static bool cgroupInitNsFromParentMem(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_mem_max == (size_t)0) { - return true; - } - - 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("Create '%s' for PID=%d", mem_cgroup_path, (int)pid); - if (mkdir(mem_cgroup_path, 0700) == -1 && errno != EEXIST) { - PLOG_E("mkdir('%s', 0700) failed", mem_cgroup_path); - return false; - } - - char fname[PATH_MAX]; - 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' to '%s'", fname, mem_max_str); - if (!utilWriteBufToFile(fname, mem_max_str, strlen(mem_max_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update memory cgroup max limit"); - return false; - } - - /* - * Use OOM-killer instead of making processes hang/sleep - */ - snprintf(fname, sizeof(fname), "%s/memory.oom_control", mem_cgroup_path); - LOG_D("Writting '0' '%s'", fname); - if (!utilWriteBufToFile(fname, "0", strlen("0"), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update memory cgroup oom control"); - return false; - } - - char pid_str[512]; - 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'", pid_str, fname); - if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update memory cgroup task list"); - return false; - } - - return true; -} - -static bool cgroupInitNsFromParentPids(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_pids_max == 0U) { - return true; - } - - char pids_cgroup_path[PATH_MAX]; - snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid); - LOG_D("Create '%s' for PID=%d", pids_cgroup_path, (int)pid); - if (mkdir(pids_cgroup_path, 0700) == -1 && errno != EEXIST) { - PLOG_E("mkdir('%s', 0700) failed", pids_cgroup_path); - return false; - } - - char fname[PATH_MAX]; - char pids_max_str[512]; - snprintf(pids_max_str, sizeof(pids_max_str), "%u", nsjconf->cgroup_pids_max); - snprintf(fname, sizeof(fname), "%s/pids.max", pids_cgroup_path); - LOG_D("Setting '%s' to '%s'", fname, pids_max_str); - if (!utilWriteBufToFile(fname, pids_max_str, strlen(pids_max_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update pids cgroup max limit"); - return false; - } - - char pid_str[512]; - snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); - snprintf(fname, sizeof(fname), "%s/tasks", pids_cgroup_path); - LOG_D("Adding PID='%s' to '%s'", pid_str, fname); - if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update pids cgroup task list"); - return false; - } - - return true; -} - -static bool cgroupInitNsFromParentNetCls(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_net_cls_classid == 0U) { - return true; - } - - char net_cls_cgroup_path[PATH_MAX]; - snprintf(net_cls_cgroup_path, sizeof(net_cls_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_net_cls_mount, nsjconf->cgroup_net_cls_parent, (int)pid); - LOG_D("Create '%s' for PID=%d", net_cls_cgroup_path, (int)pid); - if (mkdir(net_cls_cgroup_path, 0700) == -1 && errno != EEXIST) { - PLOG_E("mkdir('%s', 0700) failed", net_cls_cgroup_path); - return false; - } - - char fname[PATH_MAX]; - char net_cls_classid_str[512]; - snprintf(net_cls_classid_str, sizeof(net_cls_classid_str), "0x%x", - nsjconf->cgroup_net_cls_classid); - snprintf(fname, sizeof(fname), "%s/net_cls.classid", net_cls_cgroup_path); - LOG_D("Setting '%s' to '%s'", fname, net_cls_classid_str); - if (!utilWriteBufToFile( - fname, net_cls_classid_str, strlen(net_cls_classid_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update net_cls cgroup classid"); - return false; - } - - char pid_str[512]; - snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); - snprintf(fname, sizeof(fname), "%s/tasks", net_cls_cgroup_path); - LOG_D("Adding PID='%s' to '%s'", pid_str, fname); - if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update net_cls cgroup task list"); - return false; - } - - return true; -} - -static bool cgroupInitNsFromParentCpu(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_cpu_ms_per_sec == 0U) { - return true; - } - - char cpu_cgroup_path[PATH_MAX]; - snprintf(cpu_cgroup_path, sizeof(cpu_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_cpu_mount, nsjconf->cgroup_cpu_parent, (int)pid); - LOG_D("Create '%s' for PID=%d", cpu_cgroup_path, (int)pid); - if (mkdir(cpu_cgroup_path, 0700) == -1 && errno != EEXIST) { - PLOG_E("mkdir('%s', 0700) failed", cpu_cgroup_path); - return false; - } - - char fname[PATH_MAX]; - char cpu_ms_per_sec_str[512]; - snprintf(cpu_ms_per_sec_str, sizeof(cpu_ms_per_sec_str), "%u", - nsjconf->cgroup_cpu_ms_per_sec * 1000U); - snprintf(fname, sizeof(fname), "%s/cpu.cfs_quota_us", cpu_cgroup_path); - LOG_D("Setting '%s' to '%s'", fname, cpu_ms_per_sec_str); - if (!utilWriteBufToFile( - fname, cpu_ms_per_sec_str, strlen(cpu_ms_per_sec_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update cpu quota"); - return false; - } - - const char cpu_period_us[] = "1000000"; - snprintf(fname, sizeof(fname), "%s/cpu.cfs_period_us", cpu_cgroup_path); - LOG_D("Setting '%s' to '%s'", fname, cpu_period_us); - if (!utilWriteBufToFile( - fname, cpu_period_us, strlen(cpu_period_us), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update cpu period"); - return false; - } - - char pid_str[512]; - snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); - snprintf(fname, sizeof(fname), "%s/tasks", cpu_cgroup_path); - LOG_D("Adding PID='%s' to '%s'", pid_str, fname); - if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { - LOG_E("Could not update cpu cgroup task list"); - return false; - } - - return true; -} - -bool cgroupInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) { - if (!cgroupInitNsFromParentMem(nsjconf, pid)) { - return false; - } - if (!cgroupInitNsFromParentPids(nsjconf, pid)) { - return false; - } - if (!cgroupInitNsFromParentNetCls(nsjconf, pid)) { - return false; - } - if (!cgroupInitNsFromParentCpu(nsjconf, pid)) { - return false; - } - return true; -} - -void cgroupFinishFromParentMem(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_mem_max == (size_t)0) { - 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; -} - -void cgroupFinishFromParentPids(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_pids_max == 0U) { - return; - } - char pids_cgroup_path[PATH_MAX]; - snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid); - LOG_D("Remove '%s'", pids_cgroup_path); - if (rmdir(pids_cgroup_path) == -1) { - PLOG_W("rmdir('%s') failed", pids_cgroup_path); - } - return; -} - -void cgroupFinishFromParentCpu(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_cpu_ms_per_sec == 0U) { - return; - } - char cpu_cgroup_path[PATH_MAX]; - snprintf(cpu_cgroup_path, sizeof(cpu_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_cpu_mount, nsjconf->cgroup_cpu_parent, (int)pid); - LOG_D("Remove '%s'", cpu_cgroup_path); - if (rmdir(cpu_cgroup_path) == -1) { - PLOG_W("rmdir('%s') failed", cpu_cgroup_path); - } - return; -} - -void cgroupFinishFromParentNetCls(struct nsjconf_t* nsjconf, pid_t pid) { - if (nsjconf->cgroup_net_cls_classid == 0U) { - return; - } - char net_cls_cgroup_path[PATH_MAX]; - snprintf(net_cls_cgroup_path, sizeof(net_cls_cgroup_path), "%s/%s/NSJAIL.%d", - nsjconf->cgroup_net_cls_mount, nsjconf->cgroup_net_cls_parent, (int)pid); - LOG_D("Remove '%s'", net_cls_cgroup_path); - if (rmdir(net_cls_cgroup_path) == -1) { - PLOG_W("rmdir('%s') failed", net_cls_cgroup_path); - } - return; -} - -void cgroupFinishFromParent(struct nsjconf_t* nsjconf, pid_t pid) { - cgroupFinishFromParentMem(nsjconf, pid); - cgroupFinishFromParentPids(nsjconf, pid); - cgroupFinishFromParentNetCls(nsjconf, pid); - cgroupFinishFromParentCpu(nsjconf, pid); -} - -bool cgroupInitNs(void) { return true; } diff --git a/cgroup.cc b/cgroup.cc new file mode 100644 index 0000000..618b4cc --- /dev/null +++ b/cgroup.cc @@ -0,0 +1,288 @@ +/* + + nsjail - cgroup namespacing + ----------------------------------------- + + Copyright 2014 Google Inc. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +#include "cgroup.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "log.h" +#include "util.h" +} + +namespace cgroup { + +static bool initNsFromParentMem(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_mem_max == (size_t)0) { + return true; + } + + 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("Create '%s' for PID=%d", mem_cgroup_path, (int)pid); + if (mkdir(mem_cgroup_path, 0700) == -1 && errno != EEXIST) { + PLOG_E("mkdir('%s', 0700) failed", mem_cgroup_path); + return false; + } + + char fname[PATH_MAX]; + 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' to '%s'", fname, mem_max_str); + if (!utilWriteBufToFile(fname, mem_max_str, strlen(mem_max_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update memory cgroup max limit"); + return false; + } + + /* + * Use OOM-killer instead of making processes hang/sleep + */ + snprintf(fname, sizeof(fname), "%s/memory.oom_control", mem_cgroup_path); + LOG_D("Writting '0' '%s'", fname); + if (!utilWriteBufToFile(fname, "0", strlen("0"), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update memory cgroup oom control"); + return false; + } + + char pid_str[512]; + 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'", pid_str, fname); + if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update memory cgroup task list"); + return false; + } + + return true; +} + +static bool initNsFromParentPids(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_pids_max == 0U) { + return true; + } + + char pids_cgroup_path[PATH_MAX]; + snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid); + LOG_D("Create '%s' for PID=%d", pids_cgroup_path, (int)pid); + if (mkdir(pids_cgroup_path, 0700) == -1 && errno != EEXIST) { + PLOG_E("mkdir('%s', 0700) failed", pids_cgroup_path); + return false; + } + + char fname[PATH_MAX]; + char pids_max_str[512]; + snprintf(pids_max_str, sizeof(pids_max_str), "%u", nsjconf->cgroup_pids_max); + snprintf(fname, sizeof(fname), "%s/pids.max", pids_cgroup_path); + LOG_D("Setting '%s' to '%s'", fname, pids_max_str); + if (!utilWriteBufToFile(fname, pids_max_str, strlen(pids_max_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update pids cgroup max limit"); + return false; + } + + char pid_str[512]; + snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); + snprintf(fname, sizeof(fname), "%s/tasks", pids_cgroup_path); + LOG_D("Adding PID='%s' to '%s'", pid_str, fname); + if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update pids cgroup task list"); + return false; + } + + return true; +} + +static bool initNsFromParentNetCls(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_net_cls_classid == 0U) { + return true; + } + + char net_cls_cgroup_path[PATH_MAX]; + snprintf(net_cls_cgroup_path, sizeof(net_cls_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_net_cls_mount, nsjconf->cgroup_net_cls_parent, (int)pid); + LOG_D("Create '%s' for PID=%d", net_cls_cgroup_path, (int)pid); + if (mkdir(net_cls_cgroup_path, 0700) == -1 && errno != EEXIST) { + PLOG_E("mkdir('%s', 0700) failed", net_cls_cgroup_path); + return false; + } + + char fname[PATH_MAX]; + char net_cls_classid_str[512]; + snprintf(net_cls_classid_str, sizeof(net_cls_classid_str), "0x%x", + nsjconf->cgroup_net_cls_classid); + snprintf(fname, sizeof(fname), "%s/net_cls.classid", net_cls_cgroup_path); + LOG_D("Setting '%s' to '%s'", fname, net_cls_classid_str); + if (!utilWriteBufToFile( + fname, net_cls_classid_str, strlen(net_cls_classid_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update net_cls cgroup classid"); + return false; + } + + char pid_str[512]; + snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); + snprintf(fname, sizeof(fname), "%s/tasks", net_cls_cgroup_path); + LOG_D("Adding PID='%s' to '%s'", pid_str, fname); + if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update net_cls cgroup task list"); + return false; + } + + return true; +} + +static bool initNsFromParentCpu(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_cpu_ms_per_sec == 0U) { + return true; + } + + char cpu_cgroup_path[PATH_MAX]; + snprintf(cpu_cgroup_path, sizeof(cpu_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_cpu_mount, nsjconf->cgroup_cpu_parent, (int)pid); + LOG_D("Create '%s' for PID=%d", cpu_cgroup_path, (int)pid); + if (mkdir(cpu_cgroup_path, 0700) == -1 && errno != EEXIST) { + PLOG_E("mkdir('%s', 0700) failed", cpu_cgroup_path); + return false; + } + + char fname[PATH_MAX]; + char cpu_ms_per_sec_str[512]; + snprintf(cpu_ms_per_sec_str, sizeof(cpu_ms_per_sec_str), "%u", + nsjconf->cgroup_cpu_ms_per_sec * 1000U); + snprintf(fname, sizeof(fname), "%s/cpu.cfs_quota_us", cpu_cgroup_path); + LOG_D("Setting '%s' to '%s'", fname, cpu_ms_per_sec_str); + if (!utilWriteBufToFile( + fname, cpu_ms_per_sec_str, strlen(cpu_ms_per_sec_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update cpu quota"); + return false; + } + + const char cpu_period_us[] = "1000000"; + snprintf(fname, sizeof(fname), "%s/cpu.cfs_period_us", cpu_cgroup_path); + LOG_D("Setting '%s' to '%s'", fname, cpu_period_us); + if (!utilWriteBufToFile( + fname, cpu_period_us, strlen(cpu_period_us), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update cpu period"); + return false; + } + + char pid_str[512]; + snprintf(pid_str, sizeof(pid_str), "%d", (int)pid); + snprintf(fname, sizeof(fname), "%s/tasks", cpu_cgroup_path); + LOG_D("Adding PID='%s' to '%s'", pid_str, fname); + if (!utilWriteBufToFile(fname, pid_str, strlen(pid_str), O_WRONLY | O_CLOEXEC)) { + LOG_E("Could not update cpu cgroup task list"); + return false; + } + + return true; +} + +bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) { + if (!initNsFromParentMem(nsjconf, pid)) { + return false; + } + if (!initNsFromParentPids(nsjconf, pid)) { + return false; + } + if (!initNsFromParentNetCls(nsjconf, pid)) { + return false; + } + if (!initNsFromParentCpu(nsjconf, pid)) { + return false; + } + return true; +} + +void finishFromParentMem(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_mem_max == (size_t)0) { + 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; +} + +void finishFromParentPids(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_pids_max == 0U) { + return; + } + char pids_cgroup_path[PATH_MAX]; + snprintf(pids_cgroup_path, sizeof(pids_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_pids_mount, nsjconf->cgroup_pids_parent, (int)pid); + LOG_D("Remove '%s'", pids_cgroup_path); + if (rmdir(pids_cgroup_path) == -1) { + PLOG_W("rmdir('%s') failed", pids_cgroup_path); + } + return; +} + +void finishFromParentCpu(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_cpu_ms_per_sec == 0U) { + return; + } + char cpu_cgroup_path[PATH_MAX]; + snprintf(cpu_cgroup_path, sizeof(cpu_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_cpu_mount, nsjconf->cgroup_cpu_parent, (int)pid); + LOG_D("Remove '%s'", cpu_cgroup_path); + if (rmdir(cpu_cgroup_path) == -1) { + PLOG_W("rmdir('%s') failed", cpu_cgroup_path); + } + return; +} + +void finishFromParentNetCls(struct nsjconf_t* nsjconf, pid_t pid) { + if (nsjconf->cgroup_net_cls_classid == 0U) { + return; + } + char net_cls_cgroup_path[PATH_MAX]; + snprintf(net_cls_cgroup_path, sizeof(net_cls_cgroup_path), "%s/%s/NSJAIL.%d", + nsjconf->cgroup_net_cls_mount, nsjconf->cgroup_net_cls_parent, (int)pid); + LOG_D("Remove '%s'", net_cls_cgroup_path); + if (rmdir(net_cls_cgroup_path) == -1) { + PLOG_W("rmdir('%s') failed", net_cls_cgroup_path); + } + return; +} + +void finishFromParent(struct nsjconf_t* nsjconf, pid_t pid) { + finishFromParentMem(nsjconf, pid); + finishFromParentPids(nsjconf, pid); + finishFromParentNetCls(nsjconf, pid); + finishFromParentCpu(nsjconf, pid); +} + +bool initNs(void) { return true; } + +} // namespace cgroup diff --git a/cgroup.h b/cgroup.h index c34cd24..677ce36 100644 --- a/cgroup.h +++ b/cgroup.h @@ -27,8 +27,12 @@ #include "nsjail.h" -bool cgroupInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid); -bool cgroupInitNs(void); -void cgroupFinishFromParent(struct nsjconf_t* nsjconf, pid_t pid); +namespace cgroup { + +bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid); +bool initNs(void); +void finishFromParent(struct nsjconf_t* nsjconf, pid_t pid); + +} // namespace cgroup #endif /* _CGROUP_H */ diff --git a/contain.cc b/contain.cc index 61f47e7..42a0bda 100644 --- a/contain.cc +++ b/contain.cc @@ -38,12 +38,12 @@ #include extern "C" { -#include "cgroup.h" #include "log.h" #include "mount.h" } #include "caps.h" +#include "cgroup.h" #include "cpu.h" #include "net.h" #include "pid.h" @@ -60,7 +60,7 @@ static bool containInitNetNs(struct nsjconf_t* nsjconf) { return net::initNsFrom static bool containInitUtsNs(struct nsjconf_t* nsjconf) { return uts::initNs(nsjconf); } -static bool containInitCgroupNs(void) { return cgroupInitNs(); } +static bool containInitCgroupNs(void) { return cgroup::initNs(); } static bool containDropPrivs(struct nsjconf_t* nsjconf) { #ifndef PR_SET_NO_NEW_PRIVS diff --git a/subproc.cc b/subproc.cc index 7e91bf3..6cce1b6 100644 --- a/subproc.cc +++ b/subproc.cc @@ -42,13 +42,13 @@ #include #include +#include "cgroup.h" #include "contain.h" #include "net.h" #include "sandbox.h" #include "user.h" extern "C" { -#include "cgroup.h" #include "common.h" #include "log.h" #include "util.h" @@ -148,7 +148,7 @@ static int subprocNewProc( LOG_E("Couldn't initialize net user namespace"); _exit(0xff); } - if (cgroupInitNsFromParent(nsjconf, getpid()) == false) { + if (cgroup::initNsFromParent(nsjconf, getpid()) == false) { LOG_E("Couldn't initialize net user namespace"); _exit(0xff); } @@ -317,7 +317,7 @@ int reapProc(struct nsjconf_t* nsjconf) { } if (wait4(si.si_pid, &status, WNOHANG, NULL) == si.si_pid) { - cgroupFinishFromParent(nsjconf, si.si_pid); + cgroup::finishFromParent(nsjconf, si.si_pid); const char* remote_txt = "[UNKNOWN]"; struct pids_t* elem = getPidElem(nsjconf, si.si_pid); @@ -380,7 +380,7 @@ static bool initParent(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) { + if (cgroup::initNsFromParent(nsjconf, pid) == false) { LOG_E("Couldn't initialize cgroup user namespace"); exit(0xff); } diff --git a/user.cc b/user.cc index d10f2af..a4a44a7 100644 --- a/user.cc +++ b/user.cc @@ -349,8 +349,8 @@ static gid_t parseGid(const char* id) { return (gid_t)-1; } -bool parseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, - bool is_gid, bool is_newidmap) { +bool parseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, bool is_gid, + bool is_newidmap) { uid_t inside_id; uid_t outside_id;