aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--configure.ac18
-rw-r--r--libsandbox/Makefile.am23
-rw-r--r--libsandbox/trace.c201
-rw-r--r--libsandbox/trace/common.c15
-rw-r--r--libsandbox/trace/linux/x86_64.c87
-rw-r--r--libsandbox/wrapper-funcs/__wrapper_exec.c1
-rw-r--r--scripts/gen_trace_header.awk37
-rw-r--r--src/sandbox.c4
9 files changed, 289 insertions, 99 deletions
diff --git a/.gitignore b/.gitignore
index 209185d..348d86b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,7 @@ Makefile.in
/libsandbox/libsandbox.map
/libsandbox/sb_nr.h
/libsandbox/symbols.h
-/libsandbox/trace.h
+/libsandbox/trace_syscalls*.h
/src/sandbox
/src/sandbox.sh
diff --git a/configure.ac b/configure.ac
index 6e93025..a7c52b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,24 @@ AC_PROG_LIBTOOL
AC_PREFIX_DEFAULT([/usr])
+dnl multiple personality support (x86 & x86_64: multilib)
+AC_MSG_CHECKING([for multiple personalities])
+AC_ARG_ENABLE([schizo],
+ [AC_HELP_STRING([--enable-schizo],[Support multiple personalities])],
+ [],[enable_schizo="yes"])
+SB_SCHIZO_SETTINGS="no"
+if test "x$enable_schizo" = "xyes" ; then
+ case $host_alias in
+ x86_64*linux*) SB_SCHIZO_SETTINGS="x86_64:-m64 x86:-m32";;
+ esac
+fi
+if test "$SB_SCHIZO_SETTINGS" != "no" ; then
+ AC_DEFINE_UNQUOTED([SB_SCHIZO], ["$SB_SCHIZO_SETTINGS"], [Enable multiple personalities support])
+fi
+AC_SUBST(SB_SCHIZO_SETTINGS)
+AM_CONDITIONAL([SB_SCHIZO], test "$SB_SCHIZO_SETTINGS" != "no")
+AC_MSG_RESULT($SB_SCHIZO_SETTINGS)
+
dnl this test fills up the stack and then triggers a segfault ...
dnl but it's hard to wrap things without a stack, so let's ignore
dnl this test for now ...
diff --git a/libsandbox/Makefile.am b/libsandbox/Makefile.am
index 03e2d8c..01b9144 100644
--- a/libsandbox/Makefile.am
+++ b/libsandbox/Makefile.am
@@ -37,7 +37,7 @@ libsandbox_la_SOURCES = \
canonicalize.c
libsandbox.c: libsandbox.map sb_nr.h
-trace.c: trace.h sb_nr.h $(TRACE_FILES)
+trace.c: trace_syscalls.h sb_nr.h $(TRACE_FILES)
wrappers.c: symbols.h
TRACE_FILES = $(wildcard $(srcdir)/trace/*.[ch] $(srcdir)/trace/*/*.[ch])
@@ -62,10 +62,25 @@ SB_NR_FILE = $(srcdir)/sb_nr.h.in
sb_nr.h: symbols.h $(SB_NR_FILE)
$(EGREP) -h '^\#define SB_' $^ > $@
-trace.h: $(GEN_TRACE_SCRIPT)
- $(COMPILE) -E -dD $(top_srcdir)/headers.h | $(SB_AWK) $(GEN_TRACE_SCRIPT) > $@
+TRACE_MAKE_HEADER = \
+ $(SB_AWK) $(GEN_TRACE_SCRIPT) -v MODE=gen | \
+ $(COMPILE) -E -include $(top_srcdir)/headers.h - $$f | \
+ $(SB_AWK) $(GEN_TRACE_SCRIPT) -v syscall_prefix=$$t > $$header
+trace_syscalls.h: $(GEN_TRACE_SCRIPT)
+if SB_SCHIZO
+ for pers in $(SB_SCHIZO_SETTINGS) ; do \
+ t=_$${pers%:*}; \
+ f=$${pers#*:}; \
+ header=trace_syscalls$${t}.h; \
+ $(TRACE_MAKE_HEADER) || exit $$?; \
+ done
+ touch $@
+else
+ t= f= header=$@; \
+ $(TRACE_MAKE_HEADER)
+endif
EXTRA_DIST = $(SYMBOLS_FILE) $(SYMBOLS_WRAPPERS) $(SB_NR_FILE) $(TRACE_FILES)
-CLEANFILES = libsandbox.map sb_nr.h symbols.h trace.h
+CLEANFILES = libsandbox.map sb_nr.h symbols.h trace_syscalls*.h
DISTCLEANFILES = $(CLEANFILES)
diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 7e44bf6..fc58ab1 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -40,8 +40,8 @@ static long _do_ptrace(enum __ptrace_request request, const char *srequest, void
goto try_again;
}
- SB_EERROR("ISE:trace_loop ", "ptrace(%s): %s\n",
- srequest, strerror(errno));
+ SB_EERROR("ISE:_do_ptrace ", "ptrace(%s, ..., %p, %p): %s\n",
+ srequest, addr, data, strerror(errno));
sb_abort();
}
return ret;
@@ -68,6 +68,10 @@ static char *do_peekstr(unsigned long lptr)
char x[sizeof(long)];
} s;
+ /* if someone does open(NULL), don't shit a brick over it */
+ if (lptr < sizeof(long))
+ return NULL;
+
l = 0;
len = 1024;
ret = xmalloc(len);
@@ -88,9 +92,41 @@ static char *do_peekstr(unsigned long lptr)
}
}
+static const char *strcld_chld(int cld)
+{
+ switch (cld) {
+#define C(c) case CLD_##c: return "CLD"#c;
+ C(CONTINUED)
+ C(DUMPED)
+ C(EXITED)
+ C(KILLED)
+ C(TRAPPED)
+ C(STOPPED)
+#undef C
+ default: return "CLD???";
+ }
+}
+/* strsignal() translates the string when i want C define */
+static const char *strsig(int sig)
+{
+ switch (sig) {
+#define S(s) case SIG##s: return "SIG"#s;
+ S(CHLD)
+ S(CONT)
+ S(KILL)
+ S(TRAP)
+ S(STOP)
+#undef S
+ default: return "SIG???";
+ }
+}
+
static void trace_child_signal(int signo, siginfo_t *info, void *context)
{
- SB_DEBUG("got sig %i: code:%i status:%i", signo, info->si_code, info->si_status);
+ SB_DEBUG("got sig %s(%i): code:%s(%i) status:%s(%i)",
+ strsig(signo), signo,
+ strcld_chld(info->si_code), info->si_code,
+ strsig(info->si_status), info->si_status);
switch (info->si_code) {
case CLD_KILLED:
@@ -117,68 +153,66 @@ static void trace_child_signal(int signo, siginfo_t *info, void *context)
signo, info->si_code, info->si_status);
}
-static const struct {
- const int nr;
- const char *name;
-} syscalls[] = {
-#define S(s) { SYS_##s, #s },
-#include "trace.h"
-#undef S
-};
-static const char *sysname(int nr)
+static const struct syscall_entry *lookup_syscall_in_tbl(const struct syscall_entry *tbl, int nr)
+{
+ while (tbl->name)
+ if (tbl->nr == nr)
+ return tbl;
+ else
+ ++tbl;
+ return NULL;
+}
+static const struct syscall_entry *lookup_syscall(int nr)
{
- size_t i;
- for (i = 0; i < ARRAY_SIZE(syscalls); ++i)
- if (syscalls[i].nr == nr)
- return syscalls[i].name;
- return "unk";
+ return lookup_syscall_in_tbl(trace_check_personality(), nr);
}
-static bool _trace_check_syscall_C(void *vregs, int sb_nr, const char *func, int ibase)
+static bool _trace_check_syscall_C(void *regs, int sb_nr, const char *func, int ibase)
{
- char *path = do_peekstr(trace_arg(vregs, ibase));
+ char *path = do_peekstr(trace_arg(regs, ibase));
__SB_DEBUG("(\"%s\")", path);
bool ret = _SB_SAFE(sb_nr, func, path);
free(path);
return ret;
}
-static bool trace_check_syscall_C(void *vregs, int sb_nr, const char *func)
+static bool trace_check_syscall_C(void *regs, int sb_nr, const char *func)
{
- return _trace_check_syscall_C(vregs, sb_nr, func, 1);
+ return _trace_check_syscall_C(regs, sb_nr, func, 1);
}
-static bool __trace_check_syscall_DCF(void *vregs, int sb_nr, const char *func, int ibase, int flags)
+static bool __trace_check_syscall_DCF(void *regs, int sb_nr, const char *func, int ibase, int flags)
{
- int dirfd = trace_arg(vregs, ibase);
- char *path = do_peekstr(trace_arg(vregs, ibase + 1));
+ int dirfd = trace_arg(regs, ibase);
+ char *path = do_peekstr(trace_arg(regs, ibase + 1));
__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
bool ret = _SB_SAFE_AT(sb_nr, func, dirfd, path, flags);
free(path);
return ret;
}
-static bool _trace_check_syscall_DCF(void *vregs, int sb_nr, const char *func, int ibase)
+static bool _trace_check_syscall_DCF(void *regs, int sb_nr, const char *func, int ibase)
{
- int flags = trace_arg(vregs, ibase + 2);
- return __trace_check_syscall_DCF(vregs, sb_nr, func, ibase, flags);
+ int flags = trace_arg(regs, ibase + 2);
+ return __trace_check_syscall_DCF(regs, sb_nr, func, ibase, flags);
}
-static bool trace_check_syscall_DCF(void *vregs, int sb_nr, const char *func)
+static bool trace_check_syscall_DCF(void *regs, int sb_nr, const char *func)
{
- return _trace_check_syscall_DCF(vregs, sb_nr, func, 1);
+ return _trace_check_syscall_DCF(regs, sb_nr, func, 1);
}
-static bool _trace_check_syscall_DC(void *vregs, int sb_nr, const char *func, int ibase)
+static bool _trace_check_syscall_DC(void *regs, int sb_nr, const char *func, int ibase)
{
- return __trace_check_syscall_DCF(vregs, sb_nr, func, ibase, 0);
+ return __trace_check_syscall_DCF(regs, sb_nr, func, ibase, 0);
}
-static bool trace_check_syscall_DC(void *vregs, int sb_nr, const char *func)
+static bool trace_check_syscall_DC(void *regs, int sb_nr, const char *func)
{
- return _trace_check_syscall_DC(vregs, sb_nr, func, 1);
+ return _trace_check_syscall_DC(regs, sb_nr, func, 1);
}
-static bool trace_check_syscall(int nr, void *vregs)
+static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
{
- struct user_regs_struct *regs = vregs;
bool ret = true;
+ int nr;
+ const char *name;
/* These funcs aren't syscalls and so there are no checks:
* - fopen
@@ -192,67 +226,72 @@ static bool trace_check_syscall(int nr, void *vregs)
* Can't use switch() statement here as we auto define missing
* SYS_xxx to SB_NR_UNDEF in the build system
*/
- if (nr == SB_NR_UNDEF)
+ if (!se)
goto done;
- else if (nr == SYS_chmod) return trace_check_syscall_C (vregs, SB_NR_CHMOD, "chmod");
- else if (nr == SYS_chown) return trace_check_syscall_C (vregs, SB_NR_CHOWN, "chown");
- else if (nr == SYS_creat) return trace_check_syscall_C (vregs, SB_NR_CREAT, "creat");
- else if (nr == SYS_fchmodat) return trace_check_syscall_DCF(vregs, SB_NR_FCHMODAT, "fchmodat");
- else if (nr == SYS_fchownat) return trace_check_syscall_DCF(vregs, SB_NR_FCHOWNAT, "fchownat");
- else if (nr == SYS_futimesat) return trace_check_syscall_DC (vregs, SB_NR_FUTIMESAT, "futimesat");
- else if (nr == SYS_lchown) return trace_check_syscall_C (vregs, SB_NR_LCHOWN, "lchown");
- else if (nr == SYS_link) return _trace_check_syscall_C (vregs, SB_NR_LINK, "link", 2);
- else if (nr == SYS_linkat) return _trace_check_syscall_DCF(vregs, SB_NR_LINKAT, "linkat", 3);
- else if (nr == SYS_mkdir) return trace_check_syscall_C (vregs, SB_NR_MKDIR, "mkdir");
- else if (nr == SYS_mkdirat) return trace_check_syscall_DC (vregs, SB_NR_MKDIRAT, "mkdirat");
- else if (nr == SYS_mknod) return trace_check_syscall_C (vregs, SB_NR_MKNOD, "mknod");
- else if (nr == SYS_mknodat) return trace_check_syscall_DC (vregs, SB_NR_MKNODAT, "mknodat");
- else if (nr == SYS_rename) return trace_check_syscall_C (vregs, SB_NR_RENAME, "rename") &&
- _trace_check_syscall_C (vregs, SB_NR_RENAME, "rename", 2);
- else if (nr == SYS_renameat) return trace_check_syscall_DC (vregs, SB_NR_RENAMEAT, "renameat") &&
- _trace_check_syscall_DC (vregs, SB_NR_RENAMEAT, "renameat", 3);
- else if (nr == SYS_rmdir) return trace_check_syscall_C (vregs, SB_NR_RMDIR, "rmdir");
- else if (nr == SYS_symlink) return _trace_check_syscall_C (vregs, SB_NR_SYMLINK, "symlink", 2);
- else if (nr == SYS_symlinkat) return _trace_check_syscall_DC (vregs, SB_NR_SYMLINKAT, "symlinkat", 2);
- else if (nr == SYS_truncate) return trace_check_syscall_C (vregs, SB_NR_TRUNCATE, "truncate");
- else if (nr == SYS_truncate64)return trace_check_syscall_C (vregs, SB_NR_TRUNCATE64, "truncate64");
- else if (nr == SYS_unlink) return trace_check_syscall_C (vregs, SB_NR_UNLINK, "unlink");
- else if (nr == SYS_unlinkat) return trace_check_syscall_DCF(vregs, SB_NR_UNLINKAT, "unlinkat");
- else if (nr == SYS_utime) return trace_check_syscall_C (vregs, SB_NR_UTIME, "utime");
- else if (nr == SYS_utimes) return trace_check_syscall_C (vregs, SB_NR_UTIMES, "utimes");
- else if (nr == SYS_utimensat) return trace_check_syscall_DCF(vregs, SB_NR_UTIMENSAT, "utimensat");
-
- else if (nr == SYS_access) {
+
+ nr = se->sys;
+ name = se->name;
+ /* Hmm, add these functions to the syscall table and avoid this if() ? */
+ if (nr == SB_NR_UNDEF) goto done;
+ else if (nr == SB_NR_CHMOD) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_CHOWN) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_CREAT) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_FCHMODAT) return trace_check_syscall_DCF(regs, nr, name);
+ else if (nr == SB_NR_FCHOWNAT) return trace_check_syscall_DCF(regs, nr, name);
+ else if (nr == SB_NR_FUTIMESAT) return trace_check_syscall_DC (regs, nr, name);
+ else if (nr == SB_NR_LCHOWN) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_LINK) return _trace_check_syscall_C (regs, nr, name, 2);
+ else if (nr == SB_NR_LINKAT) return _trace_check_syscall_DCF(regs, nr, name, 3);
+ else if (nr == SB_NR_MKDIR) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_MKDIRAT) return trace_check_syscall_DC (regs, nr, name);
+ else if (nr == SB_NR_MKNOD) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_MKNODAT) return trace_check_syscall_DC (regs, nr, name);
+ else if (nr == SB_NR_RENAME) return trace_check_syscall_C (regs, nr, name) &&
+ _trace_check_syscall_C (regs, nr, name, 2);
+ else if (nr == SB_NR_RENAMEAT) return trace_check_syscall_DC (regs, nr, name) &&
+ _trace_check_syscall_DC (regs, nr, name, 3);
+ else if (nr == SB_NR_RMDIR) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_SYMLINK) return _trace_check_syscall_C (regs, nr, name, 2);
+ else if (nr == SB_NR_SYMLINKAT) return _trace_check_syscall_DC (regs, nr, name, 2);
+ else if (nr == SB_NR_TRUNCATE) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_TRUNCATE64)return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_UNLINK) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_UNLINKAT) return trace_check_syscall_DCF(regs, nr, name);
+ else if (nr == SB_NR_UTIME) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_UTIMES) return trace_check_syscall_C (regs, nr, name);
+ else if (nr == SB_NR_UTIMENSAT) return trace_check_syscall_DCF(regs, nr, name);
+
+ else if (nr == SB_NR_ACCESS) {
char *path = do_peekstr(trace_arg(regs, 1));
int flags = trace_arg(regs, 2);
__SB_DEBUG("(\"%s\", %x)", path, flags);
- ret = _SB_SAFE_ACCESS(SB_NR_ACCESS, "access", path, flags);
+ ret = _SB_SAFE_ACCESS(nr, name, path, flags);
free(path);
return ret;
- } else if (nr == SYS_faccessat) {
+ } else if (nr == SB_NR_FACCESSAT) {
int dirfd = trace_arg(regs, 1);
char *path = do_peekstr(trace_arg(regs, 2));
int flags = trace_arg(regs, 3);
__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
- ret = _SB_SAFE_ACCESS_AT(SB_NR_FACCESSAT, "faccessat", dirfd, path, flags);
+ ret = _SB_SAFE_ACCESS_AT(nr, name, dirfd, path, flags);
free(path);
return ret;
- } else if (nr == SYS_open) {
+ } else if (nr == SB_NR_OPEN) {
char *path = do_peekstr(trace_arg(regs, 1));
int flags = trace_arg(regs, 2);
__SB_DEBUG("(\"%s\", %x)", path, flags);
- ret = _SB_SAFE_OPEN_INT(SB_NR_OPEN, "open", path, flags);
+ ret = _SB_SAFE_OPEN_INT(nr, name, path, flags);
free(path);
return ret;
- } else if (nr == SYS_openat) {
+ } else if (nr == SB_NR_OPENAT) {
int dirfd = trace_arg(regs, 1);
char *path = do_peekstr(trace_arg(regs, 2));
int flags = trace_arg(regs, 3);
__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
- ret = _SB_SAFE_OPEN_INT_AT(SB_NR_OPENAT, "openat", dirfd, path, flags);
+ ret = _SB_SAFE_OPEN_INT_AT(nr, name, dirfd, path, flags);
free(path);
return ret;
}
@@ -268,22 +307,34 @@ static void trace_loop(void)
bool before_syscall;
long ret;
int nr, exec_state;
+ const struct syscall_entry *se, *tbl_at_fork;
exec_state = 0;
before_syscall = true;
+ tbl_at_fork = NULL;
do {
ret = do_ptrace(PTRACE_SYSCALL, NULL, NULL);
nr = trace_sysnum();
+
if (!exec_state) {
- if (!before_syscall || nr != SYS_execve)
+ if (!tbl_at_fork)
+ tbl_at_fork = trace_check_personality();
+ se = lookup_syscall_in_tbl(tbl_at_fork, nr);
+ if (!before_syscall || !se || se->sys != SB_NR_EXECVE) {
+ if (before_syscall)
+ _SB_DEBUG("%s:%i", se ? se->name : "IDK", nr);
+ else
+ __SB_DEBUG("(...) = ...\n");
goto loop_again;
+ }
++exec_state;
}
+ se = lookup_syscall(nr);
ret = do_ptrace(PTRACE_GETREGS, NULL, &regs);
if (before_syscall) {
- _SB_DEBUG("%s:%i", sysname(nr), nr);
- if (!trace_check_syscall(nr, &regs)) {
+ _SB_DEBUG("%s:%i", se ? se->name : "IDK", nr);
+ if (!trace_check_syscall(se, &regs)) {
do_ptrace(PTRACE_KILL, NULL, NULL);
exit(1);
}
diff --git a/libsandbox/trace/common.c b/libsandbox/trace/common.c
index 20fcb7e..390e343 100644
--- a/libsandbox/trace/common.c
+++ b/libsandbox/trace/common.c
@@ -1,3 +1,18 @@
+struct syscall_entry {
+ const int nr, sys;
+ const char *name;
+};
+
static int trace_sysnum(void);
static long trace_raw_ret(void *vregs);
static unsigned long trace_arg(void *vregs, int num);
+
+#ifndef SB_SCHIZO
+static const struct syscall_entry syscall_table[] = {
+#define S(s) { SB_SYS_##s, SB_NR_##s, #s },
+#include "trace_syscalls.h"
+#undef S
+ { SB_NR_UNDEF, SB_NR_UNDEF, NULL },
+};
+# define trace_check_personality() syscall_table
+#endif
diff --git a/libsandbox/trace/linux/x86_64.c b/libsandbox/trace/linux/x86_64.c
index 1f40036..96e732e 100644
--- a/libsandbox/trace/linux/x86_64.c
+++ b/libsandbox/trace/linux/x86_64.c
@@ -1,3 +1,41 @@
+#ifdef SB_SCHIZO
+
+static const struct syscall_entry syscall_table_32[] = {
+#define S(s) { SB_SYS_x86_##s, SB_NR_##s, #s },
+#include "trace_syscalls_x86.h"
+#undef S
+ { SB_NR_UNDEF, SB_NR_UNDEF, NULL },
+};
+static const struct syscall_entry syscall_table_64[] = {
+#define S(s) { SB_SYS_x86_64_##s, SB_NR_##s, #s },
+#include "trace_syscalls_x86_64.h"
+#undef S
+ { SB_NR_UNDEF, SB_NR_UNDEF, NULL },
+};
+
+static bool pers_is_32(void)
+{
+ switch (do_peekuser(8 * CS)) {
+ case 0x23: return true;
+ case 0x33: return false;
+ default: sb_abort();
+ }
+}
+
+static const struct syscall_entry *trace_check_personality(void)
+{
+ return pers_is_32() ? syscall_table_32 : syscall_table_64;
+}
+
+#else
+
+static bool pers_is_32(void)
+{
+ return false;
+}
+
+#endif
+
static int trace_sysnum(void)
{
return do_peekuser(8 * ORIG_RAX);
@@ -6,19 +44,48 @@ static int trace_sysnum(void)
static long trace_raw_ret(void *vregs)
{
struct user_regs_struct *regs = vregs;
- return regs->rax;
+ return pers_is_32() ? (int)regs->rax : regs->rax;
}
static unsigned long trace_arg(void *vregs, int num)
{
struct user_regs_struct *regs = vregs;
- switch (num) {
- case 1: return regs->rdi;
- case 2: return regs->rsi;
- case 3: return regs->rdx;
- case 4: return regs->r10;
- case 5: return regs->r8;
- case 6: return regs->r9;
- default: return -1;
- }
+ if (pers_is_32())
+ switch (num) {
+ case 1: return regs->rbx;
+ case 2: return regs->rcx;
+ case 3: return regs->rdx;
+ case 4: return regs->rsi;
+ case 5: return regs->rdi;
+ case 6: return regs->rbp;
+ default: return -1;
+ }
+ else
+ switch (num) {
+ case 1: return regs->rdi;
+ case 2: return regs->rsi;
+ case 3: return regs->rdx;
+ case 4: return regs->r10;
+ case 5: return regs->r8;
+ case 6: return regs->r9;
+ default: return -1;
+ }
+}
+
+#ifdef DEBUG
+static void trace_dump_regs(void *vregs)
+{
+ struct user_regs_struct *regs = vregs;
+ sb_printf("{ ");
+#define D(r) sb_printf(#r":%lu ", regs->r)
+ D(rax);
+ D(rdi);
+ D(rsi);
+ D(rdx);
+ D(r10);
+ D(r8);
+ D(r9);
+#undef D
+ sb_printf("}");
}
+#endif
diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c
index 399e8ad..2c0894c 100644
--- a/libsandbox/wrapper-funcs/__wrapper_exec.c
+++ b/libsandbox/wrapper-funcs/__wrapper_exec.c
@@ -64,6 +64,7 @@ static void sb_check_exec(const char *filename, char *const argv[])
else
PARSE_ELF(64);
+ /* We only support tracing of host personality atm */
trace_main(filename, argv);
done:
diff --git a/scripts/gen_trace_header.awk b/scripts/gen_trace_header.awk
index 6b99966..75f4f02 100644
--- a/scripts/gen_trace_header.awk
+++ b/scripts/gen_trace_header.awk
@@ -1,28 +1,47 @@
BEGIN {
COUNT = split(" " SYMBOLS_LIST, SYMBOLS);
+
+ if (MODE == "gen") {
+ for (x in SYMBOLS) {
+ s = SYMBOLS[x]
+ print "SB_" s " = SYS_" s
+ }
+ exit(0);
+ }
}
+function out(name, val)
{
- if ($1 != "#define" || $2 !~ /^SYS_/)
+ name = toupper(name)
+ print "#define SB_SYS" syscall_prefix "_" name " " val;
+ print "S(" name ")";
+}
+
+{
+ # found: SB_func = #
+ # not found: SB_func = SYS_func
+ if ($1 !~ /^SB_/)
+ next;
+ if ($3 ~ /^SYS_/)
next;
- sub(/^SYS_/, "", $2);
+ sub(/^SB_/, "", $1);
for (i = 1; i <= COUNT; ++i)
- if (SYMBOLS[i] == $2) {
+ if (SYMBOLS[i] == $1) {
SYMBOLS[i] = "";
break;
}
- print "S(" $2 ")";
+ out($1, $3);
}
END {
- for (x in SYMBOLS) {
- s = SYMBOLS[x];
- if (s != "") {
- print "#define SYS_" s " SB_NR_UNDEF";
- print "S(" s ")";
+ if (MODE != "gen") {
+ for (x in SYMBOLS) {
+ s = SYMBOLS[x];
+ if (s != "")
+ out(s, "SB_NR_UNDEF");
}
}
}
diff --git a/src/sandbox.c b/src/sandbox.c
index 0717ba2..c98f204 100644
--- a/src/sandbox.c
+++ b/src/sandbox.c
@@ -227,6 +227,10 @@ int main(int argc, char **argv)
#else
"next is OK! :D\n"
#endif
+#ifndef SB_SCHIZO
+# define SB_SCHIZO "no"
+#endif
+ " schizo: " SB_SCHIZO "\n"
"\nconfigured with these options:\n"
SANDBOX_CONFIGURE_OPTS
);