diff --git a/Makefile b/Makefile index eea405e..f9c764f 100644 --- a/Makefile +++ b/Makefile @@ -35,8 +35,8 @@ LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs protobuf) BIN = nsjail LIBS = kafel/libkafel.a -SRCS_C = log.c mount.c util.c -SRCS_CXX = caps.cc cgroup.cc cmdline.cc config.cc contain.cc cpu.cc net.cc nsjail.cc pid.cc sandbox.cc subproc.cc uts.cc user.cc +SRCS_C = log.c util.c +SRCS_CXX = caps.cc cgroup.cc cmdline.cc config.cc contain.cc cpu.cc mnt.cc net.cc nsjail.cc pid.cc sandbox.cc subproc.cc uts.cc user.cc SRCS_PROTO = config.proto SRCS_PB_CXX = $(SRCS_PROTO:.proto=.pb.cc) SRCS_PB_H = $(SRCS_PROTO:.proto=.pb.h) @@ -98,17 +98,17 @@ indent: # DO NOT DELETE THIS LINE -- make depend depends on it. log.o: log.h nsjail.h -mount.o: mount.h nsjail.h common.h log.h subproc.h util.h util.o: util.h nsjail.h common.h log.h caps.o: caps.h nsjail.h common.h log.h util.h cgroup.o: cgroup.h nsjail.h log.h util.h -cmdline.o: cmdline.h nsjail.h common.h log.h mount.h util.h caps.h config.h +cmdline.o: cmdline.h nsjail.h log.h util.h caps.h common.h config.h mnt.h cmdline.o: sandbox.h user.h -config.o: common.h config.h nsjail.h log.h mount.h util.h caps.h cmdline.h +config.o: log.h nsjail.h util.h caps.h cmdline.h common.h config.h mnt.h config.o: user.h -contain.o: contain.h nsjail.h log.h mount.h caps.h cgroup.h cpu.h net.h pid.h +contain.o: contain.h nsjail.h log.h caps.h cgroup.h cpu.h mnt.h net.h pid.h contain.o: user.h uts.h cpu.o: cpu.h nsjail.h log.h util.h +mnt.o: mnt.h nsjail.h log.h util.h common.h subproc.h net.o: net.h nsjail.h log.h subproc.h nsjail.o: nsjail.h cmdline.h common.h log.h net.h subproc.h util.h pid.o: pid.h nsjail.h log.h subproc.h diff --git a/cmdline.cc b/cmdline.cc index a87394d..7ff55d3 100644 --- a/cmdline.cc +++ b/cmdline.cc @@ -45,14 +45,14 @@ #include extern "C" { -#include "common.h" #include "log.h" -#include "mount.h" #include "util.h" } #include "caps.h" +#include "common.h" #include "config.h" +#include "mnt.h" #include "sandbox.h" #include "user.h" @@ -241,7 +241,7 @@ void logParams(struct nsjconf_t* nsjconf) { struct mounts_t* p; TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) { LOG_I("%s: %s", p->isSymlink ? "Symlink" : "Mount point", - mountDescribeMountPt(p)); + mnt::describeMountPt(p)); } } { @@ -664,29 +664,29 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { case 'R': { const char* dst = cmdlineSplitStrByColon(optarg); dst = dst ? dst : optarg; - if (!mountAddMountPtTail(nsjconf.get(), /* src= */ optarg, dst, + if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ optarg, dst, /* fs_type= */ "", /* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY, - /* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL, - 0, /* is_symlink= */ false)) { + /* isDir= */ mnt::NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, + NULL, 0, /* is_symlink= */ false)) { return nullptr; } }; break; case 'B': { const char* dst = cmdlineSplitStrByColon(optarg); dst = dst ? dst : optarg; - if (!mountAddMountPtTail(nsjconf.get(), /* src= */ optarg, dst, + if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ optarg, dst, /* fs_type= */ "", /* options= */ "", MS_BIND | MS_REC | MS_PRIVATE, - /* isDir= */ NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, NULL, - 0, /* is_symlink= */ false)) { + /* isDir= */ mnt::NS_DIR_MAYBE, /* mandatory= */ true, NULL, NULL, + NULL, 0, /* is_symlink= */ false)) { return nullptr; } }; break; case 'T': { - if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, optarg, "tmpfs", + if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ NULL, optarg, "tmpfs", /* options= */ cmdlineTmpfsSz, /* flags= */ 0, - /* isDir= */ NS_DIR_YES, + /* isDir= */ mnt::NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) { return nullptr; @@ -786,25 +786,25 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { } if (nsjconf->mount_proc) { - if (!mountAddMountPtTail(nsjconf.get(), /* src= */ NULL, nsjconf->proc_path, "proc", - "", nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ NS_DIR_YES, + if (!mnt::addMountPtTail(nsjconf.get(), /* src= */ NULL, nsjconf->proc_path, "proc", + "", nsjconf->is_proc_rw ? 0 : MS_RDONLY, /* isDir= */ mnt::NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) { return nullptr; } } if (nsjconf->chroot) { - if (!mountAddMountPtHead(nsjconf.get(), nsjconf->chroot, "/", /* fs_type= */ "", + if (!mnt::addMountPtHead(nsjconf.get(), nsjconf->chroot, "/", /* fs_type= */ "", /* options= */ "", nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE) : (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY), - /* isDir= */ NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0, + /* isDir= */ mnt::NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) { return nullptr; } } else { - if (!mountAddMountPtHead(nsjconf.get(), /* src= */ NULL, "/", "tmpfs", + if (!mnt::addMountPtHead(nsjconf.get(), /* src= */ NULL, "/", "tmpfs", /* options= */ "", nsjconf->is_root_rw ? 0 : MS_RDONLY, - /* isDir= */ NS_DIR_YES, + /* isDir= */ mnt::NS_DIR_YES, /* mandatory= */ true, NULL, NULL, NULL, 0, /* is_symlink= */ false)) { return nullptr; } diff --git a/config.cc b/config.cc index 8139740..16eddba 100644 --- a/config.cc +++ b/config.cc @@ -19,9 +19,6 @@ */ -extern "C" { -#include "common.h" - #include #include #include @@ -30,14 +27,16 @@ extern "C" { #include #include -#include "config.h" +extern "C" { #include "log.h" -#include "mount.h" #include "util.h" } #include "caps.h" #include "cmdline.h" +#include "common.h" +#include "config.h" +#include "mnt.h" #include "user.h" #include @@ -232,9 +231,9 @@ static bool configParseInternal(struct nsjconf_t* nsjconf, const nsjail::NsJailC flags |= njc.mount(i).is_bind() ? (MS_BIND | MS_REC | MS_PRIVATE) : 0; bool mandatory = njc.mount(i).mandatory(); - isDir_t isDir = NS_DIR_MAYBE; + mnt::isDir_t isDir = mnt::NS_DIR_MAYBE; if (njc.mount(i).has_is_dir()) { - isDir = njc.mount(i).is_dir() ? NS_DIR_YES : NS_DIR_NO; + isDir = njc.mount(i).is_dir() ? mnt::NS_DIR_YES : mnt::NS_DIR_NO; } const char* src_content = NULL; @@ -244,7 +243,7 @@ static bool configParseInternal(struct nsjconf_t* nsjconf, const nsjail::NsJailC src_content_len = njc.mount(i).src_content().size(); } - if (mountAddMountPtTail(nsjconf, src, dst, fstype, options, flags, isDir, mandatory, + if (mnt::addMountPtTail(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); diff --git a/contain.cc b/contain.cc index 42a0bda..c16f19e 100644 --- a/contain.cc +++ b/contain.cc @@ -39,12 +39,12 @@ extern "C" { #include "log.h" -#include "mount.h" } #include "caps.h" #include "cgroup.h" #include "cpu.h" +#include "mnt.h" #include "net.h" #include "pid.h" #include "user.h" @@ -99,7 +99,7 @@ static bool containPrepareEnv(struct nsjconf_t* nsjconf) { return true; } -static bool containInitMountNs(struct nsjconf_t* nsjconf) { return mountInitNs(nsjconf); } +static bool containInitMountNs(struct nsjconf_t* nsjconf) { return mnt::initNs(nsjconf); } static bool containCPU(struct nsjconf_t* nsjconf) { return cpu::initCpu(nsjconf); } diff --git a/mount.c b/mnt.cc similarity index 84% rename from mount.c rename to mnt.cc index ac117b4..79ae79c 100644 --- a/mount.c +++ b/mnt.cc @@ -19,7 +19,7 @@ */ -#include "mount.h" +#include "mnt.h" #include #include @@ -41,16 +41,21 @@ #include #include -#include "common.h" +extern "C" { #include "log.h" -#include "subproc.h" #include "util.h" +} + +#include "common.h" +#include "subproc.h" + +namespace mnt { #if !defined(MS_LAZYTIME) #define MS_LAZYTIME (1 << 25) #endif /* if !defined(MS_LAZYTIME) */ -const char* mountFlagsToStr(uintptr_t flags) { +const char* flagsToStr(uintptr_t flags) { static __thread char mountFlagsStr[1024]; mountFlagsStr[0] = '\0'; @@ -99,7 +104,7 @@ const char* mountFlagsToStr(uintptr_t flags) { return mountFlagsStr; } -static bool mountIsDir(const char* path) { +static bool isDir(const char* path) { /* * If the source dir is NULL, we assume it's a dir (for /proc and tmpfs) */ @@ -117,11 +122,11 @@ static bool mountIsDir(const char* path) { return false; } -static bool mountMount(struct mounts_t* mpt, const char* newroot, const char* tmpdir) { +static bool mountPt(struct mounts_t* mpt, const char* newroot, const char* tmpdir) { char dst[PATH_MAX]; snprintf(dst, sizeof(dst), "%s/%s", newroot, mpt->dst); - LOG_D("Mounting '%s'", mountDescribeMountPt(mpt)); + LOG_D("Mounting '%s'", describeMountPt(mpt)); char srcpath[PATH_MAX]; if (mpt->src != NULL && strlen(mpt->src) > 0) { @@ -199,9 +204,9 @@ static bool mountMount(struct mounts_t* mpt, const char* newroot, const char* tm "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); + describeMountPt(mpt), srcpath, dst, srcpath); } else { - PLOG_W("mount('%s') src:'%s' dst:'%s' failed", mountDescribeMountPt(mpt), + PLOG_W("mount('%s') src:'%s' dst:'%s' failed", describeMountPt(mpt), srcpath, dst); if (mpt->fs_type && strcmp(mpt->fs_type, "proc") == 0) { PLOG_W( @@ -221,7 +226,7 @@ static bool mountMount(struct mounts_t* mpt, const char* newroot, const char* tm return true; } -static bool mountRemountRO(struct mounts_t* mpt) { +static bool remountRO(struct mounts_t* mpt) { if (!mpt->mounted) { return true; } @@ -260,16 +265,16 @@ static bool mountRemountRO(struct mounts_t* mpt) { } } - LOG_D("Re-mounting R/O '%s' (flags:%s)", mpt->dst, mountFlagsToStr(new_flags)); + LOG_D("Re-mounting R/O '%s' (flags:%s)", mpt->dst, flagsToStr(new_flags)); if (mount(mpt->dst, mpt->dst, NULL, new_flags, 0) == -1) { - PLOG_W("mount('%s', flags:%s)", mpt->dst, mountFlagsToStr(new_flags)); + PLOG_W("mount('%s', flags:%s)", mpt->dst, flagsToStr(new_flags)); return false; } return true; } -static bool mountMkdirAndTest(const char* dir) { +static bool mkdirAndTest(const char* dir) { if (mkdir(dir, 0755) == -1 && errno != EEXIST) { PLOG_D("Couldn't create '%s' directory", dir); return false; @@ -282,28 +287,28 @@ static bool mountMkdirAndTest(const char* dir) { return true; } -static bool mountGetDir(struct nsjconf_t* nsjconf, char* dir, const char* name) { +static bool getDir(struct nsjconf_t* nsjconf, char* dir, const char* name) { snprintf(dir, PATH_MAX, "/run/user/%u/nsjail.%s", nsjconf->orig_uid, name); - if (mountMkdirAndTest(dir)) { + if (mkdirAndTest(dir)) { return true; } snprintf(dir, PATH_MAX, "/tmp/nsjail.%s", name); - if (mountMkdirAndTest(dir)) { + if (mkdirAndTest(dir)) { return true; } const char* tmp = getenv("TMPDIR"); if (tmp) { snprintf(dir, PATH_MAX, "%s/nsjail.%s", tmp, name); - if (mountMkdirAndTest(dir)) { + if (mkdirAndTest(dir)) { return true; } } snprintf(dir, PATH_MAX, "/dev/shm/nsjail.%s", name); - if (mountMkdirAndTest(dir)) { + if (mkdirAndTest(dir)) { return true; } snprintf(dir, PATH_MAX, "/tmp/nsjail.%s.%" PRIx64, name, utilRnd64()); - if (mountMkdirAndTest(dir)) { + if (mkdirAndTest(dir)) { return true; } @@ -311,7 +316,7 @@ static bool mountGetDir(struct nsjconf_t* nsjconf, char* dir, const char* name) return false; } -static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { +static bool initNsInternal(struct nsjconf_t* nsjconf) { /* * If CLONE_NEWNS is not used, we would be changing the global mount namespace, so simply * use --chroot in this case @@ -340,7 +345,7 @@ static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { } char destdir[PATH_MAX]; - if (mountGetDir(nsjconf, destdir, "root") == false) { + if (getDir(nsjconf, destdir, "root") == false) { LOG_E("Couldn't obtain root mount directories"); return false; } @@ -356,7 +361,7 @@ static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { } char tmpdir[PATH_MAX]; - if (mountGetDir(nsjconf, tmpdir, "tmp") == false) { + if (getDir(nsjconf, tmpdir, "tmp") == false) { LOG_E("Couldn't obtain temporary mount directories"); return false; } @@ -367,7 +372,7 @@ static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { struct mounts_t* p; TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) { - if (mountMount(p, destdir, tmpdir) == false && p->mandatory) { + if (mountPt(p, destdir, tmpdir) == false && p->mandatory) { return false; } } @@ -398,7 +403,7 @@ static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { } TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) { - if (mountRemountRO(p) == false && p->mandatory) { + if (remountRO(p) == false && p->mandatory) { return false; } } @@ -410,9 +415,9 @@ static bool mountInitNsInternal(struct nsjconf_t* nsjconf) { * 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 initNs(struct nsjconf_t* nsjconf) { if (nsjconf->mode != MODE_STANDALONE_EXECVE) { - return mountInitNsInternal(nsjconf); + return initNsInternal(nsjconf); } pid_t pid = subprocClone(CLONE_FS | SIGCHLD); @@ -421,7 +426,7 @@ bool mountInitNs(struct nsjconf_t* nsjconf) { } if (pid == 0) { - exit(mountInitNsInternal(nsjconf) ? 0 : 0xff); + exit(initNsInternal(nsjconf) ? 0 : 0xff); } int status; @@ -433,11 +438,12 @@ bool mountInitNs(struct nsjconf_t* nsjconf) { return false; } -static bool mountAddMountPt(struct nsjconf_t* nsjconf, bool head, const char* src, const char* dst, +static bool addMountPt(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 = + reinterpret_cast(utilCalloc(sizeof(struct mounts_t))); if (src_env) { const char* e = getenv(src_env); @@ -488,7 +494,7 @@ static bool mountAddMountPt(struct nsjconf_t* nsjconf, bool head, const char* sr } else if (p->src == NULL) { p->isDir = true; } else if (p->flags & MS_BIND) { - p->isDir = mountIsDir(p->src); + p->isDir = mnt::isDir(p->src); } else { p->isDir = true; } @@ -510,29 +516,27 @@ static bool mountAddMountPt(struct nsjconf_t* nsjconf, bool head, const char* sr 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) { - return mountAddMountPt(nsjconf, /* head= */ true, src, dst, fstype, options, flags, isDir, +bool addMountPtHead(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 addMountPt(nsjconf, /* head= */ true, src, dst, fstype, options, flags, isDir, 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) { - return mountAddMountPt(nsjconf, /* head= */ false, src, dst, fstype, options, flags, isDir, +bool addMountPtTail(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 addMountPt(nsjconf, /* head= */ false, src, dst, fstype, options, flags, isDir, mandatory, src_env, dst_env, src_content, src_content_len, is_symlink); } -const char* mountDescribeMountPt(struct mounts_t* mpt) { +const char* describeMountPt(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]", + flagsToStr(mpt->flags), mpt->options ? mpt->options : "[NULL]", mpt->isDir ? "true" : "false"); if (mpt->mandatory == false) { @@ -548,3 +552,5 @@ const char* mountDescribeMountPt(struct mounts_t* mpt) { return mount_pt_descr; } + +} // namespace mnt diff --git a/mount.h b/mnt.h similarity index 50% rename from mount.h rename to mnt.h index c068888..76cfd95 100644 --- a/mount.h +++ b/mnt.h @@ -19,30 +19,32 @@ */ -#ifndef NS_MOUNT_H -#define NS_MOUNT_H +#ifndef NS_MNT_H +#define NS_MNT_H #include #include #include "nsjail.h" +namespace mnt { + typedef enum { NS_DIR_NO = 0x100, NS_DIR_YES, 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); +const char* flagsToStr(uintptr_t flags); +bool initNs(struct nsjconf_t* nsjconf); +bool addMountPtHead(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 addMountPtTail(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* describeMountPt(struct mounts_t* mpt); -#endif /* NS_MOUNT_H */ +} // namespace mnt + +#endif /* NS_MNT_H */