aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-04 10:04:21 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-05 10:44:34 +0200
commit3e6e03441320e16b01a155367fd48f487b58f90c (patch)
tree5d3eb13b8f0561b75d3a59f10151547cf1fffaf8 /executor
parentc32749f1e826c13949c29c4ea0ab48ff57678d03 (diff)
executor: repair akaros support
Diffstat (limited to 'executor')
-rw-r--r--executor/common_akaros.h123
-rw-r--r--executor/executor_akaros.cc44
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);