diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | libsandbox/Makefile.am | 23 | ||||
-rw-r--r-- | libsandbox/trace.c | 201 | ||||
-rw-r--r-- | libsandbox/trace/common.c | 15 | ||||
-rw-r--r-- | libsandbox/trace/linux/x86_64.c | 87 | ||||
-rw-r--r-- | libsandbox/wrapper-funcs/__wrapper_exec.c | 1 | ||||
-rw-r--r-- | scripts/gen_trace_header.awk | 37 | ||||
-rw-r--r-- | src/sandbox.c | 4 |
9 files changed, 289 insertions, 99 deletions
@@ -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, ®s); if (before_syscall) { - _SB_DEBUG("%s:%i", sysname(nr), nr); - if (!trace_check_syscall(nr, ®s)) { + _SB_DEBUG("%s:%i", se ? se->name : "IDK", nr); + if (!trace_check_syscall(se, ®s)) { 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 ); |