diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-07-04 10:04:21 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-07-05 10:44:34 +0200 |
| commit | 3e6e03441320e16b01a155367fd48f487b58f90c (patch) | |
| tree | 5d3eb13b8f0561b75d3a59f10151547cf1fffaf8 /executor | |
| parent | c32749f1e826c13949c29c4ea0ab48ff57678d03 (diff) | |
executor: repair akaros support
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/common_akaros.h | 123 | ||||
| -rw-r--r-- | executor/executor_akaros.cc | 44 |
2 files changed, 110 insertions, 57 deletions
diff --git a/executor/common_akaros.h b/executor/common_akaros.h index c31492ad8..15902d472 100644 --- a/executor/common_akaros.h +++ b/executor/common_akaros.h @@ -3,6 +3,11 @@ // This file is shared between executor and csource package. +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <sys/syscall.h> #include <unistd.h> #if defined(SYZ_EXECUTOR) || defined(SYZ_THREADED) || defined(SYZ_COLLIDE) #include <pthread.h> @@ -65,12 +70,12 @@ static void segv_handler(int sig, siginfo_t* info, void* ctx) const uintptr_t prog_start = 1 << 20; const uintptr_t prog_end = 100 << 20; if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) { - debug("SIGSEGV on %p, skipping\n", addr); + debug("SIGSEGV on 0x%lx, skipping\n", addr); struct user_context* uctx = (struct user_context*)ctx; uctx->tf.hw_tf.tf_rip = (long)(void*)recover; return; } - debug("SIGSEGV on %p, exiting\n", addr); + debug("SIGSEGV on 0x%lx, exiting\n", addr); doexit(sig); for (;;) { } @@ -147,11 +152,9 @@ static void remove_dir(const char* dir) { DIR* dp; struct dirent* ep; - int iter = 0; -retry: dp = opendir(dir); if (dp == NULL) - return; + exitf("opendir(%s) failed", dir); while ((ep = readdir(dp))) { if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) continue; @@ -159,43 +162,33 @@ retry: snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); struct stat st; if (lstat(filename, &st)) - return; + exitf("lstat(%s) failed", filename); if (S_ISDIR(st.st_mode)) { remove_dir(filename); continue; } - int i; - for (i = 0;; i++) { - if (unlink(filename) == 0) - break; - if (errno == EROFS) - break; - if (errno != EBUSY || i > 100) - return; - } + if (unlink(filename)) + exitf("unlink(%s) failed", filename); } closedir(dp); - int i; - for (i = 0;; i++) { - if (rmdir(dir) == 0) - break; - if (i < 100) { - if (errno == EROFS) - break; - if (errno == ENOTEMPTY) { - if (iter < 100) { - iter++; - goto retry; - } - } - } - return; - } + if (rmdir(dir)) + exitf("rmdir(%s) failed", dir); +} +#endif + +#if defined(SYZ_SANDBOX_NONE) +static void loop(); +static int do_sandbox_none(void) +{ + loop(); + doexit(0); + fail("doexit returned"); + return 0; } #endif #if defined(SYZ_REPEAT) -static void test(); +static void execute_one(); #if defined(SYZ_WAIT_REPEAT) void loop() @@ -216,7 +209,7 @@ void loop() if (chdir(cwdbuf)) fail("failed to chdir"); #endif - test(); + execute_one(); doexit(0); } int status = 0; @@ -242,8 +235,70 @@ void loop() void loop() { while (1) { - test(); + execute_one(); } } #endif #endif + +#if defined(SYZ_THREADED) +struct thread_t { + int created, running, call; + pthread_t th; +}; + +static struct thread_t threads[16]; +static void execute_call(int call); +static int running; +#if defined(SYZ_COLLIDE) +static int collide; +#endif + +static void* thr(void* arg) +{ + struct thread_t* th = (struct thread_t*)arg; + for (;;) { + while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) + usleep(200); + execute_call(th->call); + __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); + __atomic_store_n(&th->running, 0, __ATOMIC_RELEASE); + } + return 0; +} + +static void execute(int num_calls) +{ + int i, call, thread; + running = 0; + for (call = 0; call < num_calls; call++) { + for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) { + struct thread_t* th = &threads[thread]; + if (!th->created) { + th->created = 1; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 128 << 10); + pthread_create(&th->th, &attr, thr, th); + } + if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) { + th->call = call; + __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); + __atomic_store_n(&th->running, 1, __ATOMIC_RELEASE); +#if defined(SYZ_COLLIDE) + if (collide && call % 2) + break; +#endif + for (i = 0; i < 100; i++) { + if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) + break; + usleep(200); + } + if (__atomic_load_n(&running, __ATOMIC_RELAXED)) + usleep((call == num_calls - 1) ? 10000 : 1000); + break; + } + } + } +} +#endif diff --git a/executor/executor_akaros.cc b/executor/executor_akaros.cc index e13719609..3f0ffb5a8 100644 --- a/executor/executor_akaros.cc +++ b/executor/executor_akaros.cc @@ -16,51 +16,38 @@ uint32 output; +static void child(); + int main(int argc, char** argv) { if (argc == 2 && strcmp(argv[1], "version") == 0) { puts(GOOS " " GOARCH " " SYZ_REVISION " " GIT_REVISION); return 0; } - - if (mmap((void*)SYZ_DATA_OFFSET, SYZ_NUM_PAGES * SYZ_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != (void*)SYZ_DATA_OFFSET) - fail("mmap of data segment failed"); + if (argc == 2 && strcmp(argv[1], "child") == 0) { + child(); + doexit(0); + } use_temporary_dir(); - install_segv_handler(); main_init(); reply_handshake(); for (;;) { - receive_execute(); char cwdbuf[128] = "/syz-tmpXXXXXX"; mkdtemp(cwdbuf); int pid = fork(); if (pid < 0) fail("fork failed"); if (pid == 0) { - close(kInPipeFd); - close(kOutPipeFd); if (chdir(cwdbuf)) fail("chdir failed"); - execute_one(); - doexit(0); + execl(argv[0], argv[0], "child", NULL); + fail("execl failed"); + return 0; } int status = 0; - uint64 start = current_time_ms(); - for (;;) { - int res = waitpid(pid, &status, WNOHANG); - if (res == pid) - break; - sleep_ms(10); - uint64 now = current_time_ms(); - if (now - start < 3 * 1000) - continue; - kill(pid, SIGKILL); - while (waitpid(pid, &status, 0) != pid) { - } - break; + while (waitpid(pid, &status, 0) != pid) { } status = WEXITSTATUS(status); if (status == kFailStatus) @@ -73,6 +60,17 @@ int main(int argc, char** argv) return 0; } +static void child() +{ + install_segv_handler(); + if (mmap((void*)SYZ_DATA_OFFSET, SYZ_NUM_PAGES * SYZ_PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != (void*)SYZ_DATA_OFFSET) + fail("mmap of data segment failed"); + receive_execute(); + close(kInPipeFd); + execute_one(); +} + long execute_syscall(const call_t* c, long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return syscall(c->sys_nr, a0, a1, a2, a3, a4, a5, a6, a7, a8); |
