From: Robert Swiecki Date: Fri, 9 Feb 2018 16:49:13 +0000 (+0100) Subject: caps: move to C++ X-Git-Tag: 2.5~64 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c4e57bf27e554597ca64d80a99c6ed0e450475dc;p=platform%2Fupstream%2Fnsjail.git caps: move to C++ --- 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.c deleted file mode 100644 index b1d02d3..0000000 --- a/caps.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - - nsjail - capability-related operations - ----------------------------------------- - - 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 "caps.h" - -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "log.h" -#include "util.h" - -static struct { - const int val; - const char* const name; -} const capNames[] = { - NS_VALSTR_STRUCT(CAP_CHOWN), - NS_VALSTR_STRUCT(CAP_DAC_OVERRIDE), - NS_VALSTR_STRUCT(CAP_DAC_READ_SEARCH), - NS_VALSTR_STRUCT(CAP_FOWNER), - NS_VALSTR_STRUCT(CAP_FSETID), - NS_VALSTR_STRUCT(CAP_KILL), - NS_VALSTR_STRUCT(CAP_SETGID), - NS_VALSTR_STRUCT(CAP_SETUID), - NS_VALSTR_STRUCT(CAP_SETPCAP), - NS_VALSTR_STRUCT(CAP_LINUX_IMMUTABLE), - NS_VALSTR_STRUCT(CAP_NET_BIND_SERVICE), - NS_VALSTR_STRUCT(CAP_NET_BROADCAST), - NS_VALSTR_STRUCT(CAP_NET_ADMIN), - NS_VALSTR_STRUCT(CAP_NET_RAW), - NS_VALSTR_STRUCT(CAP_IPC_LOCK), - NS_VALSTR_STRUCT(CAP_IPC_OWNER), - NS_VALSTR_STRUCT(CAP_SYS_MODULE), - NS_VALSTR_STRUCT(CAP_SYS_RAWIO), - NS_VALSTR_STRUCT(CAP_SYS_CHROOT), - NS_VALSTR_STRUCT(CAP_SYS_PTRACE), - NS_VALSTR_STRUCT(CAP_SYS_PACCT), - NS_VALSTR_STRUCT(CAP_SYS_ADMIN), - NS_VALSTR_STRUCT(CAP_SYS_BOOT), - NS_VALSTR_STRUCT(CAP_SYS_NICE), - NS_VALSTR_STRUCT(CAP_SYS_RESOURCE), - NS_VALSTR_STRUCT(CAP_SYS_TIME), - NS_VALSTR_STRUCT(CAP_SYS_TTY_CONFIG), - NS_VALSTR_STRUCT(CAP_MKNOD), - NS_VALSTR_STRUCT(CAP_LEASE), - NS_VALSTR_STRUCT(CAP_AUDIT_WRITE), - NS_VALSTR_STRUCT(CAP_AUDIT_CONTROL), - NS_VALSTR_STRUCT(CAP_SETFCAP), - NS_VALSTR_STRUCT(CAP_MAC_OVERRIDE), - NS_VALSTR_STRUCT(CAP_MAC_ADMIN), - NS_VALSTR_STRUCT(CAP_SYSLOG), - NS_VALSTR_STRUCT(CAP_WAKE_ALARM), - NS_VALSTR_STRUCT(CAP_BLOCK_SUSPEND), -#if defined(CAP_AUDIT_READ) - NS_VALSTR_STRUCT(CAP_AUDIT_READ), -#endif /* defined(CAP_AUDIT_READ) */ -}; - -int capsNameToVal(const char* name) { - for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (strcmp(name, capNames[i].name) == 0) { - return capNames[i].val; - } - } - LOG_W("Uknown capability: '%s'", name); - return -1; -} - -static const char* capsValToStr(int val) { - static __thread char capsStr[1024]; - for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (val == capNames[i].val) { - snprintf(capsStr, sizeof(capsStr), "%s", capNames[i].name); - return capsStr; - } - } - - snprintf(capsStr, sizeof(capsStr), "CAP_UNKNOWN(%d)", val); - return capsStr; -} - -static cap_user_data_t capsGet() { - 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, - .pid = 0, - }; - if (syscall(__NR_capget, &cap_hdr, &cap_data) == -1) { - PLOG_W("capget() failed"); - return NULL; - } - return cap_data; -} - -static bool capsSet(const cap_user_data_t cap_data) { - const struct __user_cap_header_struct cap_hdr = { - .version = _LINUX_CAPABILITY_VERSION_3, - .pid = 0, - }; - if (syscall(__NR_capset, &cap_hdr, cap_data) == -1) { - PLOG_W("capset() failed"); - return false; - } - return true; -} - -static void capsClearInheritable(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) { - 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) { - 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) { - 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) { - 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); -} - -#if !defined(PR_CAP_AMBIENT) -#define PR_CAP_AMBIENT 47 -#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) { - 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)) { - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); - capsSetInheritable(cap_data, capNames[i].val); - } - } - LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); - - if (capsSet(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) { - continue; - } - if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)capNames[i].val, 0UL, - 0UL) == -1) { - PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", capNames[i].name); - } else { - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); - } - } - LOG_D("Added the following capabilities to the ambient set:%s", dbgmsg); - - return true; -} - -bool capsInitNs(struct nsjconf_t* nsjconf) { - char dbgmsg[4096]; - struct ints_t* p; - - cap_user_data_t cap_data = capsGet(); - if (cap_data == NULL) { - return false; - } - - /* Let's start with an empty inheritable set to avoid any mistakes */ - capsClearInheritable(cap_data); - /* - * Remove all capabilities from the ambient set first. It works with newer kernel versions - * only, so don't panic() if it fails - */ - if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0UL, 0UL, 0UL) == -1) { - PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL)"); - } - - if (nsjconf->keep_caps) { - return CapsInitNsKeepCaps(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)); - return false; - } - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val)); - capsSetInheritable(cap_data, p->val); - } - LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); - - if (capsSet(cap_data) == false) { - return false; - } - - /* - * 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)) { - dbgmsg[0] = '\0'; - for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { - if (capsGetInheritable(cap_data, capNames[i].val)) { - continue; - } - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); - if (prctl(PR_CAPBSET_DROP, (unsigned long)capNames[i].val, 0UL, 0UL, 0UL) == - -1) { - PLOG_W("prctl(PR_CAPBSET_DROP, %s)", capNames[i].name); - return false; - } - } - LOG_D("Dropped the following capabilities from the bounding set:%s", dbgmsg); - } - - /* Make sure inheritable set is preserved across execve via the modified ambient set */ - dbgmsg[0] = '\0'; - 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)); - } else { - utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val)); - } - } - LOG_D("Added the following capabilities to the ambient set:%s", dbgmsg); - - return true; -} diff --git a/caps.cc b/caps.cc new file mode 100644 index 0000000..563e624 --- /dev/null +++ b/caps.cc @@ -0,0 +1,278 @@ +/* + + nsjail - capability-related operations + ----------------------------------------- + + 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 "caps.h" + +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "common.h" +#include "log.h" +#include "util.h" +} + +namespace caps { + +static struct { + const int val; + const char* const name; +} const capNames[] = { + NS_VALSTR_STRUCT(CAP_CHOWN), + NS_VALSTR_STRUCT(CAP_DAC_OVERRIDE), + NS_VALSTR_STRUCT(CAP_DAC_READ_SEARCH), + NS_VALSTR_STRUCT(CAP_FOWNER), + NS_VALSTR_STRUCT(CAP_FSETID), + NS_VALSTR_STRUCT(CAP_KILL), + NS_VALSTR_STRUCT(CAP_SETGID), + NS_VALSTR_STRUCT(CAP_SETUID), + NS_VALSTR_STRUCT(CAP_SETPCAP), + NS_VALSTR_STRUCT(CAP_LINUX_IMMUTABLE), + NS_VALSTR_STRUCT(CAP_NET_BIND_SERVICE), + NS_VALSTR_STRUCT(CAP_NET_BROADCAST), + NS_VALSTR_STRUCT(CAP_NET_ADMIN), + NS_VALSTR_STRUCT(CAP_NET_RAW), + NS_VALSTR_STRUCT(CAP_IPC_LOCK), + NS_VALSTR_STRUCT(CAP_IPC_OWNER), + NS_VALSTR_STRUCT(CAP_SYS_MODULE), + NS_VALSTR_STRUCT(CAP_SYS_RAWIO), + NS_VALSTR_STRUCT(CAP_SYS_CHROOT), + NS_VALSTR_STRUCT(CAP_SYS_PTRACE), + NS_VALSTR_STRUCT(CAP_SYS_PACCT), + NS_VALSTR_STRUCT(CAP_SYS_ADMIN), + NS_VALSTR_STRUCT(CAP_SYS_BOOT), + NS_VALSTR_STRUCT(CAP_SYS_NICE), + NS_VALSTR_STRUCT(CAP_SYS_RESOURCE), + NS_VALSTR_STRUCT(CAP_SYS_TIME), + NS_VALSTR_STRUCT(CAP_SYS_TTY_CONFIG), + NS_VALSTR_STRUCT(CAP_MKNOD), + NS_VALSTR_STRUCT(CAP_LEASE), + NS_VALSTR_STRUCT(CAP_AUDIT_WRITE), + NS_VALSTR_STRUCT(CAP_AUDIT_CONTROL), + NS_VALSTR_STRUCT(CAP_SETFCAP), + NS_VALSTR_STRUCT(CAP_MAC_OVERRIDE), + NS_VALSTR_STRUCT(CAP_MAC_ADMIN), + NS_VALSTR_STRUCT(CAP_SYSLOG), + NS_VALSTR_STRUCT(CAP_WAKE_ALARM), + NS_VALSTR_STRUCT(CAP_BLOCK_SUSPEND), +#if defined(CAP_AUDIT_READ) + NS_VALSTR_STRUCT(CAP_AUDIT_READ), +#endif /* defined(CAP_AUDIT_READ) */ +}; + +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; + } + } + LOG_W("Uknown capability: '%s'", name); + return -1; +} + +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) { + snprintf(capsStr, sizeof(capsStr), "%s", capNames[i].name); + return capsStr; + } + } + + snprintf(capsStr, sizeof(capsStr), "CAP_UNKNOWN(%d)", val); + return capsStr; +} + +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, + .pid = 0, + }; + if (syscall(__NR_capget, &cap_hdr, &cap_data) == -1) { + PLOG_W("capget() failed"); + return NULL; + } + return 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, + }; + if (syscall(__NR_capset, &cap_hdr, cap_data) == -1) { + PLOG_W("capset() failed"); + return false; + } + return true; +} + +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 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 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 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 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); +} + +#if !defined(PR_CAP_AMBIENT) +#define PR_CAP_AMBIENT 47 +#define PR_CAP_AMBIENT_RAISE 2 +#define PR_CAP_AMBIENT_CLEAR_ALL 4 +#endif /* !defined(PR_CAP_AMBIENT) */ +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 (getPermitted(cap_data, capNames[i].val)) { + utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); + setInheritable(cap_data, capNames[i].val); + } + } + LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); + + 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 (getPermitted(cap_data, capNames[i].val) == false) { + continue; + } + if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)capNames[i].val, 0UL, + 0UL) == -1) { + PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", capNames[i].name); + } else { + utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); + } + } + LOG_D("Added the following capabilities to the ambient set:%s", dbgmsg); + + return true; +} + +bool initNs(struct nsjconf_t* nsjconf) { + char dbgmsg[4096]; + struct ints_t* p; + + 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 */ + 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 + */ + if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0UL, 0UL, 0UL) == -1) { + PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL)"); + } + + if (nsjconf->keep_caps) { + 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 (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", valToStr(p->val)); + setInheritable(cap_data, p->val); + } + LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); + + if (setCaps(cap_data) == false) { + return false; + } + + /* + * 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 (getEffective(cap_data, CAP_SETPCAP)) { + dbgmsg[0] = '\0'; + for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { + if (getInheritable(cap_data, capNames[i].val)) { + continue; + } + utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name); + if (prctl(PR_CAPBSET_DROP, (unsigned long)capNames[i].val, 0UL, 0UL, 0UL) == + -1) { + PLOG_W("prctl(PR_CAPBSET_DROP, %s)", capNames[i].name); + return false; + } + } + LOG_D("Dropped the following capabilities from the bounding set:%s", dbgmsg); + } + + /* Make sure inheritable set is preserved across execve via the modified ambient set */ + dbgmsg[0] = '\0'; + 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)", valToStr(p->val)); + } else { + 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; }