user: move to C++

This commit is contained in:
Robert Swiecki 2018-02-09 18:08:11 +01:00
parent 8e8fcc2815
commit 27a226ad28
7 changed files with 63 additions and 53 deletions

View File

@ -100,20 +100,19 @@ indent:
log.o: log.h nsjail.h log.o: log.h nsjail.h
cgroup.o: cgroup.h nsjail.h log.h util.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 mount.o: mount.h nsjail.h common.h log.h subproc.h util.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 util.o: util.h nsjail.h common.h log.h
caps.o: caps.h nsjail.h common.h log.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: cmdline.h nsjail.h common.h log.h mount.h util.h caps.h config.h
cmdline.o: config.h sandbox.h cmdline.o: sandbox.h user.h
config.o: common.h config.h nsjail.h log.h mount.h user.h util.h caps.h config.o: common.h config.h nsjail.h log.h mount.h util.h caps.h cmdline.h
config.o: cmdline.h config.o: user.h
contain.o: contain.h nsjail.h cgroup.h log.h mount.h user.h caps.h cpu.h contain.o: contain.h nsjail.h cgroup.h log.h mount.h caps.h cpu.h net.h pid.h
contain.o: net.h pid.h uts.h contain.o: user.h uts.h
cpu.o: cpu.h nsjail.h log.h util.h cpu.o: cpu.h nsjail.h log.h util.h
net.o: net.h nsjail.h log.h subproc.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 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 pid.o: pid.h nsjail.h log.h subproc.h
sandbox.o: sandbox.h nsjail.h kafel/include/kafel.h log.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 cgroup.h common.h subproc.o: subproc.h nsjail.h contain.h net.h sandbox.h user.h cgroup.h
subproc.o: log.h user.h util.h subproc.o: common.h log.h util.h
uts.o: uts.h nsjail.h log.h uts.o: uts.h nsjail.h log.h

View File

@ -48,13 +48,13 @@ extern "C" {
#include "common.h" #include "common.h"
#include "log.h" #include "log.h"
#include "mount.h" #include "mount.h"
#include "user.h"
#include "util.h" #include "util.h"
} }
#include "caps.h" #include "caps.h"
#include "config.h" #include "config.h"
#include "sandbox.h" #include "sandbox.h"
#include "user.h"
namespace cmdline { namespace cmdline {
@ -623,7 +623,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id); char* cnt = cmdlineSplitStrByColon(o_id);
size_t count = size_t count =
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0); (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
if (userParseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */, if (user::parseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
false /* is_newidmap */) == false) { false /* is_newidmap */) == false) {
return nullptr; return nullptr;
} }
@ -634,7 +634,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id); char* cnt = cmdlineSplitStrByColon(o_id);
size_t count = size_t count =
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0); (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
if (userParseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */, if (user::parseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
false /* is_newidmap */) == false) { false /* is_newidmap */) == false) {
return nullptr; return nullptr;
} }
@ -645,7 +645,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id); char* cnt = cmdlineSplitStrByColon(o_id);
size_t count = size_t count =
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0); (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
if (userParseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */, if (user::parseId(nsjconf.get(), i_id, o_id, count, false /* is_gid */,
true /* is_newidmap */) == false) { true /* is_newidmap */) == false) {
return nullptr; return nullptr;
} }
@ -656,7 +656,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id); char* cnt = cmdlineSplitStrByColon(o_id);
size_t count = size_t count =
(cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0); (cnt == NULL || strlen(cnt) == 0) ? 1U : (size_t)strtoull(cnt, NULL, 0);
if (userParseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */, if (user::parseId(nsjconf.get(), i_id, o_id, count, true /* is_gid */,
true /* is_newidmap */) == false) { true /* is_newidmap */) == false) {
return nullptr; return nullptr;
} }

View File

