diff --git a/caps.cc b/caps.cc index e2935d0..96f1361 100644 --- a/caps.cc +++ b/caps.cc @@ -28,6 +28,8 @@ #include #include +#include + #include "logs.h" #include "macros.h" #include "util.h" @@ -90,17 +92,18 @@ int nameToVal(const char* name) { return -1; } -static const char* valToStr(int val) { - static __thread char capsStr[1024]; +static const std::string capToStr(int val) { + std::string res; for (size_t i = 0; i < ARRAYSIZE(capNames); i++) { if (val == capNames[i].val) { - snprintf(capsStr, sizeof(capsStr), "%s", capNames[i].name); - return capsStr; + return capNames[i].name; } } - snprintf(capsStr, sizeof(capsStr), "CAP_UNKNOWN(%d)", val); - return capsStr; + res.append("CAP_UNKNOWN("); + res.append(std::to_string(val)); + res.append(")"); + return res; } static cap_user_data_t getCaps() { @@ -226,10 +229,11 @@ bool initNs(nsjconf_t* nsjconf) { dbgmsg[0] = '\0'; for (const auto& cap : nsjconf->caps) { if (getPermitted(cap_data, cap) == false) { - LOG_W("Capability %s is not permitted in the namespace", valToStr(cap)); + LOG_W("Capability %s is not permitted in the namespace", + capToStr(cap).c_str()); return false; } - util::sSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", valToStr(cap)); + util::sSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capToStr(cap).c_str()); setInheritable(cap_data, cap); } LOG_D("Adding the following capabilities to the inheritable set:%s", dbgmsg); @@ -263,9 +267,10 @@ bool initNs(nsjconf_t* nsjconf) { for (const auto& cap : nsjconf->caps) { if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)cap, 0UL, 0UL) == -1) { - PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", valToStr(cap)); + PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)", + capToStr(cap).c_str()); } else { - util::sSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", valToStr(cap)); + util::sSnPrintf(dbgmsg, sizeof(dbgmsg), " %s", capToStr(cap).c_str()); } } LOG_D("Added the following capabilities to the ambient set:%s", dbgmsg); diff --git a/mnt.cc b/mnt.cc index 4ab11da..bd7a5be 100644 --- a/mnt.cc +++ b/mnt.cc @@ -40,6 +40,8 @@ #include #include +#include + #include "logs.h" #include "macros.h" #include "subproc.h" @@ -51,9 +53,8 @@ namespace mnt { #define MS_LAZYTIME (1 << 25) #endif /* if !defined(MS_LAZYTIME) */ -const char* flagsToStr(uintptr_t flags) { - static __thread char mountFlagsStr[1024]; - mountFlagsStr[0] = '\0'; +static const std::string flagsToStr(uintptr_t flags) { + std::string res; static struct { const uintptr_t flag; @@ -85,19 +86,20 @@ const char* flagsToStr(uintptr_t flags) { NS_VALSTR_STRUCT(MS_LAZYTIME), }; - for (size_t i = 0; i < ARRAYSIZE(mountFlags); i++) { - if (flags & mountFlags[i].flag) { - util::sSnPrintf( - mountFlagsStr, sizeof(mountFlagsStr), "%s|", mountFlags[i].name); - } - } - uintptr_t knownFlagMask = 0U; for (size_t i = 0; i < ARRAYSIZE(mountFlags); i++) { + if (flags & mountFlags[i].flag) { + res.append(mountFlags[i].name); + res.append("|"); + } knownFlagMask |= mountFlags[i].flag; } - util::sSnPrintf(mountFlagsStr, sizeof(mountFlagsStr), "%#tx", flags & ~(knownFlagMask)); - return mountFlagsStr; + + char flagstr[32]; + snprintf(flagstr, sizeof(flagstr), "%#tx", flags & ~(knownFlagMask)); + res.append(flagstr); + + return res; } static bool isDir(const char* path) { @@ -263,9 +265,9 @@ static bool remountRO(const mount_t& mpt) { } } - LOG_D("Re-mounting R/O '%s' (flags:%s)", mpt.dst.c_str(), flagsToStr(new_flags)); + LOG_D("Re-mounting R/O '%s' (flags:%s)", mpt.dst.c_str(), flagsToStr(new_flags).c_str()); if (mount(mpt.dst.c_str(), mpt.dst.c_str(), NULL, new_flags, 0) == -1) { - PLOG_W("mount('%s', flags:%s)", mpt.dst.c_str(), flagsToStr(new_flags)); + PLOG_W("mount('%s', flags:%s)", mpt.dst.c_str(), flagsToStr(new_flags).c_str()); return false; } @@ -532,8 +534,8 @@ const char* describeMountPt(const mount_t& mpt) { snprintf(mount_pt_descr, sizeof(mount_pt_descr), "src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s", mpt.src.c_str(), - mpt.dst.c_str(), mpt.fs_type.c_str(), flagsToStr(mpt.flags), mpt.options.c_str(), - mpt.isDir ? "true" : "false"); + mpt.dst.c_str(), mpt.fs_type.c_str(), flagsToStr(mpt.flags).c_str(), + mpt.options.c_str(), mpt.isDir ? "true" : "false"); if (!mpt.mandatory) { util::sSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " mandatory:false"); diff --git a/mnt.h b/mnt.h index ad2b64b..756e293 100644 --- a/mnt.h +++ b/mnt.h @@ -25,6 +25,8 @@ #include #include +#include + #include "nsjail.h" namespace mnt { @@ -35,7 +37,6 @@ typedef enum { NS_DIR_MAYBE, } isDir_t; -const char* flagsToStr(uintptr_t flags); bool initNs(nsjconf_t* nsjconf); bool addMountPtHead(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, diff --git a/nsjail.cc b/nsjail.cc index 0ad8f90..c97c31a 100644 --- a/nsjail.cc +++ b/nsjail.cc @@ -54,7 +54,7 @@ static void nsjailSig(int sig) { } static bool nsjailSetSigHandler(int sig) { - LOG_D("Setting sighandler for signal %s (%d)", util::sigName(sig), sig); + LOG_D("Setting sighandler for signal %s (%d)", util::sigName(sig).c_str(), sig); sigset_t smask; sigemptyset(&smask); diff --git a/subproc.cc b/subproc.cc index 97187a4..f07a003 100644 --- a/subproc.cc +++ b/subproc.cc @@ -41,6 +41,8 @@ #include #include +#include + #include "cgroup.h" #include "contain.h" #include "logs.h" @@ -56,9 +58,8 @@ namespace subproc { #define CLONE_NEWCGROUP 0x02000000 #endif /* !defined(CLONE_NEWCGROUP) */ -static const char* cloneFlagsToStr(uintptr_t flags) { - static __thread char cloneFlagName[1024]; - cloneFlagName[0] = '\0'; +static const std::string cloneFlagsToStr(uintptr_t flags) { + std::string res; static struct { const uintptr_t flag; @@ -89,23 +90,22 @@ static const char* cloneFlagsToStr(uintptr_t flags) { NS_VALSTR_STRUCT(CLONE_IO), }; - for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) { - if (flags & cloneFlags[i].flag) { - util::sSnPrintf( - cloneFlagName, sizeof(cloneFlagName), "%s|", cloneFlags[i].name); - } - } - uintptr_t knownFlagMask = CSIGNAL; for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) { + if (flags & cloneFlags[i].flag) { + res.append(cloneFlags[i].name); + res.append("|"); + } knownFlagMask |= cloneFlags[i].flag; } + if (flags & ~(knownFlagMask)) { - util::sSnPrintf( - cloneFlagName, sizeof(cloneFlagName), "%#tx|", flags & ~(knownFlagMask)); + char flagstr[32]; + snprintf(flagstr, sizeof(flagstr), "%#tx|", flags & ~(knownFlagMask)); + res.append(flagstr); } - util::sSnPrintf(cloneFlagName, sizeof(cloneFlagName), "%s", util::sigName(flags & CSIGNAL)); - return cloneFlagName; + res.append(util::sigName(flags & CSIGNAL).c_str()); + return res; } /* Reset the execution environment for the new process */ @@ -113,7 +113,7 @@ static bool resetEnv(void) { /* Set all previously changed signals to their default behavior */ for (size_t i = 0; i < ARRAYSIZE(nssigs); i++) { if (signal(nssigs[i], SIG_DFL) == SIG_ERR) { - PLOG_W("signal(%s, SIG_DFL)", util::sigName(nssigs[i])); + PLOG_W("signal(%s, SIG_DFL)", util::sigName(nssigs[i]).c_str()); return false; } } @@ -216,7 +216,7 @@ static void removeProc(nsjconf_t* nsjconf, pid_t pid) { for (auto p = nsjconf->pids.begin(); p != nsjconf->pids.end(); ++p) { if (p->pid == pid) { LOG_D("Removing pid '%d' from the queue (IP:'%s', start time:'%s')", p->pid, - p->remote_txt, util::timeToStr(p->start)); + p->remote_txt, util::timeToStr(p->start).c_str()); close(p->pid_syscall_fd); nsjconf->pids.erase(p); return; @@ -327,7 +327,7 @@ int reapProc(nsjconf_t* nsjconf) { if (WIFSIGNALED(status)) { LOG_I( "PID: %d (%s) terminated with signal: %s (%d), (PIDs left: %d)", - si.si_pid, remote_txt, util::sigName(WTERMSIG(status)), + si.si_pid, remote_txt, util::sigName(WTERMSIG(status)).c_str(), WTERMSIG(status), countProc(nsjconf) - 1); removeProc(nsjconf, si.si_pid); rv = 100 + WTERMSIG(status); @@ -399,16 +399,16 @@ void runChild(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err) { flags |= (nsjconf->clone_newcgroup ? CLONE_NEWCGROUP : 0); if (nsjconf->mode == MODE_STANDALONE_EXECVE) { - LOG_D("Entering namespace with flags:%s", cloneFlagsToStr(flags)); + LOG_D("Entering namespace with flags:%s", cloneFlagsToStr(flags).c_str()); if (unshare(flags) == -1) { - PLOG_E("unshare(%s)", cloneFlagsToStr(flags)); + PLOG_E("unshare(%s)", cloneFlagsToStr(flags).c_str()); _exit(0xff); } subprocNewProc(nsjconf, fd_in, fd_out, fd_err, -1); } flags |= SIGCHLD; - LOG_D("Creating new process with clone flags:%s", cloneFlagsToStr(flags)); + LOG_D("Creating new process with clone flags:%s", cloneFlagsToStr(flags).c_str()); int sv[2]; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) == -1) { @@ -435,7 +435,7 @@ void runChild(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err) { "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", - cloneFlagsToStr(flags)); + cloneFlagsToStr(flags).c_str()); close(parent_fd); return; } @@ -476,7 +476,7 @@ pid_t cloneProc(uintptr_t flags) { } if (setjmp(env) == 0) { - LOG_D("Cloning process with flags:%s", cloneFlagsToStr(flags)); + LOG_D("Cloning process with flags:%s", cloneFlagsToStr(flags).c_str()); /* * 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 @@ -547,7 +547,7 @@ int systemExe(const char** argv, char** env) { if (WIFSIGNALED(status)) { int exit_signal = WTERMSIG(status); LOG_W("PID %d killed by signal: %d (%s)", pid, exit_signal, - util::sigName(exit_signal)); + util::sigName(exit_signal).c_str()); return 2; } LOG_W("Unknown exit status: %d", status); diff --git a/util.cc b/util.cc index 1257c88..90e7a6e 100644 --- a/util.cc +++ b/util.cc @@ -40,6 +40,8 @@ #include #include +#include + #include "logs.h" #include "macros.h" @@ -244,9 +246,8 @@ uint64_t rnd64(void) { return rndX; } -const char* sigName(int signo) { - static __thread char sigstr[32]; - sigstr[0] = '\0'; +const std::string sigName(int signo) { + std::string res; static struct { const int signo; @@ -285,21 +286,27 @@ const char* sigName(int signo) { for (size_t i = 0; i < ARRAYSIZE(sigNames); i++) { if (signo == sigNames[i].signo) { - snprintf(sigstr, sizeof(sigstr), "%s", sigNames[i].name); - return sigstr; + res.append(sigNames[i].name); + return res; } } if (signo > SIGRTMIN) { - snprintf(sigstr, sizeof(sigstr), "SIG%d-RTMIN+%d", signo, signo - SIGRTMIN); - return sigstr; + res.append("SIG"); + res.append(std::to_string(signo)); + res.append("-RTMIN+"); + res.append(std::to_string(signo - SIGRTMIN)); + return res; } - snprintf(sigstr, sizeof(sigstr), "UNKNOWN-%d", signo); - return sigstr; + + res.append("SIGUNKNOWN("); + res.append(std::to_string(signo)); + res.append(")"); + return res; } -static __thread char timestr[64]; -const char* timeToStr(time_t t) { +const std::string timeToStr(time_t t) { + char timestr[128]; struct tm utctime; localtime_r(&t, &utctime); if (strftime(timestr, sizeof(timestr) - 1, "%FT%T%z", &utctime) == 0) { diff --git a/util.h b/util.h index 6af4a01..79ad624 100644 --- a/util.h +++ b/util.h @@ -26,6 +26,8 @@ #include #include +#include + #include "nsjail.h" namespace util { @@ -42,8 +44,8 @@ bool createDirRecursively(const char* dir); int sSnPrintf(char* str, size_t size, const char* format, ...); bool isANumber(const char* s); uint64_t rnd64(void); -const char* sigName(int signo); -const char* timeToStr(time_t t); +const std::string sigName(int signo); +const std::string timeToStr(time_t t); } // namespace util