X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fbox.c;h=126452adbe176f9f511e38a47bef1e7f32cc1124;hb=41af1de4522e2dc5bfb3b83f89e03f359b6381b6;hp=b72c0595b01309efd0eaa6c5d865d48c2388f3ce;hpb=81f60f3c309cf87db8a5ffcb320d181e8c3f99e2;p=moe.git diff --git a/src/box.c b/src/box.c index b72c059..126452a 100644 --- a/src/box.c +++ b/src/box.c @@ -44,6 +44,7 @@ static int is_ptraced; static volatile int timer_tick; static struct timeval start_time; static int ticks_per_sec; +static int exec_seen; #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0 /* glibc 2.1 or newer -> has lseek64 */ @@ -78,7 +79,7 @@ die(char *msg, ...) } static void __attribute__((format(printf,1,2))) -log(char *msg, ...) +msg(char *msg, ...) { va_list args; va_start(args, msg); @@ -132,7 +133,7 @@ valid_filename(unsigned long addr) } while (*p++); - log("[%s] ", namebuf); + msg("[%s] ", namebuf); if (file_access >= 3) return; if (!strchr(namebuf, '/') && strcmp(namebuf, "..")) @@ -161,11 +162,6 @@ valid_syscall(struct user *u) { switch (u->regs.orig_eax) { - case __NR_execve: - { - static int exec_counter; - return !exec_counter++; - } case __NR_open: case __NR_creat: case __NR_unlink: @@ -264,11 +260,11 @@ valid_syscall(struct user *u) return allow_times; case __NR_kill: if (u->regs.ebx == box_pid) - die("Commited suicide by signal %d", (int)u->regs.ecx); + die("Committed suicide by signal %d", (int)u->regs.ecx); return 0; case __NR_tgkill: if (u->regs.ebx == box_pid && u->regs.ecx == box_pid) - die("Commited suicide by signal %d", (int)u->regs.edx); + die("Committed suicide by signal %d", (int)u->regs.edx); return 0; default: return 0; @@ -408,7 +404,7 @@ boxkeeper(void) if (WIFSIGNALED(stat)) { box_pid = 0; - die("Caught fatal signal %d", WTERMSIG(stat)); + die("Caught fatal signal %d%s", WTERMSIG(stat), (syscall_count ? "" : " during startup")); } if (WIFSTOPPED(stat)) { @@ -421,12 +417,19 @@ boxkeeper(void) die("ptrace(PTRACE_GETREGS): %m"); stop_count++; if (!stop_count) /* Traceme request */ - log(">> Traceme request caught\n"); + msg(">> Traceme request caught\n"); else if (stop_count & 1) /* Syscall entry */ { - log(">> Syscall %3ld (%08lx,%08lx,%08lx) ", u.regs.orig_eax, u.regs.ebx, u.regs.ecx, u.regs.edx); - syscall_count++; - if (!valid_syscall(&u)) + msg(">> Syscall %3ld (%08lx,%08lx,%08lx) ", u.regs.orig_eax, u.regs.ebx, u.regs.ecx, u.regs.edx); + if (!exec_seen) + { + msg("[master] "); + if (u.regs.orig_eax == __NR_execve) + exec_seen = 1; + } + else if (valid_syscall(&u)) + syscall_count++; + else { /* * Unfortunately, PTRACE_KILL kills _after_ the syscall completes, @@ -441,12 +444,12 @@ boxkeeper(void) } } else /* Syscall return */ - log("= %ld\n", u.regs.eax); + msg("= %ld\n", u.regs.eax); ptrace(PTRACE_SYSCALL, box_pid, 0, 0); } else if (sig != SIGSTOP && sig != SIGXCPU && sig != SIGXFSZ) { - log(">> Signal %d\n", sig); + msg(">> Signal %d\n", sig); ptrace(PTRACE_SYSCALL, box_pid, 0, sig); } else @@ -462,7 +465,7 @@ box_inside(int argc, char **argv) { struct rlimit rl; char *args[argc+1]; - char *env[1] = { NULL }; + char *env[] = { "LIBC_FATAL_STDERR_=1", NULL }; memcpy(args, argv, argc * sizeof(char *)); args[argc] = NULL; @@ -491,8 +494,14 @@ box_inside(int argc, char **argv) rl.rlim_cur = rl.rlim_max = 64; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) die("setrlimit: %m"); - if (filter_syscalls && ptrace(PTRACE_TRACEME) < 0) - die("ptrace(PTRACE_TRACEME): %m"); + if (filter_syscalls) + { + if (ptrace(PTRACE_TRACEME) < 0) + die("ptrace(PTRACE_TRACEME): %m"); + /* Trick: Make sure that we are stopped until the boxkeeper wakes up. */ + signal(SIGCHLD, SIG_IGN); + raise(SIGCHLD); + } execve(args[0], args, (pass_environ ? environ : env)); die("execve(\"%s\"): %m", args[0]); }