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
cgroup.o: cgroup.h nsjail.h log.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
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 config.h nsjail.h log.h mount.h user.h util.h caps.h
config.o: cmdline.h
contain.o: contain.h nsjail.h cgroup.h log.h mount.h user.h caps.h cpu.h
contain.o: net.h pid.h uts.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: 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 cgroup.h common.h
subproc.o: log.h user.h util.h
subproc.o: subproc.h nsjail.h contain.h net.h sandbox.h user.h cgroup.h
subproc.o: common.h log.h util.h
uts.o: uts.h nsjail.h log.h

View File

@ -48,13 +48,13 @@ extern "C" {
#include "common.h"
#include "log.h"
#include "mount.h"
#include "user.h"
#include "util.h"
}
#include "caps.h"
#include "config.h"
#include "sandbox.h"
#include "user.h"
namespace cmdline {
@ -623,7 +623,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id);
size_t count =
(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) {
return nullptr;
}
@ -634,7 +634,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id);
size_t count =
(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) {
return nullptr;
}
@ -645,7 +645,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id);
size_t count =
(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) {
return nullptr;
}
@ -656,7 +656,7 @@ std::unique_ptr<struct nsjconf_t> parseArgs(int argc, char* argv[]) {
char* cnt = cmdlineSplitStrByColon(o_id);
size_t count =
(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) {
return nullptr;
}

View File

@ -33,12 +33,12 @@ extern "C" {
#include "config.h"
#include "log.h"
#include "mount.h"
#include "user.h"
#include "util.h"
}
#include "caps.h"
#include "cmdline.h"
#include "user.h"
#include <google/protobuf/io/zero_copy_stream_impl.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();
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(),
false /* is_gid */, njc.uidmap(i).use_newidmap()) == false) {
return false;
}
}
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(),
true /* is_gid */, njc.gidmap(i).use_newidmap()) == false) {
return false;

View File

@ -41,18 +41,18 @@ extern "C" {
#include "cgroup.h"
#include "log.h"
#include "mount.h"
#include "user.h"
}
#include "caps.h"
#include "cpu.h"
#include "net.h"
#include "pid.h"
#include "user.h"
#include "uts.h"
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); }

View File

@ -45,12 +45,12 @@
#include "contain.h"
#include "net.h"
#include "sandbox.h"
#include "user.h"
extern "C" {
#include "cgroup.h"
#include "common.h"
#include "log.h"
#include "user.h"
#include "util.h"
#if !defined(CLONE_NEWCGROUP)
@ -144,7 +144,7 @@ static int subprocNewProc(
}
if (pipefd == -1) {
if (userInitNsFromParent(nsjconf, getpid()) == false) {
if (user::initNsFromParent(nsjconf, getpid()) == false) {
LOG_E("Couldn't initialize net user namespace");
_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");
exit(0xff);
}
if (userInitNsFromParent(nsjconf, pid) == false) {
if (user::initNsFromParent(nsjconf, pid) == false) {
LOG_E("Couldn't initialize user namespaces for pid %d", pid);
return false;
}

View File

@ -39,12 +39,17 @@
#include <sys/types.h>
#include <unistd.h>
extern "C" {
#include "common.h"
#include "log.h"
#include "subproc.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);
#if defined(__NR_setresgid32)
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;
}
static bool userSetResUid(uid_t uid) {
static bool setResUid(uid_t uid) {
LOG_D("setresuid(%d)", uid);
#if defined(__NR_setresuid32)
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;
}
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
* uid_map/gid_map will succeed anyway
@ -95,7 +100,7 @@ static bool userSetGroups(pid_t pid) {
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];
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;
}
static bool userGidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
static bool gidMapSelf(struct nsjconf_t* nsjconf, pid_t pid) {
char fname[PATH_MAX];
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 */
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;
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 */
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;
const char* argv[1024];
@ -255,36 +260,36 @@ static bool userUidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED) {
return true;
}
static bool userUidGidMap(struct nsjconf_t* nsjconf, pid_t pid) {
if (!userGidMapSelf(nsjconf, pid)) {
static bool uidGidMap(struct nsjconf_t* nsjconf, pid_t pid) {
if (!gidMapSelf(nsjconf, pid)) {
return false;
}
if (!userGidMapExternal(nsjconf, pid)) {
if (!gidMapExternal(nsjconf, pid)) {
return false;
}
if (!userUidMapSelf(nsjconf, pid)) {
if (!uidMapSelf(nsjconf, pid)) {
return false;
}
if (!userUidMapExternal(nsjconf, pid)) {
if (!uidMapExternal(nsjconf, pid)) {
return false;
}
return true;
}
bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) {
if (userSetGroups(pid) == false) {
bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid) {
if (setGroups(pid) == false) {
return false;
}
if (nsjconf->clone_newuser == false) {
return true;
}
if (userUidGidMap(nsjconf, pid) == false) {
if (uidGidMap(nsjconf, pid) == false) {
return false;
}
return true;
}
bool userInitNsFromChild(struct nsjconf_t* nsjconf) {
bool initNsFromChild(struct nsjconf_t* nsjconf) {
/*
* Best effort because of /proc/self/setgroups
*/
@ -304,11 +309,11 @@ bool userInitNsFromChild(struct nsjconf_t* nsjconf) {
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);
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);
return false;
}
@ -316,7 +321,7 @@ bool userInitNsFromChild(struct nsjconf_t* nsjconf) {
return true;
}
static uid_t cmdParseUid(const char* id) {
static uid_t parseUid(const char* id) {
if (id == NULL || strlen(id) == 0) {
return getuid();
}
@ -330,7 +335,7 @@ static uid_t cmdParseUid(const char* id) {
return (uid_t)-1;
}
static gid_t cmdParseGid(const char* id) {
static gid_t parseGid(const char* id) {
if (id == NULL || strlen(id) == 0) {
return getgid();
}
@ -344,36 +349,36 @@ static gid_t cmdParseGid(const char* id) {
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) {
uid_t inside_id;
uid_t outside_id;
if (is_gid) {
inside_id = cmdParseGid(i_id);
inside_id = parseGid(i_id);
if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", i_id);
return false;
}
outside_id = cmdParseGid(o_id);
outside_id = parseGid(o_id);
if (outside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", o_id);
return false;
}
} else {
inside_id = cmdParseUid(i_id);
inside_id = parseUid(i_id);
if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as UID", i_id);
return false;
}
outside_id = cmdParseUid(o_id);
outside_id = parseUid(o_id);
if (outside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as UID", o_id);
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->outside_id = outside_id;
p->count = cnt;
@ -387,3 +392,5 @@ bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id,
return true;
}
} // namespace user

12
user.h
View File

@ -26,10 +26,14 @@
#include "nsjail.h"
bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid);
bool userInitNsFromChild(struct nsjconf_t* nsjconf);
namespace user {
bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt,
bool is_gid, bool is_newidmap);
bool initNsFromParent(struct nsjconf_t* nsjconf, pid_t pid);
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 */