@ -33,12 +33,12 @@ extern "C" {
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "mount.h" #include "mount.h"
#include "user.h"
#include "util.h" #include "util.h"
} }
#include "caps.h" #include "caps.h"
#include "cmdline.h" #include "cmdline.h"
#include "user.h"
#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h> #include <google/protobuf/text_format.h>
@ -199,14 +199,14 @@ static bool configParseInternal(struct nsjconf_t* nsjconf, const nsjail::NsJailC
nsjconf->clone_newcgroup = njc.clone_newcgroup(); nsjconf->clone_newcgroup = njc.clone_newcgroup();
for (ssize_t i = 0; i < njc.uidmap_size(); i++) { for (ssize_t i = 0; i < njc.uidmap_size(); i++) {
if (userParseId(nsjconf, DUP_IF_SET(njc.uidmap(i), inside_id), if (user::parseId(nsjconf, DUP_IF_SET(njc.uidmap(i), inside_id),
DUP_IF_SET(njc.uidmap(i), outside_id), njc.uidmap(i).count(), DUP_IF_SET(njc.uidmap(i), outside_id), njc.uidmap(i).count(),
false /* is_gid */, njc.uidmap(i).use_newidmap()) == false) { false /* is_gid */, njc.uidmap(i).use_newidmap()) == false) {
return false; return false;
} }
} }
for (ssize_t i = 0; i < njc.gidmap_size(); i++) { for (ssize_t i = 0; i < njc.gidmap_size(); i++) {
if (userParseId(nsjconf, DUP_IF_SET(njc.gidmap(i), inside_id), if (user::parseId(nsjconf, DUP_IF_SET(njc.gidmap(i), inside_id),
DUP_IF_SET(njc.gidmap(i), outside_id), njc.gidmap(i).count(), DUP_IF_SET(njc.gidmap(i), outside_id), njc.gidmap(i).count(),
true /* is_gid */, njc.gidmap(i).use_newidmap()) == false) { true /* is_gid */, njc.gidmap(i).use_newidmap()) == false) {
return false; return false;

View File

@ -41,18 +41,18 @@ extern "C" {
#include "cgroup.h" #include "cgroup.h"
#include "log.h" #include "log.h"
#include "mount.h" #include "mount.h"
#include "user.h"
} }
#include "caps.h" #include "caps.h"
#include "cpu.h" #include "cpu.h"
#include "net.h" #include "net.h"
#include "pid.h" #include "pid.h"
#include "user.h"
#include "uts.h" #include "uts.h"
namespace contain { namespace contain {
static bool containUserNs(struct nsjconf_t* nsjconf) { return userInitNsFromChild(nsjconf); } static bool containUserNs(struct nsjconf_t* nsjconf) { return user::initNsFromChild(nsjconf); }
static bool containInitPidNs(struct nsjconf_t* nsjconf) { return pid::initNs(nsjconf); } static bool containInitPidNs(struct nsjconf_t* nsjconf) { return pid::initNs(nsjconf); }

View File

@ -45,12 +45,12 @@
#include "contain.h" #include "contain.h"
#include "net.h" #include "net.h"
#include "sandbox.h" #include "sandbox.h"
#include "user.h"
extern "C" { extern "C" {
#include "cgroup.h" #include "cgroup.h"
#include "common.h" #include "common.h"
#include "log.h" #include "log.h"
#include "user.h"
#include "util.h" #include "util.h"
#if !defined(CLONE_NEWCGROUP) #if !defined(CLONE_NEWCGROUP)
@ -144,7 +144,7 @@ static int subprocNewProc(
} }
if (pipefd == -1) { if (pipefd == -1) {
if (userInitNsFromParent(nsjconf, getpid()) == false) { if (user::initNsFromParent(nsjconf, getpid()) == false) {
LOG_E("Couldn't initialize net user namespace"); LOG_E("Couldn't initialize net user namespace");
_exit(0xff); _exit(0xff);
} }
@ -384,7 +384,7 @@ static bool initParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd) {
LOG_E("Couldn't initialize cgroup user namespace"); LOG_E("Couldn't initialize cgroup user namespace");
exit(0xff); exit(0xff);
} }
if (userInitNsFromParent(nsjconf, pid) == false) { if (user::initNsFromParent(nsjconf, pid) == false) {
LOG_E("Couldn't initialize user namespaces for pid %d", pid); LOG_E("Couldn't initialize user namespaces for pid %d", pid);
return false; return false;
} }

View File

@ -39,12 +39,17 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
extern "C" {
#include "common.h" #include "common.h"
#include "log.h" #include "log.h"
#include "subproc.h"
#include "util.h" #include "util.h"
}
static bool userSetResGid(gid_t gid) { #include "subproc.h"
namespace user {
static bool setResGid(gid_t gid) {
LOG_D("setresgid(%d)", gid); LOG_D("setresgid(%d)", gid);
#if defined(__NR_setresgid32) #if defined(__NR_setresgid32)
if (syscall(__NR_setresgid32, (uintptr_t)gid, (uintptr_t)gid, (uintptr_t)gid) == -1) { if (syscall(__NR_setresgid32, (uintptr_t)gid, (uintptr_t)gid, (uintptr_t)gid) == -1) {
@ -60,7 +65,7 @@ static bool userSetResGid(gid_t gid) {
return true; return true;
} }
static bool userSetResUid(uid_t uid) { static bool setResUid(uid_t uid) {
LOG_D("setresuid(%d)", uid); LOG_D("setresuid(%d)", uid);
#if defined(__NR_setresuid32) #if defined(__NR_setresuid32)
if (syscall(__NR_setresuid32, (uintptr_t)uid, (uintptr_t)uid, (uintptr_t)uid) == -1) { if (syscall(__NR_setresuid32, (uintptr_t)uid, (uintptr_t)uid, (uintptr_t)uid) == -1) {
@ -76,7 +81,7 @@ static bool userSetResUid(uid_t uid) {
return true; return true;
} }
static bool userSetGroups(pid_t pid) { static bool setGroups(pid_t pid) {
/* /*
* No need to write 'deny' to /proc/pid/setgroups if our euid==0, as writing to * No need to write 'deny' to /proc/pid/setgroups if our euid==0, as writing to
* uid_map/gid_map will succeed anyway * uid_map/gid_map will succeed anyway
@ -95,7 +100,7 @@ static bool userSetGroups(pid_t pid) {
return true; return true;
} }
static bool userUidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) { static bool uidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
char fname[PATH_MAX]; char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/uid_map", pid); snprintf(fname, sizeof(fname), "/proc/%d/uid_map", pid);
@ -123,7 +128,7 @@ static bool userUidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
return true; return true;
} }
static bool userGidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) { static bool gidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
char fname[PATH_MAX]; char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/gid_map", pid); snprintf(fname, sizeof(fname), "/proc/%d/gid_map", pid);
@ -152,7 +157,7 @@ static bool userGidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
} }
/* Use /usr/bin/newgidmap for writing the gid map */ /* Use /usr/bin/newgidmap for writing the gid map */
static bool userGidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) { static bool gidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) {
size_t idx = 0; size_t idx = 0;
const char* argv[1024]; const char* argv[1024];
@ -204,7 +209,7 @@ static bool userGidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) {
} }
/* Use /usr/bin/newuidmap for writing the uid map */ /* Use /usr/bin/newuidmap for writing the uid map */
static bool userUidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) { static bool uidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) {
size_t idx = 0; size_t idx = 0;
const char* argv[1024]; const char* argv[1024];
@ -255,36 +260,36 @@ static bool userUidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) {
return true; return true;
} }
static bool userUidGidMap(struct nsjconf_t* nsjconf, pid_t pid) { static bool uidGidMap(struct nsjconf_t* nsjconf, pid_t pid) {
if (!userGidMapSelf(nsjconf, pid)) { if (!gidMapSelf(nsjconf, pid)) {
return false; return false;
} }
if (!userGidMapExternal(nsjconf, pid)) { if (!gidMapExternal(nsjconf, pid)) {
return false; return false;
} }
if (!userUidMapSelf(nsjconf, pid)) { if (!uidMapSelf(nsjconf, pid)) {
return false; return false;
} }
if (!userUidMapExternal(nsjconf, pid)) { if (!uidMapExternal(nsjconf, pid)) {
return false; return false;
} }
return true; return true;
} }
bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) { bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) {
if (userSetGroups(pid) == false) { if (setGroups(pid) == false) {
return false; return false;
} }
if (nsjconf->clone_newuser == false) { if (nsjconf->clone_newuser == false) {
return true; return true;
} }
if (userUidGidMap(nsjconf, pid) == false) { if (uidGidMap(nsjconf, pid) == false) {
return false; return false;
} }
return true; return true;
} }
bool userInitNsFromChild(struct nsjconf_t* nsjconf) { bool initNsFromChild(struct nsjconf_t* nsjconf) {
/* /*
* Best effort because of /proc/self/setgroups * Best effort because of /proc/self/setgroups
*/ */
@ -304,11 +309,11 @@ bool userInitNsFromChild(struct nsjconf_t* nsjconf) {
return false; return false;
} }
if (!userSetResGid(TAILQ_FIRST(&nsjconf->gids)->inside_id)) { if (!setResGid(TAILQ_FIRST(&nsjconf->gids)->inside_id)) {
PLOG_E("setresgid(%u)", TAILQ_FIRST(&nsjconf->gids)->inside_id); PLOG_E("setresgid(%u)", TAILQ_FIRST(&nsjconf->gids)->inside_id);
return false; return false;
} }
if (!userSetResUid(TAILQ_FIRST(&nsjconf->uids)->inside_id)) { if (!setResUid(TAILQ_FIRST(&nsjconf->uids)->inside_id)) {
PLOG_E("setresuid(%u)", TAILQ_FIRST(&nsjconf->uids)->inside_id); PLOG_E("setresuid(%u)", TAILQ_FIRST(&nsjconf->uids)->inside_id);
return false; return false;
} }
@ -316,7 +321,7 @@ bool userInitNsFromChild(struct nsjconf_t* nsjconf) {
return true; return true;
} }
static uid_t cmdParseUid(const char* id) { static uid_t parseUid(const char* id) {
if (id == NULL || strlen(id) == 0) { if (id == NULL || strlen(id) == 0) {
return getuid(); return getuid();
} }
@ -330,7 +335,7 @@ static uid_t cmdParseUid(const char* id) {
return (uid_t)-1; return (uid_t)-1;
} }
static gid_t cmdParseGid(const char* id) { static gid_t parseGid(const char* id) {
if (id == NULL || strlen(id) == 0) { if (id == NULL || strlen(id) == 0) {
return getgid(); return getgid();
} }
@ -344,36 +349,36 @@ static gid_t cmdParseGid(const char* id) {
return (gid_t)-1; return (gid_t)-1;
} }
bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, bool parseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt,
bool is_gid, bool is_newidmap) { bool is_gid, bool is_newidmap) {
uid_t inside_id; uid_t inside_id;
uid_t outside_id; uid_t outside_id;
if (is_gid) { if (is_gid) {
inside_id = cmdParseGid(i_id); inside_id = parseGid(i_id);
if (inside_id == (uid_t)-1) { if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", i_id); LOG_W("Cannot parse '%s' as GID", i_id);
return false; return false;
} }
outside_id = cmdParseGid(o_id); outside_id = parseGid(o_id);
if (outside_id == (uid_t)-1) { if (outside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", o_id); LOG_W("Cannot parse '%s' as GID", o_id);
return false; return false;
} }
} else { } else {
inside_id = cmdParseUid(i_id); inside_id = parseUid(i_id);
if (inside_id == (uid_t)-1) { if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as UID", i_id); LOG_W("Cannot parse '%s' as UID", i_id);
return false; return false;
} }
outside_id = cmdParseUid(o_id); outside_id = parseUid(o_id);
if (outside_id == (uid_t)-1) { if (outside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as UID", o_id); LOG_W("Cannot parse '%s' as UID", o_id);
return false; return false;
} }
} }
struct idmap_t* p = utilMalloc(sizeof(struct idmap_t)); struct idmap_t* p = reinterpret_cast<struct idmap_t*>(utilMalloc(sizeof(struct idmap_t)));
p->inside_id = inside_id; p->inside_id = inside_id;
p->outside_id = outside_id; p->outside_id = outside_id;
p->count = cnt; p->count = cnt;
@ -387,3 +392,5 @@ bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id,
return true; return true;
} }
} // namespace user

12
user.h
View File

@ -26,10 +26,14 @@
#include "nsjail.h" #include "nsjail.h"
bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid); namespace user {
bool userInitNsFromChild(struct nsjconf_t* nsjconf);
bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid);
bool is_gid, bool is_newidmap); bool initNsFromChild(struct nsjconf_t* nsjconf);
bool parseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt, bool is_gid,
bool is_newidmap);
} // namespace user
#endif /* NS_USER_H */ #endif /* NS_USER_H */