makedepend -Y -Ykafel/include -- -- $(SRCS_C) $(SRCS_CXX) $(SRCS_PB_CXX)
indent:
- clang-format --style=WebKit -i -sort-includes *.c *.h $(SRCS_CXX)
+ clang-format -style="{BasedOnStyle: webkit, IndentWidth: 8, UseTab: Always, IndentCaseLabels: false}" -i -sort-includes *.c *.h $(SRCS_CXX)
# DO NOT DELETE THIS LINE -- make depend depends on it.
#include "util.h"
#define VALSTR_STRUCT(x) \
- { \
- x, #x \
- }
+ { \
+ x, #x \
+ }
#if !defined(CAP_AUDIT_READ)
#define CAP_AUDIT_READ 37
-#endif /* !defined(CAP_AUDIT_READ) */
+#endif /* !defined(CAP_AUDIT_READ) */
// clang-format off
static struct {
};
// clang-format on
-int capsNameToVal(const char *name)
+int capsNameToVal(const char* name)
{
for (size_t i = 0; i < ARRAYSIZE(capNames); i++) {
if (strcmp(name, capNames[i].name) == 0) {
return -1;
}
-static const char *capsValToStr(int val)
+static const char* capsValToStr(int val)
{
static __thread char capsStr[1024];
for (size_t i = 0; i < ARRAYSIZE(capNames); i++) {
#define PR_CAP_AMBIENT 47
#define PR_CAP_AMBIENT_RAISE 2
#define PR_CAP_AMBIENT_CLEAR_ALL 4
-#endif /* !defined(PR_CAP_AMBIENT) */
+#endif /* !defined(PR_CAP_AMBIENT) */
static bool CapsInitNsKeepCaps(cap_user_data_t cap_data)
{
char dbgmsg[4096];
continue;
}
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)capNames[i].val, 0UL,
- 0UL)
+ 0UL)
== -1) {
PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", capNames[i].name);
} else {
return true;
}
-bool capsInitNs(struct nsjconf_t * nsjconf)
+bool capsInitNs(struct nsjconf_t* nsjconf)
{
char dbgmsg[4096];
- struct ints_t *p;
+ struct ints_t* p;
cap_user_data_t cap_data = capsGet();
if (cap_data == NULL) {
/* 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) {
+ 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));
+ capsValToStr(p->val));
return false;
}
utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val));
continue;
}
utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capNames[i].name);
- if (prctl(PR_CAPBSET_DROP, (unsigned long)capNames[i].val, 0UL, 0UL, 0UL) ==
- -1) {
+ 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;
}
/* 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) {
+ 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));
+ capsValToStr(p->val));
} else {
utilSSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capsValToStr(p->val));
}
#include "common.h"
-int capsNameToVal(const char *name);
-bool capsInitNs(struct nsjconf_t *nsjconf);
+int capsNameToVal(const char* name);
+bool capsInitNs(struct nsjconf_t* nsjconf);
-#endif /* NS_CAPS_H */
+#endif /* NS_CAPS_H */
#include "log.h"
#include "util.h"
-static bool cgroupInitNsFromParentMem(struct nsjconf_t *nsjconf, pid_t pid)
+static bool cgroupInitNsFromParentMem(struct nsjconf_t* nsjconf, pid_t pid)
{
- if (nsjconf->cgroup_mem_max == (size_t) 0) {
+ 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);
+ 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', 0711) failed", mem_cgroup_path);
}
char fname[PATH_MAX];
- if (nsjconf->cgroup_mem_max != (size_t) 0) {
+ if (nsjconf->cgroup_mem_max != (size_t)0) {
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);
return true;
}
-static bool cgroupInitNsFromParentPids(struct nsjconf_t *nsjconf, pid_t pid)
+static bool cgroupInitNsFromParentPids(struct nsjconf_t* nsjconf, pid_t pid)
{
- if (nsjconf->cgroup_pids_max == (size_t) 0) {
+ if (nsjconf->cgroup_pids_max == (size_t)0) {
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);
+ 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', 0711) failed", pids_cgroup_path);
}
char fname[PATH_MAX];
- if (nsjconf->cgroup_pids_max != (size_t) 0) {
+ if (nsjconf->cgroup_pids_max != (size_t)0) {
char pids_max_str[512];
snprintf(pids_max_str, sizeof(pids_max_str), "%zu", 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) ==
- false) {
+ if (utilWriteBufToFile(fname, pids_max_str, strlen(pids_max_str), O_WRONLY) == false) {
LOG_E("Could not update pids cgroup max limit");
return false;
}
return true;
}
-bool cgroupInitNsFromParent(struct nsjconf_t * nsjconf, pid_t pid)
+bool cgroupInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid)
{
if (cgroupInitNsFromParentMem(nsjconf, pid) == false) {
return false;
return true;
}
-void cgroupFinishFromParentMem(struct nsjconf_t *nsjconf, pid_t pid)
+void cgroupFinishFromParentMem(struct nsjconf_t* nsjconf, pid_t pid)
{
- if (nsjconf->cgroup_mem_max == (size_t) 0) {
+ 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);
+ 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)
+void cgroupFinishFromParentPids(struct nsjconf_t* nsjconf, pid_t pid)
{
- if (nsjconf->cgroup_pids_max == (size_t) 0) {
+ if (nsjconf->cgroup_pids_max == (size_t)0) {
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);
+ 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 cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid)
+void cgroupFinishFromParent(struct nsjconf_t* nsjconf, pid_t pid)
{
cgroupFinishFromParentMem(nsjconf, pid);
cgroupFinishFromParentPids(nsjconf, pid);
#include "common.h"
-bool cgroupInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid);
+bool cgroupInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid);
bool cgroupInitNs(void);
-void cgroupFinishFromParent(struct nsjconf_t *nsjconf, pid_t pid);
+void cgroupFinishFromParent(struct nsjconf_t* nsjconf, pid_t pid);
-#endif /* _CGROUP_H */
+#endif /* _CGROUP_H */
struct custom_option {
struct option opt;
- const char *descr;
+ const char* descr;
};
// clang-format off
};
// clang-format on
-static const char *logYesNo(bool yes)
+static const char* logYesNo(bool yes)
{
return (yes ? "true" : "false");
}
-static void cmdlineOptUsage(struct custom_option *option)
+static void cmdlineOptUsage(struct custom_option* option)
{
if (option->opt.val < 0x80) {
LOG_HELP_BOLD(" --%s%s%c %s", option->opt.name, "|-", option->opt.val,
- option->opt.has_arg == required_argument ? "VALUE" : "");
+ option->opt.has_arg == required_argument ? "VALUE" : "");
} else {
LOG_HELP_BOLD(" --%s %s", option->opt.name,
- option->opt.has_arg == required_argument ? "VALUE" : "");
+ option->opt.has_arg == required_argument ? "VALUE" : "");
}
LOG_HELP("\t%s", option->descr);
}
-static void cmdlineUsage(const char *pname)
+static void cmdlineUsage(const char* pname)
{
LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
LOG_HELP_BOLD("Options:");
for (size_t j = 0; j < ARRAYSIZE(custom_opts); j++) {
if (custom_opts[j].opt.val == deprecated_opts[i].opt.val) {
LOG_HELP_BOLD("\tDEPRECATED: Use %s instead.",
- custom_opts[j].opt.name);
+ custom_opts[j].opt.name);
break;
}
}
LOG_HELP_BOLD(" nsjail -Me --chroot / --disable_proc -- /bin/echo \"ABC\"");
}
-void cmdlineLogParams(struct nsjconf_t *nsjconf)
+void cmdlineLogParams(struct nsjconf_t* nsjconf)
{
switch (nsjconf->mode) {
case MODE_LISTEN_TCP:
"clone_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, "
"clone_newipc:%s, clonew_newuts:%s, clone_newcgroup:%s, keep_caps:%s, "
"tmpfs_size:%zu, disable_no_new_privs:%s, max_cpus:%zu",
- nsjconf->hostname, nsjconf->chroot ? nsjconf->chroot : "[NULL]", nsjconf->argv[0],
- nsjconf->bindhost, nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->tlimit,
- nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
- logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns),
- logYesNo(nsjconf->clone_newpid), logYesNo(nsjconf->clone_newipc),
- logYesNo(nsjconf->clone_newuts), logYesNo(nsjconf->clone_newcgroup),
- logYesNo(nsjconf->keep_caps), nsjconf->tmpfs_size,
- logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus);
+ nsjconf->hostname, nsjconf->chroot ? nsjconf->chroot : "[NULL]", nsjconf->argv[0],
+ nsjconf->bindhost, nsjconf->port, nsjconf->max_conns_per_ip, nsjconf->tlimit,
+ nsjconf->personality, logYesNo(nsjconf->daemonize), logYesNo(nsjconf->clone_newnet),
+ logYesNo(nsjconf->clone_newuser), logYesNo(nsjconf->clone_newns),
+ logYesNo(nsjconf->clone_newpid), logYesNo(nsjconf->clone_newipc),
+ logYesNo(nsjconf->clone_newuts), logYesNo(nsjconf->clone_newcgroup),
+ logYesNo(nsjconf->keep_caps), nsjconf->tmpfs_size,
+ logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus);
{
- struct mounts_t *p;
- TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) {
+ struct mounts_t* p;
+ TAILQ_FOREACH(p, &nsjconf->mountpts, pointers)
+ {
LOG_I("%s: %s", p->isSymlink ? "Symlink" : "Mount point",
- mountDescribeMountPt(p));
+ mountDescribeMountPt(p));
}
}
{
- struct idmap_t *p;
- TAILQ_FOREACH(p, &nsjconf->uids, pointers) {
+ struct idmap_t* p;
+ TAILQ_FOREACH(p, &nsjconf->uids, pointers)
+ {
LOG_I("Uid map: inside_uid:%lu outside_uid:%lu count:%zu newuidmap:%s",
- (unsigned long)p->inside_id, (unsigned long)p->outside_id, p->count,
- p->is_newidmap ? "true" : "false");
+ (unsigned long)p->inside_id, (unsigned long)p->outside_id, p->count,
+ p->is_newidmap ? "true" : "false");
if (p->outside_id == 0 && nsjconf->clone_newuser) {
- LOG_W
- ("Process will be UID/EUID=0 in the global user namespace, and will have user root-level access to files");
+ LOG_W("Process will be UID/EUID=0 in the global user namespace, and will have user root-level access to files");
}
}
- TAILQ_FOREACH(p, &nsjconf->gids, pointers) {
+ TAILQ_FOREACH(p, &nsjconf->gids, pointers)
+ {
LOG_I("Gid map: inside_gid:%lu outside_gid:%lu count:%zu newgidmap:%s",
- (unsigned long)p->inside_id, (unsigned long)p->outside_id, p->count,
- p->is_newidmap ? "true" : "false");
+ (unsigned long)p->inside_id, (unsigned long)p->outside_id, p->count,
+ p->is_newidmap ? "true" : "false");
if (p->outside_id == 0 && nsjconf->clone_newuser) {
- LOG_W
- ("Process will be GID/EGID=0 in the global user namespace, and will have group root-level access to files");
+ LOG_W("Process will be GID/EGID=0 in the global user namespace, and will have group root-level access to files");
}
}
}
}
-__rlim64_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul)
+__rlim64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul)
{
if (strcasecmp(optarg, "inf") == 0) {
return RLIM64_INFINITY;
return cur.rlim_max;
}
if (utilIsANumber(optarg) == false) {
- LOG_F
- ("RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' value ('%s' provided)",
- res, optarg);
+ LOG_F("RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' value ('%s' provided)",
+ res, optarg);
}
__rlim64_t val = strtoull(optarg, NULL, 0) * mul;
if (val == ULLONG_MAX && errno != 0) {
/* findSpecDestination mutates spec (source:dest) to have a null byte instead
* of ':' in between source and dest, then returns a pointer to the dest
* string. */
-static char *cmdlineSplitStrByColon(char *spec)
+static char* cmdlineSplitStrByColon(char* spec)
{
if (spec == NULL) {
return NULL;
}
- char *dest = spec;
+ char* dest = spec;
while (*dest != ':' && *dest != '\0') {
dest++;
}
}
}
-bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
+bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf)
{
-// clang-format off
+ // clang-format off
(*nsjconf) = (const struct nsjconf_t){
.exec_file = NULL,
.hostname = "NSJAIL",
.kafel_string = NULL,
.num_cpus = sysconf(_SC_NPROCESSORS_ONLN),
};
-// clang-format on
+ // clang-format on
TAILQ_INIT(&nsjconf->pids);
TAILQ_INIT(&nsjconf->mountpts);
static char cmdlineTmpfsSz[PATH_MAX] = "size=4194304";
- struct ints_t *f;
+ struct ints_t* f;
f = utilMalloc(sizeof(struct ints_t));
f->val = STDIN_FILENO;
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
int opt_index = 0;
for (;;) {
int c = getopt_long(argc, argv,
- "x:H:D:C:c:p:i:u:g:l:L:t:M:NdvqQeh?E:R:B:T:P:I:U:G:", opts,
- &opt_index);
+ "x:H:D:C:c:p:i:u:g:l:L:t:M:NdvqQeh?E:R:B:T:P:I:U:G:", opts,
+ &opt_index);
if (c == -1) {
break;
}
case 't':
nsjconf->tlimit = strtol(optarg, NULL, 0);
break;
- case 'h': /* help */
+ case 'h': /* help */
cmdlineUsage(argv[0]);
exit(0);
break;
case 0x0504:
nsjconf->skip_setsid = true;
break;
- case 0x0505:{
- struct ints_t *f;
- f = utilMalloc(sizeof(struct ints_t));
- f->val = (int)strtol(optarg, NULL, 0);
- TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
- } break;
+ case 0x0505: {
+ struct ints_t* f;
+ f = utilMalloc(sizeof(struct ints_t));
+ f->val = (int)strtol(optarg, NULL, 0);
+ TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
+ } break;
case 0x0507:
nsjconf->disable_no_new_privs = true;
break;
case 0x0508:
nsjconf->max_cpus = strtoul(optarg, NULL, 0);
break;
- case 0x509:{
- struct ints_t *f = utilMalloc(sizeof(struct ints_t));
- f->val = capsNameToVal(optarg);
- if (f->val == -1) {
- return false;
- }
- TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
+ case 0x509: {
+ struct ints_t* f = utilMalloc(sizeof(struct ints_t));
+ f->val = capsNameToVal(optarg);
+ if (f->val == -1) {
+ return false;
}
- break;
+ TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
+ } break;
case 0x0601:
nsjconf->is_root_rw = true;
break;
case 0x0602:
nsjconf->tmpfs_size = strtoull(optarg, NULL, 0);
snprintf(cmdlineTmpfsSz, sizeof(cmdlineTmpfsSz), "size=%zu",
- nsjconf->tmpfs_size);
+ nsjconf->tmpfs_size);
break;
case 0x0603:
nsjconf->mount_proc = false;
break;
- case 'E':{
- struct charptr_t *p = utilMalloc(sizeof(struct charptr_t));
- p->val = optarg;
- TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
- } break;
- case 'u':{
- char *i_id = optarg;
- char *o_id = cmdlineSplitStrByColon(i_id);
- char *cnt = cmdlineSplitStrByColon(o_id);
- size_t count = (cnt == NULL || strlen(cnt) == 0)
- ? 1U : (size_t) strtoull(cnt,
- NULL,
- 0);
- if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */ ,
- false /* is_newidmap */ )
- == false) {
- return false;
- }
+ case 'E': {
+ struct charptr_t* p = utilMalloc(sizeof(struct charptr_t));
+ p->val = optarg;
+ TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
+ } break;
+ case 'u': {
+ char* i_id = optarg;
+ char* o_id = cmdlineSplitStrByColon(i_id);
+ char* cnt = cmdlineSplitStrByColon(o_id);
+ size_t count = (cnt == NULL || strlen(cnt) == 0)
+ ? 1U
+ : (size_t)strtoull(cnt,
+ NULL,
+ 0);
+ if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */,
+ false /* is_newidmap */)
+ == false) {
+ return false;
}
- break;
- case 'g':{
- char *i_id = optarg;
- char *o_id = cmdlineSplitStrByColon(i_id);
- char *cnt = cmdlineSplitStrByColon(o_id);
- size_t count = (cnt == NULL || strlen(cnt) == 0)
- ? 1U : (size_t) strtoull(cnt,
- NULL,
- 0);
- if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */ ,
- false /* is_newidmap */ )
- == false) {
- return false;
- }
+ } break;
+ case 'g': {
+ char* i_id = optarg;
+ char* o_id = cmdlineSplitStrByColon(i_id);
+ char* cnt = cmdlineSplitStrByColon(o_id);
+ size_t count = (cnt == NULL || strlen(cnt) == 0)
+ ? 1U
+ : (size_t)strtoull(cnt,
+ NULL,
+ 0);
+ if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */,
+ false /* is_newidmap */)
+ == false) {
+ return false;
}
- break;
- case 'U':{
- char *i_id = optarg;
- char *o_id = cmdlineSplitStrByColon(i_id);
- char *cnt = cmdlineSplitStrByColon(o_id);
- size_t count = (cnt == NULL || strlen(cnt) == 0)
- ? 1U : (size_t) strtoull(cnt,
- NULL,
- 0);
- if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */ ,
- true /* is_newidmap */ )
- == false) {
- return false;
- }
+ } break;
+ case 'U': {
+ char* i_id = optarg;
+ char* o_id = cmdlineSplitStrByColon(i_id);
+ char* cnt = cmdlineSplitStrByColon(o_id);
+ size_t count = (cnt == NULL || strlen(cnt) == 0)
+ ? 1U
+ : (size_t)strtoull(cnt,
+ NULL,
+ 0);
+ if (userParseId(nsjconf, i_id, o_id, count, false /* is_gid */,
+ true /* is_newidmap */)
+ == false) {
+ return false;
}
- break;
- case 'G':{
- char *i_id = optarg;
- char *o_id = cmdlineSplitStrByColon(i_id);
- char *cnt = cmdlineSplitStrByColon(o_id);
- size_t count = (cnt == NULL || strlen(cnt) == 0)
- ? 1U : (size_t) strtoull(cnt,
- NULL,
- 0);
- if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */ ,
- true /* is_newidmap */ )
- == false) {
- return false;
- }
+ } break;
+ case 'G': {
+ char* i_id = optarg;
+ char* o_id = cmdlineSplitStrByColon(i_id);
+ char* cnt = cmdlineSplitStrByColon(o_id);
+ size_t count = (cnt == NULL || strlen(cnt) == 0)
+ ? 1U
+ : (size_t)strtoull(cnt,
+ NULL,
+ 0);
+ if (userParseId(nsjconf, i_id, o_id, count, true /* is_gid */,
+ true /* is_newidmap */)
+ == false) {
+ return false;
}
- break;
- case 'R':{
- const char *dst = cmdlineSplitStrByColon(optarg);
- dst = dst ? dst : optarg;
- if (!mountAddMountPtTail
- (nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
- /* options= */ "", MS_BIND | MS_REC | MS_RDONLY,
- /* isDir= */
- NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL, 0,
- /* is_symlink= */ false)) {
- return false;
- }
- };
- break;
- case 'B':{
- const char *dst = cmdlineSplitStrByColon(optarg);
- dst = dst ? dst : optarg;
- if (!mountAddMountPtTail
- (nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
- /* options= */ "", MS_BIND | MS_REC, /* isDir= */ NS_DIR_MAYBE,
- /* mandatory= */ true, NULL, NULL, NULL, 0,
- /* is_symlink= */
- false)) {
- return false;
- }
- };
- break;
- case 'T':{
- if (!mountAddMountPtTail
- (nsjconf, /* src= */ NULL, optarg, "tmpfs", /* options= */ "",
- /* flags= */ 0, /* isDir= */ true, /* mandatory= */ true, NULL,
- NULL, NULL, 0, /* is_symlink= */ false)) {
- return false;
- }
- };
- break;
+ } break;
+ case 'R': {
+ const char* dst = cmdlineSplitStrByColon(optarg);
+ dst = dst ? dst : optarg;
+ if (!mountAddMountPtTail(nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
+ /* options= */ "", MS_BIND | MS_REC | MS_RDONLY,
+ /* isDir= */
+ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL, 0,
+ /* is_symlink= */ false)) {
+ return false;
+ }
+ };
+ break;
+ case 'B': {
+ const char* dst = cmdlineSplitStrByColon(optarg);
+ dst = dst ? dst : optarg;
+ if (!mountAddMountPtTail(nsjconf, /* src= */ optarg, dst, /* fs_type= */ "",
+ /* options= */ "", MS_BIND | MS_REC, /* isDir= */ NS_DIR_MAYBE,
+ /* mandatory= */ true, NULL, NULL, NULL, 0,
+ /* is_symlink= */
+ false)) {
+ return false;
+ }
+ };
+ break;
+ case 'T': {
+ if (!mountAddMountPtTail(nsjconf, /* src= */ NULL, optarg, "tmpfs", /* options= */ "",
+ /* flags= */ 0, /* isDir= */ true, /* mandatory= */ true, NULL,
+ NULL, NULL, 0, /* is_symlink= */ false)) {
+ return false;
+ }
+ };
+ break;
case 'M':
switch (optarg[0]) {
case 'l':
nsjconf->iface_vs_gw = optarg;
break;
case 0x801:
- nsjconf->cgroup_mem_max = (size_t) strtoull(optarg, NULL, 0);
+ nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
break;
case 0x802:
nsjconf->cgroup_mem_mount = optarg;
nsjconf->cgroup_mem_parent = optarg;
break;
case 0x811:
- nsjconf->cgroup_pids_max = (size_t) strtoull(optarg, NULL, 0);
+ nsjconf->cgroup_pids_max = (size_t)strtoull(optarg, NULL, 0);
break;
case 0x812:
nsjconf->cgroup_pids_mount = optarg;
if (nsjconf->mount_proc == true) {
if (!mountAddMountPtHead(nsjconf, /* src= */ NULL, "/proc", "proc", "",
- nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ true,
- /* mandatory= */ true,
- NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
+ nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ true,
+ /* mandatory= */ true,
+ NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
return false;
}
}
if (nsjconf->chroot != NULL) {
- if (!mountAddMountPtHead
- (nsjconf, nsjconf->chroot, "/", /* fs_type= */ "", /* options= */ "",
- nsjconf->is_root_rw ? (MS_BIND | MS_REC) : (MS_BIND | MS_REC | MS_RDONLY),
- /* isDir= */ true, /* mandatory= */ true, NULL, NULL, NULL, 0,
- /* is_symlink= */ false)) {
+ if (!mountAddMountPtHead(nsjconf, nsjconf->chroot, "/", /* fs_type= */ "", /* options= */ "",
+ nsjconf->is_root_rw ? (MS_BIND | MS_REC) : (MS_BIND | MS_REC | MS_RDONLY),
+ /* isDir= */ true, /* mandatory= */ true, NULL, NULL, NULL, 0,
+ /* is_symlink= */ false)) {
return false;
}
} else {
if (!mountAddMountPtHead(nsjconf, /* src= */ NULL, "/", "tmpfs", /* options= */ "",
- nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ true,
- /* mandatory= */ true,
- NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
+ nsjconf->is_root_rw ? 0 : MS_RDONLY, /* isDir= */ true,
+ /* mandatory= */ true,
+ NULL, NULL, NULL, 0, /* is_symlink= */ false)) {
return false;
}
}
if (TAILQ_EMPTY(&nsjconf->uids)) {
- struct idmap_t *p = utilMalloc(sizeof(struct idmap_t));
+ struct idmap_t* p = utilMalloc(sizeof(struct idmap_t));
p->inside_id = getuid();
p->outside_id = getuid();
p->count = 1U;
TAILQ_INSERT_HEAD(&nsjconf->uids, p, pointers);
}
if (TAILQ_EMPTY(&nsjconf->gids)) {
- struct idmap_t *p = utilMalloc(sizeof(struct idmap_t));
+ struct idmap_t* p = utilMalloc(sizeof(struct idmap_t));
p->inside_id = getgid();
p->outside_id = getgid();
p->count = 1U;
}
if (argv[optind]) {
- nsjconf->argv = (const char **)&argv[optind];
+ nsjconf->argv = (const char**)&argv[optind];
}
if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) {
cmdlineUsage(argv[0]);
#include "common.h"
-__rlim64_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul);
-void cmdlineLogParams(struct nsjconf_t *nsjconf);
-bool cmdlineParse(int argc, char *argv[], struct nsjconf_t *nsjconf);
+__rlim64_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul);
+void cmdlineLogParams(struct nsjconf_t* nsjconf);
+bool cmdlineParse(int argc, char* argv[], struct nsjconf_t* nsjconf);
-#endif /* _CMDLINE_H */
+#endif /* _CMDLINE_H */
#define ARRAYSIZE(array) (sizeof(array) / sizeof(*array))
#define UNUSED __attribute__((unused))
-#if 0 /* Works, but needs -fblocks and libBlocksRuntime with clang */
+#if 0 /* Works, but needs -fblocks and libBlocksRuntime with clang */
/* Go-style defer implementation */
#define __STRMERGE(a, b) a##b
#define _STRMERGE(a, b) __STRMERGE(a, b)
#define defer void (^_STRMERGE(__defer_f_, __COUNTER__))(void) __attribute__((cleanup(__clang_cleanup_func))) __attribute__((unused)) = ^
#else
#define __block
-#define _DEFER(a, count) \
- auto void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused))); \
- int _STRMERGE(__defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) __attribute__((unused)); \
- void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused)))
+#define _DEFER(a, count) \
+ auto void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused))); \
+ int _STRMERGE(__defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) __attribute__((unused)); \
+ void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused)))
#define defer _DEFER(a, __COUNTER__)
#endif
#endif
char remote_txt[64];
struct sockaddr_in6 remote_addr;
int pid_syscall_fd;
- TAILQ_ENTRY(pids_t)
- pointers;
+ TAILQ_ENTRY(pids_t)
+ pointers;
};
struct mounts_t {
- const char *src;
- const uint8_t *src_content;
+ const char* src;
+ const uint8_t* src_content;
size_t src_content_len;
- const char *dst;
- const char *fs_type;
- const char *options;
+ const char* dst;
+ const char* fs_type;
+ const char* options;
uintptr_t flags;
bool isDir;
bool isSymlink;
bool mandatory;
bool mounted;
- TAILQ_ENTRY(mounts_t)
- pointers;
+ TAILQ_ENTRY(mounts_t)
+ pointers;
};
struct idmap_t {
uid_t outside_id;
size_t count;
bool is_newidmap;
- TAILQ_ENTRY(idmap_t)
- pointers;
+ TAILQ_ENTRY(idmap_t)
+ pointers;
};
struct ints_t {
int val;
- TAILQ_ENTRY(ints_t)
- pointers;
+ TAILQ_ENTRY(ints_t)
+ pointers;
};
enum ns_mode_t {
};
struct charptr_t {
- const char *val;
- TAILQ_ENTRY(charptr_t)
- pointers;
+ const char* val;
+ TAILQ_ENTRY(charptr_t)
+ pointers;
};
enum llevel_t {
};
struct nsjconf_t {
- const char *exec_file;
- const char *hostname;
- const char *cwd;
- const char **argv;
+ const char* exec_file;
+ const char* hostname;
+ const char* cwd;
+ const char** argv;
int port;
- const char *bindhost;
+ const char* bindhost;
int log_fd;
- const char *logfile;
+ const char* logfile;
enum llevel_t loglevel;
bool daemonize;
time_t tlimit;
bool clone_newuts;
bool clone_newcgroup;
enum ns_mode_t mode;
- const char *chroot;
+ const char* chroot;
bool is_root_rw;
bool is_silent;
bool skip_setsid;
size_t tmpfs_size;
bool mount_proc;
bool iface_no_lo;
- const char *iface_vs;
- const char *iface_vs_ip;
- const char *iface_vs_nm;
- const char *iface_vs_gw;
- const char *cgroup_mem_mount;
- const char *cgroup_mem_parent;
+ const char* iface_vs;
+ const char* iface_vs_ip;
+ const char* iface_vs_nm;
+ const char* iface_vs_gw;
+ const char* cgroup_mem_mount;
+ const char* cgroup_mem_parent;
size_t cgroup_mem_max;
- const char *cgroup_pids_mount;
- const char *cgroup_pids_parent;
+ const char* cgroup_pids_mount;
+ const char* cgroup_pids_parent;
size_t cgroup_pids_max;
- FILE *kafel_file;
- char *kafel_string;
+ FILE* kafel_file;
+ char* kafel_string;
uid_t orig_euid;
long num_cpus;
- TAILQ_HEAD(udmaplist, idmap_t)
- uids;
- TAILQ_HEAD(gdmaplist, idmap_t)
- gids;
- TAILQ_HEAD(envlist, charptr_t)
- envs;
- TAILQ_HEAD(pidslist, pids_t)
- pids;
- TAILQ_HEAD(mountptslist, mounts_t)
- mountpts;
- TAILQ_HEAD(fdslistt, ints_t)
- open_fds;
- TAILQ_HEAD(capslistt, ints_t)
- caps;
+ TAILQ_HEAD(udmaplist, idmap_t)
+ uids;
+ TAILQ_HEAD(gdmaplist, idmap_t)
+ gids;
+ TAILQ_HEAD(envlist, charptr_t)
+ envs;
+ TAILQ_HEAD(pidslist, pids_t)
+ pids;
+ TAILQ_HEAD(mountptslist, mounts_t)
+ mountpts;
+ TAILQ_HEAD(fdslistt, ints_t)
+ open_fds;
+ TAILQ_HEAD(capslistt, ints_t)
+ caps;
};
-#endif /* NS_COMMON_H */
+#endif /* NS_COMMON_H */
static __rlim64_t configRLimit(int res, const nsjail::RLimit& rl, const uint64_t val, unsigned long mul = 1UL)
{
- if (rl == nsjail::RLimit::VALUE) {
- return (val * mul);
- }
- if (rl == nsjail::RLimit::SOFT) {
- return cmdlineParseRLimit(res, "soft", mul);
- }
- if (rl == nsjail::RLimit::HARD) {
- return cmdlineParseRLimit(res, "hard", mul);
- }
- if (rl == nsjail::RLimit::INF) {
- return RLIM64_INFINITY;
- }
- LOG_F("Unknown rlimit value type for rlimit:%d", res);
- abort();
+ if (rl == nsjail::RLimit::VALUE) {
+ return (val * mul);
+ }
+ if (rl == nsjail::RLimit::SOFT) {
+ return cmdlineParseRLimit(res, "soft", mul);
+ }
+ if (rl == nsjail::RLimit::HARD) {
+ return cmdlineParseRLimit(res, "hard", mul);
+ }
+ if (rl == nsjail::RLimit::INF) {
+ return RLIM64_INFINITY;
+ }
+ LOG_F("Unknown rlimit value type for rlimit:%d", res);
+ abort();
}
static bool configParseInternal(struct nsjconf_t* nsjconf,
const nsjail::NsJailConfig& njc)
{
- switch (njc.mode()) {
- case nsjail::Mode::LISTEN:
- nsjconf->mode = MODE_LISTEN_TCP;
- break;
- case nsjail::Mode::ONCE:
- nsjconf->mode = MODE_STANDALONE_ONCE;
- break;
- case nsjail::Mode::RERUN:
- nsjconf->mode = MODE_STANDALONE_RERUN;
- break;
- case nsjail::Mode::EXECVE:
- nsjconf->mode = MODE_STANDALONE_EXECVE;
- break;
- default:
- LOG_E("Uknown running mode: %d", njc.mode());
- return false;
- }
- nsjconf->chroot = DUP_IF_SET(njc, chroot_dir);
- nsjconf->is_root_rw = njc.is_root_rw();
- nsjconf->hostname = njc.hostname().c_str();
- nsjconf->cwd = njc.cwd().c_str();
- nsjconf->port = njc.port();
- nsjconf->bindhost = njc.bindhost().c_str();
- nsjconf->max_conns_per_ip = njc.max_conns_per_ip();
- nsjconf->tlimit = njc.time_limit();
- nsjconf->max_cpus = njc.max_cpus();
- nsjconf->daemonize = njc.daemon();
-
- if (njc.has_log_fd()) {
- nsjconf->log_fd = njc.log_fd();
- }
- nsjconf->logfile = DUP_IF_SET(njc, log_file);
- if (njc.has_log_level()) {
- switch (njc.log_level()) {
- case nsjail::LogLevel::DEBUG:
- nsjconf->loglevel = DEBUG;
- break;
- case nsjail::LogLevel::INFO:
- nsjconf->loglevel = INFO;
- break;
- case nsjail::LogLevel::WARNING:
- nsjconf->loglevel = WARNING;
- break;
- case nsjail::LogLevel::ERROR:
- nsjconf->loglevel = ERROR;
- break;
- case nsjail::LogLevel::FATAL:
- nsjconf->loglevel = FATAL;
- break;
- default:
- LOG_E("Unknown log_level: %d", njc.log_level());
- return false;
- }
- }
-
- if (njc.has_log_fd() || njc.has_log_file() || njc.has_log_level()) {
- if (logInitLogFile(nsjconf) == false) {
- return false;
- }
- }
-
- nsjconf->keep_env = njc.keep_env();
- for (ssize_t i = 0; i < njc.envar_size(); i++) {
- struct charptr_t* p = reinterpret_cast<charptr_t*>(utilMalloc(sizeof(struct charptr_t)));
- p->val = njc.envar(i).c_str();
- TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
- }
-
- nsjconf->keep_caps = njc.keep_caps();
- for (ssize_t i = 0; i < njc.cap_size(); i++) {
- struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
- f->val = capsNameToVal(njc.cap(i).c_str());
- if (f->val == -1) {
- return false;
- }
- TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
- }
-
- nsjconf->is_silent = njc.silent();
- nsjconf->skip_setsid = njc.skip_setsid();
-
- for (ssize_t i = 0; i < njc.pass_fd_size(); i++) {
- struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
- f->val = njc.pass_fd(i);
- TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
- }
-
- nsjconf->disable_no_new_privs = njc.disable_no_new_privs();
-
- nsjconf->rl_as = configRLimit(RLIMIT_AS, njc.rlimit_as_type(), njc.rlimit_as(), 1024UL * 1024UL);
- nsjconf->rl_core = configRLimit(RLIMIT_CORE, njc.rlimit_core_type(), njc.rlimit_core(), 1024UL * 1024UL);
- nsjconf->rl_cpu = configRLimit(RLIMIT_CPU, njc.rlimit_cpu_type(), njc.rlimit_cpu());
- nsjconf->rl_fsize = configRLimit(RLIMIT_FSIZE, njc.rlimit_fsize_type(), njc.rlimit_fsize(), 1024UL * 1024UL);
- nsjconf->rl_nofile = configRLimit(RLIMIT_NOFILE, njc.rlimit_nofile_type(), njc.rlimit_nofile());
- nsjconf->rl_nproc = configRLimit(RLIMIT_NPROC, njc.rlimit_nproc_type(), njc.rlimit_nproc());
- nsjconf->rl_stack = configRLimit(RLIMIT_STACK, njc.rlimit_stack_type(), njc.rlimit_stack(), 1024UL * 1024UL);
-
- if (njc.persona_addr_compat_layout()) {
- nsjconf->personality |= ADDR_COMPAT_LAYOUT;
- }
- if (njc.persona_mmap_page_zero()) {
- nsjconf->personality |= MMAP_PAGE_ZERO;
- }
- if (njc.persona_read_implies_exec()) {
- nsjconf->personality |= READ_IMPLIES_EXEC;
- }
- if (njc.persona_addr_limit_3gb()) {
- nsjconf->personality |= ADDR_LIMIT_3GB;
- }
- if (njc.persona_addr_no_randomize()) {
- nsjconf->personality |= ADDR_NO_RANDOMIZE;
- }
-
- nsjconf->clone_newnet = njc.clone_newnet();
- nsjconf->clone_newuser = njc.clone_newuser();
- nsjconf->clone_newns = njc.clone_newns();
- nsjconf->clone_newpid = njc.clone_newpid();
- nsjconf->clone_newipc = njc.clone_newipc();
- nsjconf->clone_newuts = njc.clone_newuts();
- 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), 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), DUP_IF_SET(njc.gidmap(i), outside_id),
- njc.gidmap(i).count(), true /* is_gid */,
- njc.gidmap(i).use_newidmap())
- == false) {
- return false;
- }
- }
-
- nsjconf->mount_proc = njc.mount_proc();
- for (ssize_t i = 0; i < njc.mount_size(); i++) {
- const char* src = (njc.mount(i).has_src()) ? njc.mount(i).src().c_str() : NULL;
- const char* src_env = (njc.mount(i).has_prefix_src_env()) ? njc.mount(i).prefix_src_env().c_str() : NULL;
- const char* dst = (njc.mount(i).has_dst()) ? njc.mount(i).dst().c_str() : NULL;
- const char* dst_env = (njc.mount(i).has_prefix_dst_env()) ? njc.mount(i).prefix_dst_env().c_str() : NULL;
- const char* fstype = (njc.mount(i).has_fstype()) ? njc.mount(i).fstype().c_str() : NULL;
- const char* options = (njc.mount(i).has_options()) ? njc.mount(i).options().c_str() : NULL;
-
- uintptr_t flags = (njc.mount(i).rw() == false) ? MS_RDONLY : 0;
- flags |= njc.mount(i).is_bind() ? (MS_BIND | MS_REC) : 0;
- bool mandatory = njc.mount(i).mandatory();
-
- isDir_t isDir = NS_DIR_MAYBE;
- if (njc.mount(i).has_is_dir()) {
- isDir = njc.mount(i).is_dir() ? NS_DIR_YES : NS_DIR_NO;
- }
-
- const char* src_content = NULL;
- size_t src_content_len = 0;
- if (njc.mount(i).has_src_content()) {
- src_content = njc.mount(i).src_content().data();
- src_content_len = njc.mount(i).src_content().size();
- }
-
- if (mountAddMountPtTail(nsjconf, src, dst, fstype, options, flags, isDir,
- mandatory, src_env, dst_env, src_content,
- src_content_len, njc.mount(i).is_symlink())
- == false) {
- LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
- return false;
- }
- }
-
- if (njc.has_seccomp_policy_file()) {
- if ((nsjconf->kafel_file = fopen(njc.seccomp_policy_file().c_str(), "rb")) == NULL) {
- PLOG_W("Couldn't open file with seccomp policy '%s'",
- njc.seccomp_policy_file().c_str());
- return false;
- }
- }
-
- std::string kafel_string;
- for (ssize_t i = 0; i < njc.seccomp_string().size(); i++) {
- kafel_string += njc.seccomp_string(i);
- }
- nsjconf->kafel_string = njc.seccomp_string().size() > 0
- ? utilStrDup(kafel_string.c_str())
- : NULL;
-
- nsjconf->cgroup_mem_max = njc.cgroup_mem_max();
- nsjconf->cgroup_mem_mount = njc.cgroup_mem_mount().c_str();
- nsjconf->cgroup_mem_parent = njc.cgroup_mem_parent().c_str();
- nsjconf->cgroup_pids_max = njc.cgroup_pids_max();
- nsjconf->cgroup_pids_mount = njc.cgroup_pids_mount().c_str();
- nsjconf->cgroup_pids_parent = njc.cgroup_pids_parent().c_str();
-
- nsjconf->iface_no_lo = njc.iface_no_lo();
- nsjconf->iface_vs = DUP_IF_SET(njc, macvlan_iface);
- nsjconf->iface_vs_ip = njc.macvlan_vs_ip().c_str();
- nsjconf->iface_vs_nm = njc.macvlan_vs_nm().c_str();
- nsjconf->iface_vs_gw = njc.macvlan_vs_gw().c_str();
-
- if (njc.has_exec_bin()) {
- static std::vector<const char*> argv;
- if (njc.exec_bin().has_arg0()) {
- argv.push_back(njc.exec_bin().arg0().c_str());
- } else {
- argv.push_back(njc.exec_bin().path().c_str());
- }
- for (ssize_t i = 0; i < njc.exec_bin().arg().size(); i++) {
- argv.push_back(njc.exec_bin().arg(i).c_str());
- }
- argv.push_back(nullptr);
- nsjconf->exec_file = DUP_IF_SET(njc.exec_bin(), path);
- nsjconf->argv = argv.data();
- }
-
- return true;
+ switch (njc.mode()) {
+ case nsjail::Mode::LISTEN:
+ nsjconf->mode = MODE_LISTEN_TCP;
+ break;
+ case nsjail::Mode::ONCE:
+ nsjconf->mode = MODE_STANDALONE_ONCE;
+ break;
+ case nsjail::Mode::RERUN:
+ nsjconf->mode = MODE_STANDALONE_RERUN;
+ break;
+ case nsjail::Mode::EXECVE:
+ nsjconf->mode = MODE_STANDALONE_EXECVE;
+ break;
+ default:
+ LOG_E("Uknown running mode: %d", njc.mode());
+ return false;
+ }
+ nsjconf->chroot = DUP_IF_SET(njc, chroot_dir);
+ nsjconf->is_root_rw = njc.is_root_rw();
+ nsjconf->hostname = njc.hostname().c_str();
+ nsjconf->cwd = njc.cwd().c_str();
+ nsjconf->port = njc.port();
+ nsjconf->bindhost = njc.bindhost().c_str();
+ nsjconf->max_conns_per_ip = njc.max_conns_per_ip();
+ nsjconf->tlimit = njc.time_limit();
+ nsjconf->max_cpus = njc.max_cpus();
+ nsjconf->daemonize = njc.daemon();
+
+ if (njc.has_log_fd()) {
+ nsjconf->log_fd = njc.log_fd();
+ }
+ nsjconf->logfile = DUP_IF_SET(njc, log_file);
+ if (njc.has_log_level()) {
+ switch (njc.log_level()) {
+ case nsjail::LogLevel::DEBUG:
+ nsjconf->loglevel = DEBUG;
+ break;
+ case nsjail::LogLevel::INFO:
+ nsjconf->loglevel = INFO;
+ break;
+ case nsjail::LogLevel::WARNING:
+ nsjconf->loglevel = WARNING;
+ break;
+ case nsjail::LogLevel::ERROR:
+ nsjconf->loglevel = ERROR;
+ break;
+ case nsjail::LogLevel::FATAL:
+ nsjconf->loglevel = FATAL;
+ break;
+ default:
+ LOG_E("Unknown log_level: %d", njc.log_level());
+ return false;
+ }
+ }
+
+ if (njc.has_log_fd() || njc.has_log_file() || njc.has_log_level()) {
+ if (logInitLogFile(nsjconf) == false) {
+ return false;
+ }
+ }
+
+ nsjconf->keep_env = njc.keep_env();
+ for (ssize_t i = 0; i < njc.envar_size(); i++) {
+ struct charptr_t* p = reinterpret_cast<charptr_t*>(utilMalloc(sizeof(struct charptr_t)));
+ p->val = njc.envar(i).c_str();
+ TAILQ_INSERT_TAIL(&nsjconf->envs, p, pointers);
+ }
+
+ nsjconf->keep_caps = njc.keep_caps();
+ for (ssize_t i = 0; i < njc.cap_size(); i++) {
+ struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
+ f->val = capsNameToVal(njc.cap(i).c_str());
+ if (f->val == -1) {
+ return false;
+ }
+ TAILQ_INSERT_HEAD(&nsjconf->caps, f, pointers);
+ }
+
+ nsjconf->is_silent = njc.silent();
+ nsjconf->skip_setsid = njc.skip_setsid();
+
+ for (ssize_t i = 0; i < njc.pass_fd_size(); i++) {
+ struct ints_t* f = reinterpret_cast<struct ints_t*>(utilMalloc(sizeof(struct ints_t)));
+ f->val = njc.pass_fd(i);
+ TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
+ }
+
+ nsjconf->disable_no_new_privs = njc.disable_no_new_privs();
+
+ nsjconf->rl_as = configRLimit(RLIMIT_AS, njc.rlimit_as_type(), njc.rlimit_as(), 1024UL * 1024UL);
+ nsjconf->rl_core = configRLimit(RLIMIT_CORE, njc.rlimit_core_type(), njc.rlimit_core(), 1024UL * 1024UL);
+ nsjconf->rl_cpu = configRLimit(RLIMIT_CPU, njc.rlimit_cpu_type(), njc.rlimit_cpu());
+ nsjconf->rl_fsize = configRLimit(RLIMIT_FSIZE, njc.rlimit_fsize_type(), njc.rlimit_fsize(), 1024UL * 1024UL);
+ nsjconf->rl_nofile = configRLimit(RLIMIT_NOFILE, njc.rlimit_nofile_type(), njc.rlimit_nofile());
+ nsjconf->rl_nproc = configRLimit(RLIMIT_NPROC, njc.rlimit_nproc_type(), njc.rlimit_nproc());
+ nsjconf->rl_stack = configRLimit(RLIMIT_STACK, njc.rlimit_stack_type(), njc.rlimit_stack(), 1024UL * 1024UL);
+
+ if (njc.persona_addr_compat_layout()) {
+ nsjconf->personality |= ADDR_COMPAT_LAYOUT;
+ }
+ if (njc.persona_mmap_page_zero()) {
+ nsjconf->personality |= MMAP_PAGE_ZERO;
+ }
+ if (njc.persona_read_implies_exec()) {
+ nsjconf->personality |= READ_IMPLIES_EXEC;
+ }
+ if (njc.persona_addr_limit_3gb()) {
+ nsjconf->personality |= ADDR_LIMIT_3GB;
+ }
+ if (njc.persona_addr_no_randomize()) {
+ nsjconf->personality |= ADDR_NO_RANDOMIZE;
+ }
+
+ nsjconf->clone_newnet = njc.clone_newnet();
+ nsjconf->clone_newuser = njc.clone_newuser();
+ nsjconf->clone_newns = njc.clone_newns();
+ nsjconf->clone_newpid = njc.clone_newpid();
+ nsjconf->clone_newipc = njc.clone_newipc();
+ nsjconf->clone_newuts = njc.clone_newuts();
+ 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), 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), DUP_IF_SET(njc.gidmap(i), outside_id),
+ njc.gidmap(i).count(), true /* is_gid */,
+ njc.gidmap(i).use_newidmap())
+ == false) {
+ return false;
+ }
+ }
+
+ nsjconf->mount_proc = njc.mount_proc();
+ for (ssize_t i = 0; i < njc.mount_size(); i++) {
+ const char* src = (njc.mount(i).has_src()) ? njc.mount(i).src().c_str() : NULL;
+ const char* src_env = (njc.mount(i).has_prefix_src_env()) ? njc.mount(i).prefix_src_env().c_str() : NULL;
+ const char* dst = (njc.mount(i).has_dst()) ? njc.mount(i).dst().c_str() : NULL;
+ const char* dst_env = (njc.mount(i).has_prefix_dst_env()) ? njc.mount(i).prefix_dst_env().c_str() : NULL;
+ const char* fstype = (njc.mount(i).has_fstype()) ? njc.mount(i).fstype().c_str() : NULL;
+ const char* options = (njc.mount(i).has_options()) ? njc.mount(i).options().c_str() : NULL;
+
+ uintptr_t flags = (njc.mount(i).rw() == false) ? MS_RDONLY : 0;
+ flags |= njc.mount(i).is_bind() ? (MS_BIND | MS_REC) : 0;
+ bool mandatory = njc.mount(i).mandatory();
+
+ isDir_t isDir = NS_DIR_MAYBE;
+ if (njc.mount(i).has_is_dir()) {
+ isDir = njc.mount(i).is_dir() ? NS_DIR_YES : NS_DIR_NO;
+ }
+
+ const char* src_content = NULL;
+ size_t src_content_len = 0;
+ if (njc.mount(i).has_src_content()) {
+ src_content = njc.mount(i).src_content().data();
+ src_content_len = njc.mount(i).src_content().size();
+ }
+
+ if (mountAddMountPtTail(nsjconf, src, dst, fstype, options, flags, isDir,
+ mandatory, src_env, dst_env, src_content,
+ src_content_len, njc.mount(i).is_symlink())
+ == false) {
+ LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
+ return false;
+ }
+ }
+
+ if (njc.has_seccomp_policy_file()) {
+ if ((nsjconf->kafel_file = fopen(njc.seccomp_policy_file().c_str(), "rb")) == NULL) {
+ PLOG_W("Couldn't open file with seccomp policy '%s'",
+ njc.seccomp_policy_file().c_str());
+ return false;
+ }
+ }
+
+ std::string kafel_string;
+ for (ssize_t i = 0; i < njc.seccomp_string().size(); i++) {
+ kafel_string += njc.seccomp_string(i);
+ }
+ nsjconf->kafel_string = njc.seccomp_string().size() > 0
+ ? utilStrDup(kafel_string.c_str())
+ : NULL;
+
+ nsjconf->cgroup_mem_max = njc.cgroup_mem_max();
+ nsjconf->cgroup_mem_mount = njc.cgroup_mem_mount().c_str();
+ nsjconf->cgroup_mem_parent = njc.cgroup_mem_parent().c_str();
+ nsjconf->cgroup_pids_max = njc.cgroup_pids_max();
+ nsjconf->cgroup_pids_mount = njc.cgroup_pids_mount().c_str();
+ nsjconf->cgroup_pids_parent = njc.cgroup_pids_parent().c_str();
+
+ nsjconf->iface_no_lo = njc.iface_no_lo();
+ nsjconf->iface_vs = DUP_IF_SET(njc, macvlan_iface);
+ nsjconf->iface_vs_ip = njc.macvlan_vs_ip().c_str();
+ nsjconf->iface_vs_nm = njc.macvlan_vs_nm().c_str();
+ nsjconf->iface_vs_gw = njc.macvlan_vs_gw().c_str();
+
+ if (njc.has_exec_bin()) {
+ static std::vector<const char*> argv;
+ if (njc.exec_bin().has_arg0()) {
+ argv.push_back(njc.exec_bin().arg0().c_str());
+ } else {
+ argv.push_back(njc.exec_bin().path().c_str());
+ }
+ for (ssize_t i = 0; i < njc.exec_bin().arg().size(); i++) {
+ argv.push_back(njc.exec_bin().arg(i).c_str());
+ }
+ argv.push_back(nullptr);
+ nsjconf->exec_file = DUP_IF_SET(njc.exec_bin(), path);
+ nsjconf->argv = argv.data();
+ }
+
+ return true;
}
static void LogHandler(google::protobuf::LogLevel level, const char* filename, int line, const std::string& message)
{
- LOG_W("config.cc: '%s'", message.c_str());
+ LOG_W("config.cc: '%s'", message.c_str());
}
extern "C" bool configParse(struct nsjconf_t* nsjconf, const char* file)
{
- LOG_I("Parsing configuration from '%s'", file);
-
- int fd = open(file, O_RDONLY);
- if (fd == -1) {
- PLOG_W("Couldn't open config file '%s'", file);
- return false;
- }
-
- SetLogHandler(LogHandler);
- google::protobuf::io::FileInputStream input(fd);
- input.SetCloseOnDelete(true);
-
- /* Use static so we can get c_str() pointers, and copy them into the nsjconf struct */
- static nsjail::NsJailConfig nsc;
-
- auto parser = google::protobuf::TextFormat::Parser();
- if (!parser.Parse(&input, &nsc)) {
- LOG_W("Couldn't parse file '%s' from Text into ProtoBuf", file);
- return false;
- }
- if (!configParseInternal(nsjconf, nsc)) {
- LOG_W("Couldn't parse the ProtoBuf");
- return false;
- }
- LOG_D("Parsed config:\n'%s'", nsc.DebugString().c_str());
-
- return true;
+ LOG_I("Parsing configuration from '%s'", file);
+
+ int fd = open(file, O_RDONLY);
+ if (fd == -1) {
+ PLOG_W("Couldn't open config file '%s'", file);
+ return false;
+ }
+
+ SetLogHandler(LogHandler);
+ google::protobuf::io::FileInputStream input(fd);
+ input.SetCloseOnDelete(true);
+
+ /* Use static so we can get c_str() pointers, and copy them into the nsjconf struct */
+ static nsjail::NsJailConfig nsc;
+
+ auto parser = google::protobuf::TextFormat::Parser();
+ if (!parser.Parse(&input, &nsc)) {
+ LOG_W("Couldn't parse file '%s' from Text into ProtoBuf", file);
+ return false;
+ }
+ if (!configParseInternal(nsjconf, nsc)) {
+ LOG_W("Couldn't parse the ProtoBuf");
+ return false;
+ }
+ LOG_D("Parsed config:\n'%s'", nsc.DebugString().c_str());
+
+ return true;
}
#endif
#include "common.h"
- bool configParse(struct nsjconf_t *nsjconf, const char *file);
+bool configParse(struct nsjconf_t* nsjconf, const char* file);
#ifdef __cplusplus
-} // extern "C"
+} // extern "C"
#endif
-#endif /* NS_CONFIG_H */
+#endif /* NS_CONFIG_H */
#include "util.h"
#include "uts.h"
-static bool containUserNs(struct nsjconf_t *nsjconf)
+static bool containUserNs(struct nsjconf_t* nsjconf)
{
return userInitNsFromChild(nsjconf);
}
-static bool containInitPidNs(struct nsjconf_t *nsjconf)
+static bool containInitPidNs(struct nsjconf_t* nsjconf)
{
return pidInitNs(nsjconf);
}
-static bool containInitNetNs(struct nsjconf_t *nsjconf)
+static bool containInitNetNs(struct nsjconf_t* nsjconf)
{
return netInitNsFromChild(nsjconf);
}
-static bool containInitUtsNs(struct nsjconf_t *nsjconf)
+static bool containInitUtsNs(struct nsjconf_t* nsjconf)
{
return utsInitNs(nsjconf);
}
return cgroupInitNs();
}
-static bool containDropPrivs(struct nsjconf_t *nsjconf)
+static bool containDropPrivs(struct nsjconf_t* nsjconf)
{
#ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38
return true;
}
-static bool containPrepareEnv(struct nsjconf_t *nsjconf)
+static bool containPrepareEnv(struct nsjconf_t* nsjconf)
{
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) {
PLOG_E("prctl(PR_SET_PDEATHSIG, SIGKILL)");
return true;
}
-static bool containInitMountNs(struct nsjconf_t *nsjconf)
+static bool containInitMountNs(struct nsjconf_t* nsjconf)
{
return mountInitNs(nsjconf);
}
-static bool containCPU(struct nsjconf_t *nsjconf)
+static bool containCPU(struct nsjconf_t* nsjconf)
{
return cpuInit(nsjconf);
}
-static bool containSetLimits(struct nsjconf_t *nsjconf)
+static bool containSetLimits(struct nsjconf_t* nsjconf)
{
struct rlimit64 rl;
rl.rlim_cur = rl.rlim_max = nsjconf->rl_as;
return true;
}
-static bool containPassFd(struct nsjconf_t *nsjconf, int fd)
+static bool containPassFd(struct nsjconf_t* nsjconf, int fd)
{
- struct ints_t *p;
- TAILQ_FOREACH(p, &nsjconf->open_fds, pointers) {
+ struct ints_t* p;
+ TAILQ_FOREACH(p, &nsjconf->open_fds, pointers)
+ {
if (p->val == fd) {
return true;
}
return false;
}
-static bool containMakeFdsCOENaive(struct nsjconf_t *nsjconf)
+static bool containMakeFdsCOENaive(struct nsjconf_t* nsjconf)
{
/*
* Don't use getrlimit(RLIMIT_NOFILE) here, as it can return an artifically small value
return true;
}
-static bool containMakeFdsCOEProc(struct nsjconf_t *nsjconf)
+static bool containMakeFdsCOEProc(struct nsjconf_t* nsjconf)
{
int dirfd = open("/proc/self/fd", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (dirfd == -1) {
PLOG_D("open('/proc/self/fd', O_DIRECTORY|O_RDONLY)");
return false;
}
- DIR *dir = fdopendir(dirfd);
+ DIR* dir = fdopendir(dirfd);
if (dir == NULL) {
PLOG_W("fdopendir(fd=%d)", dirfd);
close(dirfd);
/* Make all fds above stderr close-on-exec */
for (;;) {
errno = 0;
- struct dirent *entry = readdir(dir);
+ struct dirent* entry = readdir(dir);
if (entry == NULL && errno != 0) {
PLOG_D("readdir('/proc/self/fd')");
closedir(dir);
return true;
}
-static bool containMakeFdsCOE(struct nsjconf_t *nsjconf)
+static bool containMakeFdsCOE(struct nsjconf_t* nsjconf)
{
if (containMakeFdsCOEProc(nsjconf) == true) {
return true;
return false;
}
-bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err)
+bool containSetupFD(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err)
{
if (nsjconf->mode != MODE_LISTEN_TCP) {
if (nsjconf->is_silent == false) {
return true;
}
-bool containContain(struct nsjconf_t * nsjconf)
+bool containContain(struct nsjconf_t* nsjconf)
{
if (containUserNs(nsjconf) == false) {
return false;
#include "common.h"
-bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err);
-bool containContain(struct nsjconf_t *nsjconf);
+bool containSetupFD(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err);
+bool containContain(struct nsjconf_t* nsjconf);
-#endif /* NS_CONTAIN_H */
+#endif /* NS_CONTAIN_H */
#include "log.h"
#include "util.h"
-static void cpuSetRandomCpu(cpu_set_t * mask, size_t mask_size, size_t cpu_num)
+static void cpuSetRandomCpu(cpu_set_t* mask, size_t mask_size, size_t cpu_num)
{
- if ((size_t) CPU_COUNT_S(mask_size, mask) >= cpu_num) {
- LOG_F
- ("Number of CPUs in the mask '%d' is bigger than number of available CPUs '%zu'",
- CPU_COUNT(mask), cpu_num);
+ if ((size_t)CPU_COUNT_S(mask_size, mask) >= cpu_num) {
+ LOG_F("Number of CPUs in the mask '%d' is bigger than number of available CPUs '%zu'",
+ CPU_COUNT(mask), cpu_num);
}
for (;;) {
}
}
-bool cpuInit(struct nsjconf_t *nsjconf)
+bool cpuInit(struct nsjconf_t* nsjconf)
{
if (nsjconf->num_cpus < 0) {
PLOG_W("sysconf(_SC_NPROCESSORS_ONLN) returned %ld", nsjconf->num_cpus);
return false;
}
- if (nsjconf->max_cpus > (size_t) nsjconf->num_cpus) {
+ if (nsjconf->max_cpus > (size_t)nsjconf->num_cpus) {
LOG_W("Requested number of CPUs:%zu is bigger than CPUs online:%ld",
- nsjconf->max_cpus, nsjconf->num_cpus);
+ nsjconf->max_cpus, nsjconf->num_cpus);
return true;
}
- if (nsjconf->max_cpus == (size_t) nsjconf->num_cpus) {
+ if (nsjconf->max_cpus == (size_t)nsjconf->num_cpus) {
LOG_D("All CPUs requested (%zu of %ld)", nsjconf->max_cpus, nsjconf->num_cpus);
return true;
}
return true;
}
- cpu_set_t *mask = CPU_ALLOC(nsjconf->num_cpus);
+ cpu_set_t* mask = CPU_ALLOC(nsjconf->num_cpus);
if (mask == NULL) {
PLOG_W("Failure allocating cpu_set_t for %ld CPUs", nsjconf->num_cpus);
return false;
#include "common.h"
-bool cpuInit(struct nsjconf_t *nsjconf);
+bool cpuInit(struct nsjconf_t* nsjconf);
-#endif /* NS_CPU_H */
+#endif /* NS_CPU_H */
* Log to stderr by default. Use a dup()d fd, because in the future we'll associate the
* connection socket with fd (0, 1, 2).
*/
-bool logInitLogFile(struct nsjconf_t *nsjconf)
+bool logInitLogFile(struct nsjconf_t* nsjconf)
{
/* Close previous log_fd */
if (log_fd > STDERR_FILENO) {
if (nsjconf->logfile == NULL) {
log_fd = fcntl(log_fd, F_DUPFD_CLOEXEC, 0);
} else {
- if (TEMP_FAILURE_RETRY
- (log_fd = open(nsjconf->logfile, O_CREAT | O_RDWR | O_APPEND, 0640)) == -1) {
+ if (TEMP_FAILURE_RETRY(log_fd = open(nsjconf->logfile, O_CREAT | O_RDWR | O_APPEND, 0640)) == -1) {
log_fd = STDERR_FILENO;
PLOG_E("Couldn't open logfile open('%s')", nsjconf->logfile);
return false;
return true;
}
-void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...)
+void logLog(enum llevel_t ll, const char* fn, int ln, bool perr, const char* fmt, ...)
{
if (ll < log_level) {
return;
snprintf(strerr, sizeof(strerr), "%s", strerror(errno));
}
struct ll_t {
- const char *const descr;
- const char *const prefix;
+ const char* const descr;
+ const char* const prefix;
const bool print_funcline;
const bool print_time;
};
static struct ll_t const logLevels[] = {
- {"D", "\033[0;4m", true, true},
- {"I", "\033[1m", false, true},
- {"W", "\033[0;33m", true, true},
- {"E", "\033[1;31m", true, true},
- {"F", "\033[7;35m", true, true},
- {"HR", "\033[0m", false, false},
- {"HB", "\033[1m", false, false},
+ { "D", "\033[0;4m", true, true },
+ { "I", "\033[1m", false, true },
+ { "W", "\033[0;33m", true, true },
+ { "E", "\033[1;31m", true, true },
+ { "F", "\033[7;35m", true, true },
+ { "HR", "\033[0m", false, false },
+ { "HB", "\033[1m", false, false },
};
time_t ltstamp = time(NULL);
#define PLOG_E(...) logLog(ERROR, __func__, __LINE__, true, __VA_ARGS__);
#define PLOG_F(...) logLog(FATAL, __func__, __LINE__, true, __VA_ARGS__);
-bool logInitLogFile(struct nsjconf_t *nsjconf);
-void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...)
- __attribute__ ((format(printf, 5, 6)));
+bool logInitLogFile(struct nsjconf_t* nsjconf);
+void logLog(enum llevel_t ll, const char* fn, int ln, bool perr, const char* fmt, ...)
+ __attribute__((format(printf, 5, 6)));
void logStop(int sig);
-#endif /* NS_LOG_H */
+#endif /* NS_LOG_H */
#include "util.h"
#define VALSTR_STRUCT(x) \
- { \
- x, #x \
- }
+ { \
+ x, #x \
+ }
#if !defined(MS_LAZYTIME)
#define MS_LAZYTIME (1 << 25)
-#endif /* if !defined(MS_LAZYTIME) */
+#endif /* if !defined(MS_LAZYTIME) */
-const char *mountFlagsToStr(uintptr_t flags)
+const char* mountFlagsToStr(uintptr_t flags)
{
static __thread char mountFlagsStr[1024];
mountFlagsStr[0] = '\0';
-// clang-format off
+ // clang-format off
static struct {
const uintptr_t flag;
const char* const name;
VALSTR_STRUCT(MS_STRICTATIME),
VALSTR_STRUCT(MS_LAZYTIME),
};
-// clang-format on
+ // clang-format on
for (size_t i = 0; i < ARRAYSIZE(mountFlags); i++) {
if (flags & mountFlags[i].flag) {
utilSSnPrintf(mountFlagsStr, sizeof(mountFlagsStr), "%s|",
- mountFlags[i].name);
+ mountFlags[i].name);
}
}
return mountFlagsStr;
}
-static bool mountIsDir(const char *path)
+static bool mountIsDir(const char* path)
{
/*
* If the source dir is NULL, we assume it's a dir (for /proc and tmpfs)
return false;
}
-static bool mountMount(struct mounts_t *mpt, const char *newroot, const char *tmpdir)
+static bool mountMount(struct mounts_t* mpt, const char* newroot, const char* tmpdir)
{
char dst[PATH_MAX];
snprintf(dst, sizeof(dst), "%s/%s", newroot, mpt->dst);
return false;
} else {
PLOG_W("symlink('%s', '%s'), but it's not mandatory, continuing",
- srcpath, dst);
+ srcpath, dst);
}
}
return true;
if (mpt->src_content) {
static uint64_t df_counter = 0;
snprintf(srcpath, sizeof(srcpath), "%s/dynamic_file.%" PRIu64, tmpdir,
- ++df_counter);
- int fd =
- TEMP_FAILURE_RETRY(open
- (srcpath, O_CREAT | O_EXCL | O_CLOEXEC | O_WRONLY, 0644));
+ ++df_counter);
+ int fd = TEMP_FAILURE_RETRY(open(srcpath, O_CREAT | O_EXCL | O_CLOEXEC | O_WRONLY, 0644));
if (fd < 0) {
PLOG_W("open(srcpath, O_CREAT|O_EXCL|O_CLOEXEC|O_WRONLY, 0644) failed");
return false;
if (errno == EACCES) {
PLOG_W("mount('%s') src:'%s' dst:'%s' failed. "
"Try fixing this problem by applying 'chmod o+x' to the '%s' directory and "
- "its ancestors", mountDescribeMountPt(mpt), srcpath, dst, srcpath);
+ "its ancestors",
+ mountDescribeMountPt(mpt), srcpath, dst, srcpath);
} else {
PLOG_W("mount('%s') src:'%s' dst:'%s' failed", mountDescribeMountPt(mpt),
- srcpath, dst);
+ srcpath, dst);
}
} else {
mpt->mounted = true;
return true;
}
-static bool mountRemountRO(struct mounts_t *mpt)
+static bool mountRemountRO(struct mounts_t* mpt)
{
if (!mpt->mounted) {
return true;
unsigned long new_flags = MS_REMOUNT | MS_BIND | MS_RDONLY | vfs.f_flag;
LOG_D("Re-mounting R/O '%s' (old_flags:%s, new_flags:%s)", mpt->dst,
- mountFlagsToStr(vfs.f_flag), mountFlagsToStr(new_flags));
+ mountFlagsToStr(vfs.f_flag), mountFlagsToStr(new_flags));
if (mount(mpt->dst, mpt->dst, NULL, new_flags, 0) == -1) {
PLOG_W("mount('%s', flags:%s)", mpt->dst, mountFlagsToStr(new_flags));
return true;
}
-static bool mountMkdirAndTest(const char *dir)
+static bool mountMkdirAndTest(const char* dir)
{
if (mkdir(dir, 0755) == -1 && errno != EEXIST) {
PLOG_W("Couldn't create '%s' directory", dir);
return true;
}
-static bool mountGetDir(char *dir, const char *name)
+static bool mountGetDir(char* dir, const char* name)
{
snprintf(dir, PATH_MAX, "/dev/shm/nsjail.%s", name);
if (mountMkdirAndTest(dir)) {
if (mountMkdirAndTest(dir)) {
return true;
}
- const char *tmp = getenv("TMPDIR");
+ const char* tmp = getenv("TMPDIR");
if (tmp) {
snprintf(dir, PATH_MAX, "%s/nsjail.%s", name, tmp);
if (mountMkdirAndTest(dir)) {
return false;
}
-static bool mountInitNsInternal(struct nsjconf_t *nsjconf)
+static bool mountInitNsInternal(struct nsjconf_t* nsjconf)
{
/*
* If CLONE_NEWNS is not used, we would be changing the global mount namespace, so simply
*/
if (nsjconf->clone_newns == false) {
if (nsjconf->chroot == NULL) {
- PLOG_E
- ("--chroot was not specified, and it's required when not using CLONE_NEWNS");
+ PLOG_E("--chroot was not specified, and it's required when not using CLONE_NEWNS");
return false;
}
if (chroot(nsjconf->chroot) == -1) {
return false;
}
- struct mounts_t *p;
- TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) {
+ struct mounts_t* p;
+ TAILQ_FOREACH(p, &nsjconf->mountpts, pointers)
+ {
if (mountMount(p, destdir, tmpdir) == false && p->mandatory) {
return false;
}
return false;
}
- TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) {
+ TAILQ_FOREACH(p, &nsjconf->mountpts, pointers)
+ {
if (mountRemountRO(p) == false && p->mandatory) {
return false;
}
* With mode MODE_STANDALONE_EXECVE it's required to mount /proc inside a new process,
* as the current process is still in the original PID namespace (man pid_namespaces)
*/
-bool mountInitNs(struct nsjconf_t * nsjconf)
+bool mountInitNs(struct nsjconf_t* nsjconf)
{
if (nsjconf->mode != MODE_STANDALONE_EXECVE) {
return mountInitNsInternal(nsjconf);
}
int status;
- while (wait4(pid, &status, 0, NULL) != pid) ;
+ while (wait4(pid, &status, 0, NULL) != pid)
+ ;
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
return true;
}
return false;
}
-static bool mountAddMountPt(struct nsjconf_t *nsjconf, bool head, const char *src, const char *dst,
- const char *fstype, const char *options, uintptr_t flags, isDir_t isDir,
- bool mandatory, const char *src_env, const char *dst_env,
- const char *src_content, size_t src_content_len, bool is_symlink)
+static bool mountAddMountPt(struct nsjconf_t* nsjconf, bool head, const char* src, const char* dst,
+ const char* fstype, const char* options, uintptr_t flags, isDir_t isDir,
+ bool mandatory, const char* src_env, const char* dst_env,
+ const char* src_content, size_t src_content_len, bool is_symlink)
{
- struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
+ struct mounts_t* p = utilCalloc(sizeof(struct mounts_t));
if (src_env) {
- const char *e = getenv(src_env);
+ const char* e = getenv(src_env);
if (e == NULL) {
LOG_W("No such envvar:'%s'", src_env);
return false;
}
- if (asprintf((char **)&p->src, "%s%s", e, src ? src : "") == -1) {
+ if (asprintf((char**)&p->src, "%s%s", e, src ? src : "") == -1) {
PLOG_W("asprintf() failed");
return false;
}
}
if (dst_env) {
- const char *e = getenv(dst_env);
+ const char* e = getenv(dst_env);
if (e == NULL) {
LOG_W("No such envvar:'%s'", dst_env);
return false;
}
- if (asprintf((char **)&p->dst, "%s%s", e, dst ? dst : "") == -1) {
+ if (asprintf((char**)&p->dst, "%s%s", e, dst ? dst : "") == -1) {
PLOG_W("asprintf() failed");
return false;
}
case NS_DIR_NO:
p->isDir = false;
break;
- case NS_DIR_MAYBE:{
- if (src_content) {
- p->isDir = false;
- } else if (p->src == NULL) {
- p->isDir = true;
- } else if (p->flags & MS_BIND) {
- p->isDir = mountIsDir(p->src);
- } else {
- p->isDir = true;
- }
+ case NS_DIR_MAYBE: {
+ if (src_content) {
+ p->isDir = false;
+ } else if (p->src == NULL) {
+ p->isDir = true;
+ } else if (p->flags & MS_BIND) {
+ p->isDir = mountIsDir(p->src);
+ } else {
+ p->isDir = true;
}
- break;
+ } break;
default:
LOG_F("Unknown isDir value: %d", isDir);
break;
}
- p->src_content = utilMemDup((const uint8_t *)src_content, src_content_len);
+ p->src_content = utilMemDup((const uint8_t*)src_content, src_content_len);
p->src_content_len = src_content_len;
if (head) {
return true;
}
-bool mountAddMountPtHead(struct nsjconf_t * nsjconf, const char *src, const char *dst,
- const char *fstype, const char *options, uintptr_t flags, isDir_t isDir,
- bool mandatory, const char *src_env, const char *dst_env,
- const char *src_content, size_t src_content_len, bool is_symlink)
+bool mountAddMountPtHead(struct nsjconf_t* nsjconf, const char* src, const char* dst,
+ const char* fstype, const char* options, uintptr_t flags, isDir_t isDir,
+ bool mandatory, const char* src_env, const char* dst_env,
+ const char* src_content, size_t src_content_len, bool is_symlink)
{
return mountAddMountPt(nsjconf, /* head= */ true, src, dst, fstype, options, flags, isDir,
- mandatory, src_env, dst_env, src_content, src_content_len,
- is_symlink);
+ mandatory, src_env, dst_env, src_content, src_content_len,
+ is_symlink);
}
-bool mountAddMountPtTail(struct nsjconf_t * nsjconf, const char *src, const char *dst,
- const char *fstype, const char *options, uintptr_t flags, isDir_t isDir,
- bool mandatory, const char *src_env, const char *dst_env,
- const char *src_content, size_t src_content_len, bool is_symlink)
+bool mountAddMountPtTail(struct nsjconf_t* nsjconf, const char* src, const char* dst,
+ const char* fstype, const char* options, uintptr_t flags, isDir_t isDir,
+ bool mandatory, const char* src_env, const char* dst_env,
+ const char* src_content, size_t src_content_len, bool is_symlink)
{
return mountAddMountPt(nsjconf, /* head= */ false, src, dst, fstype, options, flags, isDir,
- mandatory, src_env, dst_env, src_content, src_content_len,
- is_symlink);
+ mandatory, src_env, dst_env, src_content, src_content_len,
+ is_symlink);
}
-const char *mountDescribeMountPt(struct mounts_t *mpt)
+const char* mountDescribeMountPt(struct mounts_t* mpt)
{
static __thread char mount_pt_descr[4096];
snprintf(mount_pt_descr, sizeof(mount_pt_descr),
- "src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s",
- mpt->src ? mpt->src : "[NULL]", mpt->dst, mpt->fs_type ? mpt->fs_type : "[NULL]",
- mountFlagsToStr(mpt->flags), mpt->options ? mpt->options : "[NULL]",
- mpt->isDir ? "true" : "false");
+ "src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s",
+ mpt->src ? mpt->src : "[NULL]", mpt->dst, mpt->fs_type ? mpt->fs_type : "[NULL]",
+ mountFlagsToStr(mpt->flags), mpt->options ? mpt->options : "[NULL]",
+ mpt->isDir ? "true" : "false");
if (mpt->mandatory == false) {
utilSSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " mandatory:false");
}
if (mpt->src_content) {
utilSSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " src_content_len:%zu",
- mpt->src_content_len);
+ mpt->src_content_len);
}
if (mpt->isSymlink) {
utilSSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " symlink:true");
NS_DIR_MAYBE,
} isDir_t;
-const char *mountFlagsToStr(uintptr_t flags);
-bool mountInitNs(struct nsjconf_t *nsjconf);
-bool mountAddMountPtHead(struct nsjconf_t *nsjconf, const char *src, const char *dst,
- const char *fstype, const char *options, uintptr_t flags, isDir_t isDir,
- bool mandatory, const char *src_env, const char *dst_env,
- const char *src_content, size_t src_content_len, bool is_symlink);
-bool mountAddMountPtTail(struct nsjconf_t *nsjconf, const char *src, const char *dst,
- const char *fstype, const char *options, uintptr_t flags, isDir_t isDir,
- bool mandatory, const char *src_env, const char *dst_env,
- const char *src_content, size_t src_content_len, bool is_symlink);
-const char *mountDescribeMountPt(struct mounts_t *mpt);
-
-#endif /* NS_MOUNT_H */
+const char* mountFlagsToStr(uintptr_t flags);
+bool mountInitNs(struct nsjconf_t* nsjconf);
+bool mountAddMountPtHead(struct nsjconf_t* nsjconf, const char* src, const char* dst,
+ const char* fstype, const char* options, uintptr_t flags, isDir_t isDir,
+ bool mandatory, const char* src_env, const char* dst_env,
+ const char* src_content, size_t src_content_len, bool is_symlink);
+bool mountAddMountPtTail(struct nsjconf_t* nsjconf, const char* src, const char* dst,
+ const char* fstype, const char* options, uintptr_t flags, isDir_t isDir,
+ bool mandatory, const char* src_env, const char* dst_env,
+ const char* src_content, size_t src_content_len, bool is_symlink);
+const char* mountDescribeMountPt(struct mounts_t* mpt);
+
+#endif /* NS_MOUNT_H */
#define IFACE_NAME "vs"
-extern char **environ;
+extern char** environ;
#if defined(NSJAIL_NL3_WITH_MACVLAN)
#include <netlink/route/link.h>
#include <netlink/route/link/macvlan.h>
-bool netInitNsFromParent(struct nsjconf_t *nsjconf, int pid)
+bool netInitNsFromParent(struct nsjconf_t* nsjconf, int pid)
{
if (nsjconf->clone_newnet == false) {
return true;
LOG_D("Putting iface:'%s' into namespace of PID:%d (with libnl3)", nsjconf->iface_vs, pid);
- struct nl_sock *sk = nl_socket_alloc();
+ struct nl_sock* sk = nl_socket_alloc();
if (sk == NULL) {
LOG_E("Could not allocate socket with nl_socket_alloc()");
return false;
return false;
}
- struct rtnl_link *rmv = rtnl_link_macvlan_alloc();
+ struct rtnl_link* rmv = rtnl_link_macvlan_alloc();
if (rmv == NULL) {
LOG_E("rtnl_link_macvlan_alloc(): %s", nl_geterror(err));
nl_socket_free(sk);
return false;
}
- struct nl_cache *link_cache;
+ struct nl_cache* link_cache;
if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) {
LOG_E("rtnl_link_alloc_cache(): %s", nl_geterror(err));
rtnl_link_put(rmv);
if ((err = rtnl_link_add(sk, rmv, NLM_F_CREATE)) < 0) {
LOG_E("rtnl_link_add(name:'%s' link:'%s'): %s", IFACE_NAME, nsjconf->iface_vs,
- nl_geterror(err));
+ nl_geterror(err));
nl_cache_free(link_cache);
rtnl_link_put(rmv);
nl_socket_free(sk);
nl_socket_free(sk);
return true;
}
-#else // defined(NSJAIL_NL3_WITH_MACVLAN)
+#else // defined(NSJAIL_NL3_WITH_MACVLAN)
-bool netInitNsFromParent(struct nsjconf_t *nsjconf, int pid)
+bool netInitNsFromParent(struct nsjconf_t* nsjconf, int pid)
{
if (nsjconf->clone_newnet == false) {
return true;
}
LOG_D("Putting iface:'%s' into namespace of PID:%d (with /sbin/ip)", nsjconf->iface_vs,
- pid);
+ pid);
char pid_str[256];
snprintf(pid_str, sizeof(pid_str), "%d", pid);
- const char *argv[] = {
- "/sbin/ip", "link", "add", "link", (char *)nsjconf->iface_vs, "name", IFACE_NAME,
+ const char* argv[] = {
+ "/sbin/ip", "link", "add", "link", (char*)nsjconf->iface_vs, "name", IFACE_NAME,
"netns", pid_str, "type", "macvlan", "mode", "bridge", NULL
};
if (subprocSystem(argv, environ) != 0) {
return true;
}
-#endif // defined(NSJAIL_NL3_WITH_MACVLAN)
+#endif // defined(NSJAIL_NL3_WITH_MACVLAN)
static bool netIsSocket(int fd)
{
return true;
}
-bool netLimitConns(struct nsjconf_t * nsjconf, int connsock)
+bool netLimitConns(struct nsjconf_t* nsjconf, int connsock)
{
/* 0 means 'unlimited' */
if (nsjconf->max_conns_per_ip == 0) {
struct sockaddr_in6 addr;
char cs_addr[64];
- netConnToText(connsock, true /* remote */ , cs_addr, sizeof(cs_addr), &addr);
+ netConnToText(connsock, true /* remote */, cs_addr, sizeof(cs_addr), &addr);
unsigned int cnt = 0;
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
if (memcmp(addr.sin6_addr.s6_addr, p->remote_addr.sin6_addr.s6_addr,
- sizeof(*p->remote_addr.sin6_addr.s6_addr))
+ sizeof(*p->remote_addr.sin6_addr.s6_addr))
== 0) {
cnt++;
}
if (cnt >= nsjconf->max_conns_per_ip) {
LOG_W("Rejecting connection from '%s', max_conns_per_ip limit reached: %u", cs_addr,
- nsjconf->max_conns_per_ip);
+ nsjconf->max_conns_per_ip);
return false;
}
return true;
}
-int netGetRecvSocket(const char *bindhost, int port)
+int netGetRecvSocket(const char* bindhost, int port)
{
if (port < 1 || port > 65535) {
- LOG_F
- ("TCP port %d out of bounds (0 <= port <= 65535), specify one with --port <port>",
- port);
+ LOG_F("TCP port %d out of bounds (0 <= port <= 65535), specify one with --port <port>",
+ port);
}
char bindaddr[128];
struct in6_addr in6a;
if (inet_pton(AF_INET6, bindaddr, &in6a) != 1) {
PLOG_E("Couldn't convert '%s' (orig:'%s') into AF_INET6 address", bindaddr,
- bindhost);
+ bindhost);
return -1;
}
.sin6_addr = in6a,
.sin6_scope_id = 0,
};
- if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
close(sockfd);
PLOG_E("bind(host:[%s (orig:'%s')], port:%d)", bindaddr, bindhost, port);
return -1;
}
char ss_addr[64];
- netConnToText(sockfd, false /* remote */ , ss_addr, sizeof(ss_addr), NULL);
+ netConnToText(sockfd, false /* remote */, ss_addr, sizeof(ss_addr), NULL);
LOG_I("Listening on %s", ss_addr);
return sockfd;
{
struct sockaddr_in6 cli_addr;
socklen_t socklen = sizeof(cli_addr);
- int connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &socklen);
+ int connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &socklen);
if (connfd == -1) {
if (errno != EINTR) {
PLOG_E("accept(%d)", listenfd);
}
char cs_addr[64], ss_addr[64];
- netConnToText(connfd, true /* remote */ , cs_addr, sizeof(cs_addr), NULL);
- netConnToText(connfd, false /* remote */ , ss_addr, sizeof(ss_addr), NULL);
+ netConnToText(connfd, true /* remote */, cs_addr, sizeof(cs_addr), NULL);
+ netConnToText(connfd, false /* remote */, ss_addr, sizeof(ss_addr), NULL);
LOG_I("New connection from: %s on: %s", cs_addr, ss_addr);
return connfd;
}
-void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 *addr_or_null)
+void netConnToText(int fd, bool remote, char* buf, size_t s, struct sockaddr_in6* addr_or_null)
{
if (netIsSocket(fd) == false) {
snprintf(buf, s, "[STANDALONE_MODE]");
struct sockaddr_in6 addr;
socklen_t addrlen = sizeof(addr);
if (remote) {
- if (getpeername(fd, (struct sockaddr *)&addr, &addrlen) == -1) {
+ if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) == -1) {
PLOG_W("getpeername(%d)", fd);
snprintf(buf, s, "[unknown]");
return;
}
} else {
- if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) == -1) {
+ if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) == -1) {
PLOG_W("getsockname(%d)", fd);
snprintf(buf, s, "[unknown]");
return;
return;
}
-static bool netIfaceUp(const char *ifacename)
+static bool netIfaceUp(const char* ifacename)
{
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock == -1) {
return true;
}
-static bool netConfigureVs(struct nsjconf_t *nsjconf)
+static bool netConfigureVs(struct nsjconf_t* nsjconf)
{
struct ifreq ifr;
memset(&ifr, '\0', sizeof(ifr));
return true;
}
- struct sockaddr_in *sa = (struct sockaddr_in *)(&ifr.ifr_addr);
+ struct sockaddr_in* sa = (struct sockaddr_in*)(&ifr.ifr_addr);
sa->sin_family = AF_INET;
sa->sin_addr = addr;
if (ioctl(sock, SIOCSIFADDR, &ifr) == -1) {
struct rtentry rt;
memset(&rt, '\0', sizeof(rt));
- struct sockaddr_in *sdest = (struct sockaddr_in *)(&rt.rt_dst);
- struct sockaddr_in *smask = (struct sockaddr_in *)(&rt.rt_genmask);
- struct sockaddr_in *sgate = (struct sockaddr_in *)(&rt.rt_gateway);
+ struct sockaddr_in* sdest = (struct sockaddr_in*)(&rt.rt_dst);
+ struct sockaddr_in* smask = (struct sockaddr_in*)(&rt.rt_genmask);
+ struct sockaddr_in* sgate = (struct sockaddr_in*)(&rt.rt_gateway);
sdest->sin_family = AF_INET;
sdest->sin_addr.s_addr = INADDR_ANY;
smask->sin_family = AF_INET;
return true;
}
-bool netInitNsFromChild(struct nsjconf_t * nsjconf)
+bool netInitNsFromChild(struct nsjconf_t* nsjconf)
{
if (nsjconf->clone_newnet == false) {
return true;
#include "common.h"
-bool netLimitConns(struct nsjconf_t *nsjconf, int connsock);
-int netGetRecvSocket(const char *bindhost, int port);
+bool netLimitConns(struct nsjconf_t* nsjconf, int connsock);
+int netGetRecvSocket(const char* bindhost, int port);
int netAcceptConn(int listenfd);
-void netConnToText(int fd, bool remote, char *buf, size_t s, struct sockaddr_in6 *addr_or_null);
-bool netInitNsFromParent(struct nsjconf_t *nsjconf, int pid);
-bool netInitNsFromChild(struct nsjconf_t *nsjconf);
+void netConnToText(int fd, bool remote, char* buf, size_t s, struct sockaddr_in6* addr_or_null);
+bool netInitNsFromParent(struct nsjconf_t* nsjconf, int pid);
+bool netInitNsFromChild(struct nsjconf_t* nsjconf);
-#endif /* _NET_H */
+#endif /* _NET_H */
return true;
}
-static bool nsjailSetTimer(struct nsjconf_t *nsjconf)
+static bool nsjailSetTimer(struct nsjconf_t* nsjconf)
{
if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
return true;
}
struct itimerval it = {
- .it_value = {.tv_sec = 1,.tv_usec = 0},
- .it_interval = {.tv_sec = 1,.tv_usec = 0},
+ .it_value = {.tv_sec = 1, .tv_usec = 0 },
+ .it_interval = {.tv_sec = 1, .tv_usec = 0 },
};
if (setitimer(ITIMER_REAL, &it, NULL) == -1) {
PLOG_E("setitimer(ITIMER_REAL)");
return true;
}
-static void nsjailListenMode(struct nsjconf_t *nsjconf)
+static void nsjailListenMode(struct nsjconf_t* nsjconf)
{
int listenfd = netGetRecvSocket(nsjconf->bindhost, nsjconf->port);
if (listenfd == -1) {
}
}
-static int nsjailStandaloneMode(struct nsjconf_t *nsjconf)
+static int nsjailStandaloneMode(struct nsjconf_t* nsjconf)
{
subprocRunChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
for (;;) {
// not reached
}
-int main(int argc, char *argv[])
+int main(int argc, char* argv[])
{
struct nsjconf_t nsjconf;
if (!cmdlineParse(argc, argv, &nsjconf)) {
/*
* To satisfy requirement for BlocksRuntime in clang -fblocks
*/
-void *_NSConcreteStackBlock[32] = { 0 };
+void* _NSConcreteStackBlock[32] = { 0 };
#include "common.h"
-#endif /* _NSJAIL_H */
+#endif /* _NSJAIL_H */
#include "log.h"
#include "subproc.h"
-bool pidInitNs(struct nsjconf_t *nsjconf)
+bool pidInitNs(struct nsjconf_t* nsjconf)
{
if (nsjconf->mode != MODE_STANDALONE_EXECVE) {
return true;
#include "common.h"
-bool pidInitNs(struct nsjconf_t *nsjconf);
+bool pidInitNs(struct nsjconf_t* nsjconf);
-#endif /* NS_PID_H */
+#endif /* NS_PID_H */
#include "kafel.h"
#include "log.h"
-#ifndef PR_SET_NO_NEW_PRIVS /* in prctl.h since Linux 3.5 */
+#ifndef PR_SET_NO_NEW_PRIVS /* in prctl.h since Linux 3.5 */
#define PR_SET_NO_NEW_PRIVS 38
-#endif /* PR_SET_NO_NEW_PRIVS */
+#endif /* PR_SET_NO_NEW_PRIVS */
-static bool sandboxPrepareAndCommit(struct nsjconf_t *nsjconf)
+static bool sandboxPrepareAndCommit(struct nsjconf_t* nsjconf)
{
if (nsjconf->kafel_file == NULL && nsjconf->kafel_string == NULL) {
return true;
return true;
}
-bool sandboxApply(struct nsjconf_t * nsjconf)
+bool sandboxApply(struct nsjconf_t* nsjconf)
{
return sandboxPrepareAndCommit(nsjconf);
}
#include "common.h"
-bool sandboxApply(struct nsjconf_t *nsjconf);
+bool sandboxApply(struct nsjconf_t* nsjconf);
-#endif /* NS_SANDBOX_H */
+#endif /* NS_SANDBOX_H */
static const char subprocDoneChar = 'D';
#define VALSTR_STRUCT(x) \
- { \
- x, #x \
- }
+ { \
+ x, #x \
+ }
#if !defined(CLONE_NEWCGROUP)
#define CLONE_NEWCGROUP 0x02000000
-#endif /* !defined(CLONE_NEWCGROUP) */
+#endif /* !defined(CLONE_NEWCGROUP) */
-static const char *subprocCloneFlagsToStr(uintptr_t flags)
+static const char* subprocCloneFlagsToStr(uintptr_t flags)
{
static __thread char cloneFlagName[1024];
cloneFlagName[0] = '\0';
-// clang-format off
+ // clang-format off
static struct {
const uintptr_t flag;
const char* const name;
VALSTR_STRUCT(CLONE_NEWNET),
VALSTR_STRUCT(CLONE_IO),
};
-// clang-format on
+ // clang-format on
for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) {
if (flags & cloneFlags[i].flag) {
utilSSnPrintf(cloneFlagName, sizeof(cloneFlagName), "%s|",
- cloneFlags[i].name);
+ cloneFlags[i].name);
}
}
}
if (flags & ~(knownFlagMask)) {
utilSSnPrintf(cloneFlagName, sizeof(cloneFlagName), "%#tx|",
- flags & ~(knownFlagMask));
+ flags & ~(knownFlagMask));
}
utilSSnPrintf(cloneFlagName, sizeof(cloneFlagName), "%s", utilSigName(flags & CSIGNAL));
return cloneFlagName;
}
-static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int pipefd)
+static int subprocNewProc(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err, int pipefd)
{
if (containSetupFD(nsjconf, fd_in, fd_out, fd_err) == false) {
exit(0xff);
if (nsjconf->keep_env == false) {
clearenv();
}
- struct charptr_t *p;
- TAILQ_FOREACH(p, &nsjconf->envs, pointers) {
- putenv((char *)p->val);
+ struct charptr_t* p;
+ TAILQ_FOREACH(p, &nsjconf->envs, pointers)
+ {
+ putenv((char*)p->val);
}
char cs_addr[64];
- netConnToText(fd_in, true /* remote */ , cs_addr, sizeof(cs_addr), NULL);
+ netConnToText(fd_in, true /* remote */, cs_addr, sizeof(cs_addr), NULL);
LOG_I("Executing '%s' for '%s'", nsjconf->exec_file, cs_addr);
for (size_t i = 0; nsjconf->argv[i]; i++) {
if (sandboxApply(nsjconf) == false) {
exit(0xff);
}
- execv(nsjconf->exec_file, (char *const *)&nsjconf->argv[0]);
+ execv(nsjconf->exec_file, (char* const*)&nsjconf->argv[0]);
PLOG_E("execve('%s') failed", nsjconf->exec_file);
_exit(0xff);
}
-static void subprocAdd(struct nsjconf_t *nsjconf, pid_t pid, int sock)
+static void subprocAdd(struct nsjconf_t* nsjconf, pid_t pid, int sock)
{
- struct pids_t *p = utilMalloc(sizeof(struct pids_t));
+ struct pids_t* p = utilMalloc(sizeof(struct pids_t));
p->pid = pid;
p->start = time(NULL);
- netConnToText(sock, true /* remote */ , p->remote_txt, sizeof(p->remote_txt),
- &p->remote_addr);
+ netConnToText(sock, true /* remote */, p->remote_txt, sizeof(p->remote_txt),
+ &p->remote_addr);
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/syscall", (int)pid);
TAILQ_INSERT_HEAD(&nsjconf->pids, p, pointers);
LOG_D("Added pid '%d' with start time '%u' to the queue for IP: '%s'", pid,
- (unsigned int)p->start, p->remote_txt);
+ (unsigned int)p->start, p->remote_txt);
}
-static void subprocRemove(struct nsjconf_t *nsjconf, pid_t pid)
+static void subprocRemove(struct nsjconf_t* nsjconf, pid_t pid)
{
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
if (p->pid == pid) {
LOG_D("Removing pid '%d' from the queue (IP:'%s', start time:'%s')", p->pid,
- p->remote_txt, utilTimeToStr(p->start));
+ p->remote_txt, utilTimeToStr(p->start));
close(p->pid_syscall_fd);
TAILQ_REMOVE(&nsjconf->pids, p, pointers);
free(p);
LOG_W("PID: %d not found (?)", pid);
}
-int subprocCount(struct nsjconf_t *nsjconf)
+int subprocCount(struct nsjconf_t* nsjconf)
{
int cnt = 0;
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
cnt++;
}
return cnt;
}
-void subprocDisplay(struct nsjconf_t *nsjconf)
+void subprocDisplay(struct nsjconf_t* nsjconf)
{
LOG_I("Total number of spawned namespaces: %d", subprocCount(nsjconf));
time_t now = time(NULL);
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
time_t diff = now - p->start;
time_t left = nsjconf->tlimit ? nsjconf->tlimit - diff : 0;
LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", p->pid,
- p->remote_txt, (long)diff, (long)left);
+ p->remote_txt, (long)diff, (long)left);
}
}
-static struct pids_t *subprocGetPidElem(struct nsjconf_t *nsjconf, pid_t pid)
+static struct pids_t* subprocGetPidElem(struct nsjconf_t* nsjconf, pid_t pid)
{
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
if (p->pid == pid) {
return p;
}
return NULL;
}
-static void subprocSeccompViolation(struct nsjconf_t *nsjconf, siginfo_t * si)
+static void subprocSeccompViolation(struct nsjconf_t* nsjconf, siginfo_t* si)
{
LOG_W("PID: %d commited a syscall/seccomp violation and exited with SIGSYS", si->si_pid);
- struct pids_t *p = subprocGetPidElem(nsjconf, si->si_pid);
+ struct pids_t* p = subprocGetPidElem(nsjconf, si->si_pid);
if (p == NULL) {
LOG_W("PID: %d, Syscall number: %d, Seccomp reason: %d", (int)si->si_pid,
- si->si_syscall, si->si_errno);
+ si->si_syscall, si->si_errno);
LOG_E("Couldn't find pid element in the subproc list for PID: %d", (int)si->si_pid);
return;
}
ssize_t rdsize = utilReadFromFd(p->pid_syscall_fd, buf, sizeof(buf) - 1);
if (rdsize < 1) {
LOG_W("PID: %d, Syscall number: %d, Seccomp reason: %d", (int)si->si_pid,
- si->si_syscall, si->si_errno);
+ si->si_syscall, si->si_errno);
return;
}
buf[rdsize - 1] = '\0';
uintptr_t arg1, arg2, arg3, arg4, arg5, arg6, sp, pc;
ptrdiff_t sc;
- int ret =
- sscanf(buf, "%td %tx %tx %tx %tx %tx %tx %tx %tx", &sc, &arg1, &arg2, &arg3, &arg4,
- &arg5, &arg6, &sp, &pc);
+ int ret = sscanf(buf, "%td %tx %tx %tx %tx %tx %tx %tx %tx", &sc, &arg1, &arg2, &arg3, &arg4,
+ &arg5, &arg6, &sp, &pc);
if (ret == 9) {
- LOG_W
- ("PID: %d, Syscall number: %td, Arguments: %#tx, %#tx, %#tx, %#tx, %#tx, %#tx, SP: %#tx, PC: %#tx, si_syscall: %d, si_errno: %#x",
- (int)si->si_pid, sc, arg1, arg2, arg3, arg4, arg5, arg6, sp, pc,
- si->si_syscall, si->si_errno);
+ LOG_W("PID: %d, Syscall number: %td, Arguments: %#tx, %#tx, %#tx, %#tx, %#tx, %#tx, SP: %#tx, PC: %#tx, si_syscall: %d, si_errno: %#x",
+ (int)si->si_pid, sc, arg1, arg2, arg3, arg4, arg5, arg6, sp, pc,
+ si->si_syscall, si->si_errno);
} else if (ret == 3) {
LOG_W("PID: %d, Syscall number: %d, Seccomp reason: %d, SP: %#tx, PC: %#tx",
- (int)si->si_pid, si->si_syscall, si->si_errno, arg1, arg2);
+ (int)si->si_pid, si->si_syscall, si->si_errno, arg1, arg2);
} else {
LOG_W("PID: %d, Syscall number: %d, Seccomp reason: %d, Syscall string '%s'",
- (int)si->si_pid, si->si_syscall, si->si_errno, buf);
+ (int)si->si_pid, si->si_syscall, si->si_errno, buf);
}
}
-int subprocReap(struct nsjconf_t *nsjconf)
+int subprocReap(struct nsjconf_t* nsjconf)
{
int status;
int rv = 0;
if (wait4(si.si_pid, &status, WNOHANG, NULL) == si.si_pid) {
cgroupFinishFromParent(nsjconf, si.si_pid);
- const char *remote_txt = "[UNKNOWN]";
- struct pids_t *elem = subprocGetPidElem(nsjconf, si.si_pid);
+ const char* remote_txt = "[UNKNOWN]";
+ struct pids_t* elem = subprocGetPidElem(nsjconf, si.si_pid);
if (elem) {
remote_txt = elem->remote_txt;
}
if (WIFEXITED(status)) {
LOG_I("PID: %d (%s) exited with status: %d, (PIDs left: %d)",
- si.si_pid, remote_txt, WEXITSTATUS(status),
- subprocCount(nsjconf) - 1);
+ si.si_pid, remote_txt, WEXITSTATUS(status),
+ subprocCount(nsjconf) - 1);
subprocRemove(nsjconf, si.si_pid);
rv = WEXITSTATUS(status) % 100;
if (rv == 0 && WEXITSTATUS(status) != 0) {
}
}
if (WIFSIGNALED(status)) {
- LOG_I
- ("PID: %d (%s) terminated with signal: %s (%d), (PIDs left: %d)",
- si.si_pid, remote_txt, utilSigName(WTERMSIG(status)),
- WTERMSIG(status), subprocCount(nsjconf) - 1);
+ LOG_I("PID: %d (%s) terminated with signal: %s (%d), (PIDs left: %d)",
+ si.si_pid, remote_txt, utilSigName(WTERMSIG(status)),
+ WTERMSIG(status), subprocCount(nsjconf) - 1);
subprocRemove(nsjconf, si.si_pid);
rv = 100 + WTERMSIG(status);
}
}
time_t now = time(NULL);
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
if (nsjconf->tlimit == 0) {
continue;
}
time_t diff = now - p->start;
if (diff >= nsjconf->tlimit) {
LOG_I("PID: %d run time >= time limit (%ld >= %ld) (%s). Killing it", pid,
- (long)diff, (long)nsjconf->tlimit, p->remote_txt);
+ (long)diff, (long)nsjconf->tlimit, p->remote_txt);
/*
* Probably a kernel bug - some processes cannot be killed with KILL if
* they're namespaced, and in a stopped state
return rv;
}
-void subprocKillAll(struct nsjconf_t *nsjconf)
+void subprocKillAll(struct nsjconf_t* nsjconf)
{
- struct pids_t *p;
- TAILQ_FOREACH(p, &nsjconf->pids, pointers) {
+ struct pids_t* p;
+ TAILQ_FOREACH(p, &nsjconf->pids, pointers)
+ {
kill(p->pid, SIGKILL);
}
}
-static bool subprocInitParent(struct nsjconf_t *nsjconf, pid_t pid, int pipefd)
+static bool subprocInitParent(struct nsjconf_t* nsjconf, pid_t pid, int pipefd)
{
if (netInitNsFromParent(nsjconf, pid) == false) {
LOG_E("Couldn't create and put MACVTAP interface into NS of PID '%d'", pid);
LOG_E("Couldn't initialize user namespaces for pid %d", pid);
return false;
}
- if (utilWriteToFd(pipefd, &subprocDoneChar, sizeof(subprocDoneChar)) !=
- sizeof(subprocDoneChar)) {
+ if (utilWriteToFd(pipefd, &subprocDoneChar, sizeof(subprocDoneChar)) != sizeof(subprocDoneChar)) {
LOG_E("Couldn't signal the new process via a socketpair");
return false;
}
}
/* Will be used inside the child process only, so it's save to have it in BSS */
-static uint8_t subprocCloneStack[128 * 1024]; /* 128 KiB */
+static uint8_t subprocCloneStack[128 * 1024]; /* 128 KiB */
/* Cannot be on the stack, as the child's stack pointer will change after clone() */
static __thread jmp_buf env;
-static int subprocCloneFunc(void *arg __attribute__ ((unused)))
+static int subprocCloneFunc(void* arg __attribute__((unused)))
{
longjmp(env, 1);
return 0;
* Avoid the problem of the stack growing up/down under different CPU architectures, by using
* middle of the static stack buffer (which is temporary, and used only inside of subprocCloneFunc
*/
- void *stack = &subprocCloneStack[sizeof(subprocCloneStack) / 2];
+ void* stack = &subprocCloneStack[sizeof(subprocCloneStack) / 2];
/* Parent */
return clone(subprocCloneFunc, stack, flags, NULL, NULL, NULL);
}
return 0;
}
-void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err)
+void subprocRunChild(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err)
{
if (netLimitConns(nsjconf, fd_in) == false) {
return;
PLOG_E("clone(flags=%s) failed. You probably need root privileges if your system "
"doesn't support CLONE_NEWUSER. Alternatively, you might want to recompile your "
"kernel with support for namespaces or check the setting of the "
- "kernel.unprivileged_userns_clone sysctl", subprocCloneFlagsToStr(flags));
+ "kernel.unprivileged_userns_clone sysctl",
+ subprocCloneFlagsToStr(flags));
close(parent_fd);
return;
}
close(parent_fd);
char cs_addr[64];
- netConnToText(fd_in, true /* remote */ , cs_addr, sizeof(cs_addr), NULL);
+ netConnToText(fd_in, true /* remote */, cs_addr, sizeof(cs_addr), NULL);
}
-int subprocSystem(const char **argv, char **env)
+int subprocSystem(const char** argv, char** env)
{
bool exec_failed = false;
if (pid == 0) {
close(sv[0]);
- execve(argv[0], (char *const *)argv, (char *const *)env);
+ execve(argv[0], (char* const*)argv, (char* const*)env);
PLOG_W("execve('%s')", argv[0]);
utilWriteToFd(sv[1], "A", 1);
exit(0);
if (WIFSIGNALED(status)) {
int exit_signal = WTERMSIG(status);
LOG_W("PID %d killed by signal: %d (%s)", pid, exit_signal,
- utilSigName(exit_signal));
+ utilSigName(exit_signal));
return 2;
}
LOG_W("Unknown exit status: %d", status);
#include <inttypes.h>
#include <unistd.h>
-void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err);
-int subprocCount(struct nsjconf_t *nsjconf);
-void subprocDisplay(struct nsjconf_t *nsjconf);
-void subprocKillAll(struct nsjconf_t *nsjconf);
-int subprocSystem(const char **argv, char **env);
+void subprocRunChild(struct nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err);
+int subprocCount(struct nsjconf_t* nsjconf);
+void subprocDisplay(struct nsjconf_t* nsjconf);
+void subprocKillAll(struct nsjconf_t* nsjconf);
+int subprocSystem(const char** argv, char** env);
pid_t subprocClone(uintptr_t flags);
-void subprocCloneFlags(struct nsjconf_t *nsjconf);
+void subprocCloneFlags(struct nsjconf_t* nsjconf);
/* Returns the exit code of the first failing subprocess, or 0 if none fail */
-int subprocReap(struct nsjconf_t *nsjconf);
+int subprocReap(struct nsjconf_t* nsjconf);
-#endif /* NS_PROC_H */
+#endif /* NS_PROC_H */
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/setgroups", pid);
- const char *denystr = "deny";
+ const char* denystr = "deny";
if (utilWriteBufToFile(fname, denystr, strlen(denystr), O_WRONLY) == false) {
LOG_E("utilWriteBufToFile('%s', '%s') failed", fname, denystr);
return false;
return true;
}
-static bool userUidMapSelf(struct nsjconf_t *nsjconf, pid_t pid)
+static bool userUidMapSelf(struct nsjconf_t* nsjconf, pid_t pid)
{
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/uid_map", pid);
char map[4096] = {[0] = '\0' };
- struct idmap_t *p;
- TAILQ_FOREACH(p, &nsjconf->uids, pointers) {
+ struct idmap_t* p;
+ TAILQ_FOREACH(p, &nsjconf->uids, pointers)
+ {
if (p->is_newidmap) {
continue;
}
utilSSnPrintf(map, sizeof(map), "%lu %lu %zu\n", (unsigned long)p->inside_id,
- (unsigned long)p->outside_id, p->count);
+ (unsigned long)p->outside_id, p->count);
}
if (strlen(map) == 0) {
return true;
}
-static bool userGidMapSelf(struct nsjconf_t *nsjconf, pid_t pid)
+static bool userGidMapSelf(struct nsjconf_t* nsjconf, pid_t pid)
{
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "/proc/%d/gid_map", pid);
char map[4096] = {[0] = '\0' };
- struct idmap_t *p;
- TAILQ_FOREACH(p, &nsjconf->gids, pointers) {
+ struct idmap_t* p;
+ TAILQ_FOREACH(p, &nsjconf->gids, pointers)
+ {
if (p->is_newidmap) {
continue;
}
utilSSnPrintf(map, sizeof(map), "%lu %lu %zu\n", (unsigned long)p->inside_id,
- (unsigned long)p->outside_id, p->count);
+ (unsigned long)p->outside_id, p->count);
}
if (strlen(map) == 0) {
}
/* Use /usr/bin/newgidmap for writing the gid map */
-static bool userGidMapExternal(struct nsjconf_t *nsjconf, pid_t pid UNUSED)
+static bool userGidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED)
{
static size_t idx = 0;
- const char *argv[1024];
+ const char* argv[1024];
char parms[1024][256];
argv[idx++] = "/usr/bin/newgidmap";
argv[idx] = parms[idx];
idx++;
- struct idmap_t *p;
+ struct idmap_t* p;
bool use = false;
- TAILQ_FOREACH(p, &nsjconf->gids, pointers) {
+ TAILQ_FOREACH(p, &nsjconf->gids, pointers)
+ {
if (p->is_newidmap == false) {
continue;
}
}
/* Use /usr/bin/newuidmap for writing the uid map */
-static bool userUidMapExternal(struct nsjconf_t *nsjconf, pid_t pid UNUSED)
+static bool userUidMapExternal(struct nsjconf_t* nsjconf, pid_t pid UNUSED)
{
static size_t idx = 0;
- const char *argv[1024];
+ const char* argv[1024];
char parms[1024][256];
argv[idx++] = "/usr/bin/newuidmap";
idx++;
bool use = false;
- struct idmap_t *p;
- TAILQ_FOREACH(p, &nsjconf->uids, pointers) {
+ struct idmap_t* p;
+ TAILQ_FOREACH(p, &nsjconf->uids, pointers)
+ {
if (p->is_newidmap == false) {
continue;
}
return true;
}
-static bool userUidGidMap(struct nsjconf_t *nsjconf, pid_t pid)
+static bool userUidGidMap(struct nsjconf_t* nsjconf, pid_t pid)
{
if (!userGidMapSelf(nsjconf, pid)) {
return false;
return true;
}
-bool userInitNsFromParent(struct nsjconf_t * nsjconf, pid_t pid)
+bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid)
{
if (userSetGroups(pid) == false) {
return false;
return true;
}
-bool userInitNsFromChild(struct nsjconf_t * nsjconf)
+bool userInitNsFromChild(struct nsjconf_t* nsjconf)
{
/*
* Best effort because of /proc/self/setgroups
*/
LOG_D("setgroups(0, NULL)");
- gid_t *group_list = NULL;
+ gid_t* group_list = NULL;
if (setgroups(0, group_list) == -1) {
PLOG_D("setgroups(NULL) failed");
}
* Make sure all capabilities are retained after the subsequent setuid/setgid, as they will be
* needed for privileged operations: mounts, uts change etc.
*/
- if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_NO_SETUID_FIXUP, 0UL, 0UL, 0UL) ==
- -1) {
+ if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_NO_SETUID_FIXUP, 0UL, 0UL, 0UL) == -1) {
PLOG_E("prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_NO_SETUID_FIXUP)");
return false;
}
LOG_D("setresgid(%d, %d, %d)", TAILQ_FIRST(&nsjconf->gids)->inside_id,
- TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id);
+ TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id);
if (syscall(__NR_setresgid, TAILQ_FIRST(&nsjconf->gids)->inside_id,
- TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id)
+ TAILQ_FIRST(&nsjconf->gids)->inside_id, TAILQ_FIRST(&nsjconf->gids)->inside_id)
== -1) {
PLOG_E("setresgid(%u)", TAILQ_FIRST(&nsjconf->gids)->inside_id);
return false;
}
LOG_D("setresuid(%d, %d, %d)", TAILQ_FIRST(&nsjconf->uids)->inside_id,
- TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id);
+ TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id);
if (syscall(__NR_setresuid, TAILQ_FIRST(&nsjconf->uids)->inside_id,
- TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id)
+ TAILQ_FIRST(&nsjconf->uids)->inside_id, TAILQ_FIRST(&nsjconf->uids)->inside_id)
== -1) {
PLOG_E("setresuid(%u)", TAILQ_FIRST(&nsjconf->uids)->inside_id);
return false;
return true;
}
-static uid_t cmdParseUid(const char *id)
+static uid_t cmdParseUid(const char* id)
{
if (id == NULL || strlen(id) == 0) {
return getuid();
}
- struct passwd *pw = getpwnam(id);
+ struct passwd* pw = getpwnam(id);
if (pw != NULL) {
return pw->pw_uid;
}
if (utilIsANumber(id)) {
- return (uid_t) strtoull(id, NULL, 0);
+ return (uid_t)strtoull(id, NULL, 0);
}
return -1;
}
-static gid_t cmdParseGid(const char *id)
+static gid_t cmdParseGid(const char* id)
{
if (id == NULL || strlen(id) == 0) {
return getgid();
}
- struct group *gr = getgrnam(id);
+ struct group* gr = getgrnam(id);
if (gr != NULL) {
return gr->gr_gid;
}
if (utilIsANumber(id)) {
- return (gid_t) strtoull(id, NULL, 0);
+ return (gid_t)strtoull(id, NULL, 0);
}
return -1;
}
-bool userParseId(struct nsjconf_t * nsjconf, const char *i_id, const char *o_id, size_t cnt,
- bool is_gid, bool is_newidmap)
+bool userParseId(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);
- if (inside_id == (uid_t) - 1) {
+ if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", i_id);
return false;
}
outside_id = cmdParseGid(o_id);
- if (inside_id == (uid_t) - 1) {
+ if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as GID", o_id);
return false;
}
} else {
inside_id = cmdParseUid(i_id);
- if (inside_id == (uid_t) - 1) {
+ if (inside_id == (uid_t)-1) {
LOG_W("Cannot parse '%s' as UID", i_id);
return false;
}
outside_id = cmdParseUid(o_id);
- if (inside_id == (uid_t) - 1) {
+ if (inside_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 = utilMalloc(sizeof(struct idmap_t));
p->inside_id = inside_id;
p->outside_id = outside_id;
p->count = cnt;
#include "common.h"
-bool userInitNsFromParent(struct nsjconf_t *nsjconf, pid_t pid);
-bool userInitNsFromChild(struct nsjconf_t *nsjconf);
+bool userInitNsFromParent(struct nsjconf_t* nsjconf, pid_t pid);
+bool userInitNsFromChild(struct nsjconf_t* nsjconf);
-bool userParseId(struct nsjconf_t *nsjconf, const char *i_id, const char *o_id, size_t cnt,
- bool is_gid, bool is_newidmap);
+bool userParseId(struct nsjconf_t* nsjconf, const char* i_id, const char* o_id, size_t cnt,
+ bool is_gid, bool is_newidmap);
-#endif /* NS_USER_H */
+#endif /* NS_USER_H */
#include "log.h"
-void *utilMalloc(size_t sz)
+void* utilMalloc(size_t sz)
{
- void *ret = malloc(sz);
+ void* ret = malloc(sz);
if (ret == NULL) {
LOG_F("malloc(sz=%zu) failed", sz);
}
return ret;
}
-void *utilCalloc(size_t sz)
+void* utilCalloc(size_t sz)
{
- void *r = utilMalloc(sz);
+ void* r = utilMalloc(sz);
memset(r, '\0', sz);
return r;
}
-char *utilStrDup(const char *str)
+char* utilStrDup(const char* str)
{
if (str == NULL) {
return NULL;
}
- char *ret = strdup(str);
+ char* ret = strdup(str);
if (ret == NULL) {
LOG_E("Cannot allocate memory for strdup(sz=%zu)", strlen(str));
}
return ret;
}
-uint8_t *utilMemDup(const uint8_t * src, size_t len)
+uint8_t* utilMemDup(const uint8_t* src, size_t len)
{
if (src == NULL) {
return NULL;
}
- uint8_t *ret = utilMalloc(len);
+ uint8_t* ret = utilMalloc(len);
memcpy(ret, src, len);
return ret;
}
-ssize_t utilReadFromFd(int fd, void *buf, size_t len)
+ssize_t utilReadFromFd(int fd, void* buf, size_t len)
{
- uint8_t *charbuf = (uint8_t *) buf;
+ uint8_t* charbuf = (uint8_t*)buf;
size_t readSz = 0;
while (readSz < len) {
return readSz;
}
-ssize_t utilReadFromFile(const char *fname, void *buf, size_t len)
+ssize_t utilReadFromFile(const char* fname, void* buf, size_t len)
{
int fd;
TEMP_FAILURE_RETRY(fd = open(fname, O_RDONLY | O_CLOEXEC));
return ret;
}
-ssize_t utilWriteToFd(int fd, const void *buf, size_t len)
+ssize_t utilWriteToFd(int fd, const void* buf, size_t len)
{
- const uint8_t *charbuf = (const uint8_t *)buf;
+ const uint8_t* charbuf = (const uint8_t*)buf;
size_t writtenSz = 0;
while (writtenSz < len) {
return true;
}
-bool utilWriteBufToFile(const char *filename, const void *buf, size_t len, int open_flags)
+bool utilWriteBufToFile(const char* filename, const void* buf, size_t len, int open_flags)
{
int fd;
TEMP_FAILURE_RETRY(fd = open(filename, open_flags, 0644));
return true;
}
-bool utilCreateDirRecursively(const char *dir)
+bool utilCreateDirRecursively(const char* dir)
{
if (dir[0] != '/') {
LOG_W("The directory path must start with '/': '%s' provided", dir);
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s", dir);
- char *curr = path;
+ char* curr = path;
for (;;) {
while (*curr == '/') {
curr++;
}
- char *next = strchr(curr, '/');
+ char* next = strchr(curr, '/');
if (next == NULL) {
close(prev_dir_fd);
return true;
}
}
-int utilSSnPrintf(char *str, size_t size, const char *format, ...)
+int utilSSnPrintf(char* str, size_t size, const char* format, ...)
{
char buf1[size];
char buf2[size];
return snprintf(str, size, "%s%s", buf1, buf2);
}
-bool utilIsANumber(const char *s)
+bool utilIsANumber(const char* s)
{
for (int i = 0; s[i]; s++) {
if (!isdigit(s[i]) && s[i] != 'x') {
if (syscall(__NR_getrandom, &rndX, sizeof(rndX), 0) == sizeof(rndX)) {
return;
}
-#endif /* defined(__NR_getrandom) */
+#endif /* defined(__NR_getrandom) */
int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1) {
PLOG_D("Couldn't open /dev/urandom for reading. Using gettimeofday fall-back");
struct timeval tv;
gettimeofday(&tv, NULL);
- rndX = tv.tv_usec + ((uint64_t) tv.tv_sec << 32);
+ rndX = tv.tv_usec + ((uint64_t)tv.tv_sec << 32);
return;
}
- if (utilReadFromFd(fd, (uint8_t *) & rndX, sizeof(rndX)) != sizeof(rndX)) {
+ if (utilReadFromFd(fd, (uint8_t*)&rndX, sizeof(rndX)) != sizeof(rndX)) {
PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
close(fd);
}
}
#define VALSTR_STRUCT(x) \
- { \
- x, #x \
- }
-const char *utilSigName(int signo)
+ { \
+ x, #x \
+ }
+const char* utilSigName(int signo)
{
static __thread char sigstr[32];
sigstr[0] = '\0';
-// clang-format off
+ // clang-format off
static struct {
const int signo;
const char* const name;
VALSTR_STRUCT(SIGUSR2),
VALSTR_STRUCT(SIGWINCH),
};
-// clang-format on
+ // clang-format on
for (size_t i = 0; i < ARRAYSIZE(sigNames); i++) {
if (signo == sigNames[i].signo) {
}
static __thread char timestr[64];
-const char *utilTimeToStr(time_t t)
+const char* utilTimeToStr(time_t t)
{
struct tm utctime;
localtime_r(&t, &utctime);
#include "common.h"
-void *utilMalloc(size_t sz);
-void *utilCalloc(size_t sz);
-char *utilStrDup(const char *str);
-uint8_t *utilMemDup(const uint8_t * src, size_t len);
-ssize_t utilReadFromFd(int fd, void *buf, size_t len);
-ssize_t utilReadFromFile(const char *fname, void *buf, size_t len);
-ssize_t utilWriteToFd(int fd, const void *buf, size_t len);
-bool utilWriteBufToFile(const char *filename, const void *buf, size_t len, int open_flags);
-bool utilCreateDirRecursively(const char *dir);
-int utilSSnPrintf(char *str, size_t size, const char *format, ...);
-bool utilIsANumber(const char *s);
+void* utilMalloc(size_t sz);
+void* utilCalloc(size_t sz);
+char* utilStrDup(const char* str);
+uint8_t* utilMemDup(const uint8_t* src, size_t len);
+ssize_t utilReadFromFd(int fd, void* buf, size_t len);
+ssize_t utilReadFromFile(const char* fname, void* buf, size_t len);
+ssize_t utilWriteToFd(int fd, const void* buf, size_t len);
+bool utilWriteBufToFile(const char* filename, const void* buf, size_t len, int open_flags);
+bool utilCreateDirRecursively(const char* dir);
+int utilSSnPrintf(char* str, size_t size, const char* format, ...);
+bool utilIsANumber(const char* s);
uint64_t utilRnd64(void);
-const char *utilSigName(int signo);
-const char *utilTimeToStr(time_t t);
+const char* utilSigName(int signo);
+const char* utilTimeToStr(time_t t);
-#endif /* NS_UTIL_H */
+#endif /* NS_UTIL_H */
#include "log.h"
-bool utsInitNs(struct nsjconf_t * nsjconf)
+bool utsInitNs(struct nsjconf_t* nsjconf)
{
if (nsjconf->clone_newuts == false) {
return true;
#include "common.h"
-bool utsInitNs(struct nsjconf_t *nsjconf);
+bool utsInitNs(struct nsjconf_t* nsjconf);
-#endif /* NS_UTS_H */
+#endif /* NS_UTS_H */