diff --git a/Makefile b/Makefile index 2f30677..8c20fe9 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 = caps.c log.c cgroup.c mount.c pid.c user.c util.c uts.c -SRCS_CXX = cmdline.cc config.cc contain.cc cpu.cc net.cc nsjail.cc sandbox.cc subproc.cc +SRCS_C = log.c cgroup.c mount.c pid.c user.c util.c uts.c +SRCS_CXX = caps.cc cmdline.cc config.cc contain.cc cpu.cc net.cc nsjail.cc sandbox.cc subproc.cc SRCS_PROTO = config.proto SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc) SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h) @@ -97,7 +97,6 @@ indent: # DO NOT DELETE THIS LINE -- make depend depends on it. -caps.o: caps.h nsjail.h common.h log.h util.h 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 @@ -105,12 +104,13 @@ pid.o: pid.h nsjail.h log.h subproc.h user.o: user.h nsjail.h common.h log.h subproc.h util.h util.o: util.h nsjail.h common.h log.h uts.o: uts.h nsjail.h log.h -cmdline.o: cmdline.h nsjail.h caps.h common.h log.h mount.h user.h util.h +caps.o: caps.h nsjail.h common.h log.h util.h +cmdline.o: cmdline.h nsjail.h common.h log.h mount.h user.h util.h caps.h cmdline.o: config.h sandbox.h -config.o: common.h caps.h nsjail.h config.h log.h mount.h user.h util.h +config.o: common.h config.h nsjail.h log.h mount.h user.h util.h caps.h config.o: cmdline.h -contain.o: contain.h nsjail.h caps.h cgroup.h log.h mount.h pid.h user.h -contain.o: uts.h cpu.h net.h +contain.o: contain.h nsjail.h cgroup.h log.h mount.h pid.h user.h uts.h +contain.o: caps.h cpu.h net.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 diff --git a/caps.c b/caps.cc similarity index 82% rename from caps.c rename to caps.cc index b1d02d3..563e624 100644 --- a/caps.c +++ b/caps.cc @@ -28,9 +28,13 @@ #include #include +extern "C" { #include "common.h" #include "log.h" #include "util.h" +} + +namespace caps { static struct { const int val; @@ -78,7 +82,7 @@ static struct { #endif /* defined(CAP_AUDIT_READ) */ }; -int capsNameToVal(const char* name) { +int nameToVal(const char* name) { for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { if (strcmp(name, capNames[i].name) == 0) { return capNames[i].val; @@ -88,7 +92,7 @@ int capsNameToVal(const char* name) { return -1; } -static const char* capsValToStr(int val) { +static const char* valToStr(int val) { static __thread char capsStr[1024]; for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { if (val == capNames[i].val) { @@ -101,7 +105,7 @@ static const char* capsValToStr(int val) { return capsStr; } -static cap_user_data_t capsGet() { +static cap_user_data_t getCaps() { static __thread struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3]; const struct __user_cap_header_struct cap_hdr = { .version = _LINUX_CAPABILITY_VERSION_3, @@ -114,7 +118,7 @@ static cap_user_data_t capsGet() { return cap_data; } -static bool capsSet(const cap_user_data_t cap_data) { +static bool setCaps(const cap_user_data_t cap_data) { const struct __user_cap_header_struct cap_hdr = { .version = _LINUX_CAPABILITY_VERSION_3, .pid = 0, @@ -126,31 +130,31 @@ static bool capsSet(const cap_user_data_t cap_data) { return true; } -static void capsClearInheritable(cap_user_data_t cap_data) { +static void clearInheritable(cap_user_data_t cap_data) { for (size_t i = 0; i < _LINUX_CAPABILITY_U32S_3; i++) { cap_data[i].inheritable = 0U; } } -static bool capsGetPermitted(cap_user_data_t cap_data, unsigned int cap) { +static bool getPermitted(cap_user_data_t cap_data, unsigned int cap) { size_t off_byte = cap / (sizeof(cap_data->permitted) * 8); size_t off_bit = cap % (sizeof(cap_data->permitted) * 8); return cap_data[off_byte].permitted & (1U << off_bit); } -static bool capsGetEffective(cap_user_data_t cap_data, unsigned int cap) { +static bool getEffective(cap_user_data_t cap_data, unsigned int cap) { size_t off_byte = cap / (sizeof(cap_data->effective) * 8); size_t off_bit = cap % (sizeof(cap_data->effective) * 8); return cap_data[off_byte].effective & (1U << off_bit); } -static bool capsGetInheritable(cap_user_data_t cap_data, unsigned int cap) { +static bool getInheritable(cap_user_data_t cap_data, unsigned int cap) { size_t off_byte = cap / (sizeof(cap_data->inheritable) * 8); size_t off_bit = cap % (sizeof(cap_data->inheritable) * 8); return cap_data[off_byte].inheritable & (1U << off_bit); } -static void capsSetInheritable(cap_user_data_t cap_data, unsigned int cap) { +static void setInheritable(cap_user_data_t cap_data, unsigned int cap) { size_t off_byte = cap / (sizeof(cap_data->inheritable) * 8); size_t off_bit = cap % (sizeof(cap_data->inheritable) * 8); cap_data[off_byte].inheritable |= (1U << off_bit); @@ -161,27 +165,27 @@ static void capsSetInheritable(cap_user_data_t cap_data, unsigned int cap) { #define PR_CAP_AMBIENT_RAISE 2 #define PR_CAP_AMBIENT_CLEAR_ALL 4 #endif /* !defined(PR_CAP_AMBIENT) */ -static bool CapsInitNsKeepCaps(cap_user_data_t cap_data) { +static bool initNsKeepCaps(cap_user_data_t cap_data) { char dbgmsg[4096]; /* Copy all permitted caps to the inheritable set */ dbgmsg[0] = '\0'; for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (capsGetPermitted(cap_data, capNames[i].val)) { + if (getPermitted(cap_data, capNames[i].val)) { utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); - capsSetInheritable(cap_data, capNames[i].val); + setInheritable(cap_data, capNames[i].val); } } LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); - if (capsSet(cap_data) == false) { + if (setCaps(cap_data) == false) { return false; } /* Make sure the inheritable set is preserved across execve via the ambient set */ dbgmsg[0] = '\0'; for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (capsGetPermitted(cap_data, capNames[i].val) == false) { + if (getPermitted(cap_data, capNames[i].val) == false) { continue; } if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)capNames[i].val, 0UL, @@ -196,17 +200,17 @@ static bool CapsInitNsKeepCaps(cap_user_data_t cap_data) { return true; } -bool capsInitNs(struct nsjconf_t* nsjconf) { +bool initNs(struct nsjconf_t* nsjconf) { char dbgmsg[4096]; struct ints_t* p; - cap_user_data_t cap_data = capsGet(); + cap_user_data_t cap_data = getCaps(); if (cap_data == NULL) { return false; } /* Let's start with an empty inheritable set to avoid any mistakes */ - capsClearInheritable(cap_data); + clearInheritable(cap_data); /* * Remove all capabilities from the ambient set first. It works with newer kernel versions * only, so don't panic() if it fails @@ -216,24 +220,23 @@ bool capsInitNs(struct nsjconf_t* nsjconf) { } if (nsjconf->keep_caps) { - return CapsInitNsKeepCaps(cap_data); + return initNsKeepCaps(cap_data); } /* Set all requested caps in the inheritable set if these are present in the permitted set */ dbgmsg[0] = '\0'; TAILQ_FOREACH(p, &nsjconf->caps, pointers) { - if (capsGetPermitted(cap_data, p->val) == false) { - LOG_W("Capability %s is not permitted in the namespace", - capsValToStr(p->val)); + if (getPermitted(cap_data, p->val) == false) { + LOG_W("Capability %s is not permitted in the namespace", valToStr(p->val)); return false; } - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val)); - capsSetInheritable(cap_data, p->val); + utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", valToStr(p->val)); + setInheritable(cap_data, p->val); } LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); - if (capsSet(cap_data) == false) { + if (setCaps(cap_data) == false) { return false; } @@ -241,10 +244,10 @@ bool capsInitNs(struct nsjconf_t* nsjconf) { * Make sure all other caps (those which were not explicitly requested) are removed from the * bounding set. We need to have CAP_SETPCAP to do that now */ - if (capsGetEffective(cap_data, CAP_SETPCAP)) { + if (getEffective(cap_data, CAP_SETPCAP)) { dbgmsg[0] = '\0'; for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (capsGetInheritable(cap_data, capNames[i].val)) { + if (getInheritable(cap_data, capNames[i].val)) { continue; } utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); @@ -262,13 +265,14 @@ bool capsInitNs(struct nsjconf_t* nsjconf) { TAILQ_FOREACH(p, &nsjconf->caps, pointers) { if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)p->val, 0UL, 0UL) == -1) { - PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", - capsValToStr(p->val)); + PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", valToStr(p->val)); } else { - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val)); + utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", valToStr(p->val)); } } LOG_D("Added the following capabilities to the ambient set:%s", dbgmsg); return true; } + +} // namespace caps diff --git a/caps.h b/caps.h index f2ccf88..dd72d55 100644 --- a/caps.h +++ b/caps.h @@ -27,7 +27,11 @@ #include "nsjail.h" -int capsNameToVal(const char* name); -bool capsInitNs(struct nsjconf_t* nsjconf); +namespace caps { + +int nameToVal(const char* name); +bool initNs(struct nsjconf_t* nsjconf); + +} // namespace caps #endif /* NS_CAPS_H */ diff --git a/cmdline.cc b/cmdline.cc index 2fe4964..4d535a7 100644 --- a/cmdline.cc +++ b/cmdline.cc @@ -45,7 +45,6 @@ #include extern "C" { -#include "caps.h" #include "common.h" #include "log.h" #include "mount.h" @@ -53,6 +52,7 @@ extern "C" { #include "util.h" } +#include "caps.h" #include "config.h" #include "sandbox.h" @@ -585,7 +585,7 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { case 0x0509: { struct ints_t* f = reinterpret_cast(utilMalloc(sizeof(struct ints_t))); - f->val = capsNameToVal(optarg); + f->val = caps::nameToVal(optarg); if (f->val == -1) { return nullptr; } diff --git a/config.cc b/config.cc index 5d0d8d6..8f8ca47 100644 --- a/config.cc +++ b/config.cc @@ -30,7 +30,6 @@ extern "C" { #include #include -#include "caps.h" #include "config.h" #include "log.h" #include "mount.h" @@ -38,6 +37,7 @@ extern "C" { #include "util.h" } +#include "caps.h" #include "cmdline.h" #include @@ -142,7 +142,7 @@ static bool configParseInternal(struct nsjconf_t* nsjconf, const nsjail::NsJailC for (ssize_t i = 0; i < njc.cap_size(); i++) { struct ints_t* f = reinterpret_cast(utilMalloc(sizeof(struct ints_t))); - f->val = capsNameToVal(njc.cap(i).c_str()); + f->val = caps::nameToVal(njc.cap(i).c_str()); if (f->val == -1) { return false; } diff --git a/contain.cc b/contain.cc index 6ea3bdb..a0e085b 100644 --- a/contain.cc +++ b/contain.cc @@ -38,7 +38,6 @@ #include extern "C" { -#include "caps.h" #include "cgroup.h" #include "log.h" #include "mount.h" @@ -47,6 +46,7 @@ extern "C" { #include "uts.h" } +#include "caps.h" #include "cpu.h" #include "net.h" @@ -73,7 +73,7 @@ static bool containDropPrivs(struct nsjconf_t* nsjconf) { } } - if (capsInitNs(nsjconf) == false) { + if (caps::initNs(nsjconf) == false) { return false; }