diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-12-08 15:20:01 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-12-08 17:38:31 +0100 |
| commit | 9c94dffdc595729e4c1f1cc7675c47974fc9eee0 (patch) | |
| tree | 0c26c092409a0a39259b97a1ab5d212059d88c1b /csource | |
| parent | ebfa6e169e01bb909cc301becb623e780f40fab7 (diff) | |
executor: handle exit failures
See the added comment for explanation.
Diffstat (limited to 'csource')
| -rw-r--r-- | csource/common.go | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/csource/common.go b/csource/common.go index f2aa8c39f..e4ed2d577 100644 --- a/csource/common.go +++ b/csource/common.go @@ -9,6 +9,7 @@ var commonHeader = ` #endif #include <sys/ioctl.h> +#include <sys/mman.h> #include <sys/mount.h> #include <sys/prctl.h> #include <sys/resource.h> @@ -46,6 +47,18 @@ const int kFailStatus = 67; const int kErrorStatus = 68; const int kRetryStatus = 69; +__attribute__((noreturn)) void doexit(int status) +{ + syscall(__NR_exit_group, status); + for (volatile unsigned i = 0;; i++) { + } +} + +#if defined(SYZ_EXECUTOR) +#define exit use_doexit_instead +#define _exit use_doexit_instead +#endif + __attribute__((noreturn)) void fail(const char* msg, ...) { int e = errno; @@ -55,7 +68,7 @@ __attribute__((noreturn)) void fail(const char* msg, ...) vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, " (errno %d)\n", e); - exit(kFailStatus); + doexit(kFailStatus); } #if defined(SYZ_EXECUTOR) @@ -67,7 +80,7 @@ __attribute__((noreturn)) void error(const char* msg, ...) vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, "\n"); - exit(kErrorStatus); + doexit(kErrorStatus); } #endif @@ -80,7 +93,7 @@ __attribute__((noreturn)) void exitf(const char* msg, ...) vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, " (errno %d)\n", e); - exit(kRetryStatus); + doexit(kRetryStatus); } static int flag_debug; @@ -103,7 +116,9 @@ static void segv_handler(int sig, siginfo_t* info, void* uctx) { if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED)) _longjmp(segv_env, 1); - exit(sig); + doexit(sig); + for (;;) { + } } static void install_segv_handler() @@ -411,7 +426,7 @@ static int do_sandbox_none() return pid; sandbox_common(); loop(); - exit(1); + doexit(1); } #endif @@ -433,14 +448,14 @@ static int do_sandbox_setuid() fail("failed to setresuid"); loop(); - exit(1); + doexit(1); } #endif #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) static int real_uid; static int real_gid; -static char sandbox_stack[1 << 20]; +__attribute__((aligned(64 << 10))) static char sandbox_stack[1 << 20]; static bool write_file(const char* file, const char* what, ...) { @@ -513,13 +528,14 @@ static int namespace_sandbox_proc(void* arg) fail("capset failed"); loop(); - exit(1); + doexit(1); } static int do_sandbox_namespace() { real_uid = getuid(); real_gid = getgid(); + mprotect(sandbox_stack, 4096, PROT_NONE); return clone(namespace_sandbox_proc, &sandbox_stack[sizeof(sandbox_stack) - 8], CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL); } @@ -627,7 +643,7 @@ void loop() if (chdir(cwdbuf)) fail("failed to chdir"); test(); - exit(0); + doexit(0); } int status = 0; uint64_t start = current_time_ms(); |
