Add flags printing for clone()

This commit is contained in:
Robert Swiecki 2017-05-21 19:44:54 +02:00
parent 525ba9e2dd
commit a60f84d7e2
3 changed files with 98 additions and 37 deletions

View File

@ -76,7 +76,7 @@ indent:
# DO NOT DELETE THIS LINE -- make depend depends on it.
nsjail.o: nsjail.h common.h cmdline.h log.h net.h subproc.h
cmdline.o: cmdline.h common.h log.h util.h
cmdline.o: cmdline.h common.h log.h mount.h util.h
contain.o: contain.h common.h cgroup.h log.h mount.h net.h pid.h user.h
contain.o: util.h uts.h
log.o: log.h common.h

69
mount.c
View File

@ -40,7 +40,7 @@
#include "subproc.h"
#include "util.h"
#define VALSTR(x) { x, #x }
#define VALSTR_STRUCT(x) { x, #x }
#if !defined(MS_LAZYTIME)
#define MS_LAZYTIME (1<<25)
@ -55,30 +55,30 @@ void mountFlagsToStr(uintptr_t flags, char *str, size_t len)
uintptr_t flag;
const char *name;
} const mountFlags[] = {
VALSTR(MS_RDONLY),
VALSTR(MS_NOSUID),
VALSTR(MS_NODEV),
VALSTR(MS_NOEXEC),
VALSTR(MS_SYNCHRONOUS),
VALSTR(MS_REMOUNT),
VALSTR(MS_MANDLOCK),
VALSTR(MS_DIRSYNC),
VALSTR(MS_NOATIME),
VALSTR(MS_NODIRATIME),
VALSTR(MS_BIND),
VALSTR(MS_MOVE),
VALSTR(MS_REC),
VALSTR(MS_SILENT),
VALSTR(MS_POSIXACL),
VALSTR(MS_UNBINDABLE),
VALSTR(MS_PRIVATE),
VALSTR(MS_SLAVE),
VALSTR(MS_SHARED),
VALSTR(MS_RELATIME),
VALSTR(MS_KERNMOUNT),
VALSTR(MS_I_VERSION),
VALSTR(MS_STRICTATIME),
VALSTR(MS_LAZYTIME),
VALSTR_STRUCT(MS_RDONLY),
VALSTR_STRUCT(MS_NOSUID),
VALSTR_STRUCT(MS_NODEV),
VALSTR_STRUCT(MS_NOEXEC),
VALSTR_STRUCT(MS_SYNCHRONOUS),
VALSTR_STRUCT(MS_REMOUNT),
VALSTR_STRUCT(MS_MANDLOCK),
VALSTR_STRUCT(MS_DIRSYNC),
VALSTR_STRUCT(MS_NOATIME),
VALSTR_STRUCT(MS_NODIRATIME),
VALSTR_STRUCT(MS_BIND),
VALSTR_STRUCT(MS_MOVE),
VALSTR_STRUCT(MS_REC),
VALSTR_STRUCT(MS_SILENT),
VALSTR_STRUCT(MS_POSIXACL),
VALSTR_STRUCT(MS_UNBINDABLE),
VALSTR_STRUCT(MS_PRIVATE),
VALSTR_STRUCT(MS_SLAVE),
VALSTR_STRUCT(MS_SHARED),
VALSTR_STRUCT(MS_RELATIME),
VALSTR_STRUCT(MS_KERNMOUNT),
VALSTR_STRUCT(MS_I_VERSION),
VALSTR_STRUCT(MS_STRICTATIME),
VALSTR_STRUCT(MS_LAZYTIME),
};
/* *INDENT-ON* */
@ -92,7 +92,7 @@ void mountFlagsToStr(uintptr_t flags, char *str, size_t len)
for (size_t i = 0; i < ARRAYSIZE(mountFlags); i++) {
knownFlagMask |= mountFlags[i].flag;
}
utilSSnPrintf(str, len, "0x%#tx", flags & ~(knownFlagMask));
utilSSnPrintf(str, len, "%#tx", flags & ~(knownFlagMask));
}
static bool mountIsDir(const char *path)
@ -197,17 +197,24 @@ static bool mountRemountRO(struct mounts_t *mpt)
}
if (mpt->flags & MS_RDONLY) {
LOG_D("Re-mounting RO '%s'", mpt->dst);
char oldflagstr[4096];
mountFlagsToStr(vfs.f_flag, oldflagstr, sizeof(oldflagstr));
/*
* It's fine to use 'flags | vfs.f_flag' here as per
* /usr/include/x86_64-linux-gnu/bits/statvfs.h: 'Definitions for
* the flag in `f_flag'. These definitions should be
* kept in sync with the definitions in <sys/mount.h>'
*/
if (mount
(mpt->dst, mpt->dst, NULL,
MS_BIND | MS_REMOUNT | MS_RDONLY | vfs.f_flag, 0) == -1) {
PLOG_E("mount('%s', MS_REC|MS_BIND|MS_REMOUNT|MS_RDONLY)", mpt->dst);
unsigned long new_flags = MS_BIND | MS_REMOUNT | MS_RDONLY | vfs.f_flag;
char newflagstr[4096];
mountFlagsToStr(new_flags, newflagstr, sizeof(newflagstr));
LOG_D("Re-mounting RO '%s' (old_flags:%s, new_flags:%s)", mpt->dst, oldflagstr,
newflagstr);
if (mount(mpt->dst, mpt->dst, NULL, new_flags, 0) == -1) {
PLOG_E("mount('%s', flags:%s)", mpt->dst, newflagstr);
return false;
}
}

View File

@ -52,6 +52,59 @@
static const char subprocDoneChar = 'D';
#define VALSTR_STRUCT(x) { x, #x }
#if !defined(CLONE_NEWCGROUP)
#define CLONE_NEWCGROUP 0x02000000
#endif /* !defined(CLONE_NEWCGROUP) */
static void subprocCloneFlagsToStr(uintptr_t flags, char *str, size_t len)
{
str[0] = '\0';
/* *INDENT-OFF* */
static struct {
uintptr_t flag;
const char *name;
} const cloneFlags[] = {
VALSTR_STRUCT(CLONE_VM),
VALSTR_STRUCT(CLONE_FS),
VALSTR_STRUCT(CLONE_FILES),
VALSTR_STRUCT(CLONE_SIGHAND),
VALSTR_STRUCT(CLONE_PTRACE),
VALSTR_STRUCT(CLONE_VFORK),
VALSTR_STRUCT(CLONE_PARENT),
VALSTR_STRUCT(CLONE_THREAD),
VALSTR_STRUCT(CLONE_NEWNS),
VALSTR_STRUCT(CLONE_SYSVSEM),
VALSTR_STRUCT(CLONE_SETTLS),
VALSTR_STRUCT(CLONE_PARENT_SETTID),
VALSTR_STRUCT(CLONE_CHILD_CLEARTID),
VALSTR_STRUCT(CLONE_DETACHED),
VALSTR_STRUCT(CLONE_UNTRACED),
VALSTR_STRUCT(CLONE_CHILD_SETTID),
VALSTR_STRUCT(CLONE_NEWCGROUP),
VALSTR_STRUCT(CLONE_NEWUTS),
VALSTR_STRUCT(CLONE_NEWIPC),
VALSTR_STRUCT(CLONE_NEWUSER),
VALSTR_STRUCT(CLONE_NEWPID),
VALSTR_STRUCT(CLONE_NEWNET),
VALSTR_STRUCT(CLONE_IO),
};
/* *INDENT-ON* */
for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) {
if (flags & cloneFlags[i].flag) {
utilSSnPrintf(str, len, "%s|", cloneFlags[i].name);
}
}
uintptr_t knownFlagMask = 0U;
for (size_t i = 0; i < ARRAYSIZE(cloneFlags); i++) {
knownFlagMask |= cloneFlags[i].flag;
}
utilSSnPrintf(str, len, "%#tx", flags & ~(knownFlagMask));
}
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) {
@ -321,7 +374,9 @@ pid_t subprocClone(uintptr_t flags)
}
if (setjmp(env) == 0) {
LOG_D("Cloning process with flags %#tx", flags);
char cloneflagstr[4096];
subprocCloneFlagsToStr(flags, cloneflagstr, sizeof(cloneflagstr));
LOG_D("Cloning process with flags:%s", cloneflagstr);
/*
* 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
@ -339,9 +394,6 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
if (netLimitConns(nsjconf, fd_in) == false) {
return;
}
#ifndef CLONE_NEWCGROUP
#define CLONE_NEWCGROUP 0x02000000
#endif
unsigned long flags = 0UL;
flags |= (nsjconf->clone_newnet ? CLONE_NEWNET : 0);
flags |= (nsjconf->clone_newuser ? CLONE_NEWUSER : 0);
@ -352,7 +404,9 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
flags |= (nsjconf->clone_newcgroup ? CLONE_NEWCGROUP : 0);
if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
LOG_D("Entering namespace with flags: %#lx", flags);
char cloneflagstr[4096];
subprocCloneFlagsToStr(flags, cloneflagstr, sizeof(cloneflagstr));
LOG_D("Entering namespace with flags:%s", cloneflagstr);
if (unshare(flags) == -1) {
PLOG_E("unshare(%#lx)", flags);
_exit(EXIT_FAILURE);