aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_bsd.h
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-20 20:26:05 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-24 12:04:27 +0200
commit9fe4bdc5f1037a409e82299f36117030114c7b94 (patch)
treed3d73c1f69ded8152436be47684a07baa0e7f6ec /executor/common_bsd.h
parentdb7957bc09bf5715d33e4c56b8614579aa94000a (diff)
executor: overhaul
Make as much code as possible shared between all OSes. In particular main is now common across all OSes. Make more code shared between executor and csource (in particular, loop function and threaded execution logic). Also make loop and threaded logic shared across all OSes. Make more posix/unix code shared across OSes (e.g. signal handling, pthread creation, etc). Plus other changes along similar lines. Also support test OS in executor (based on portable posix) and add 4 arches that cover all execution modes (fork server/no fork server, shmem/no shmem). This change paves way for testing of executor code and allows to preserve consistency across OSes and executor/csource.
Diffstat (limited to 'executor/common_bsd.h')
-rw-r--r--executor/common_bsd.h162
1 files changed, 11 insertions, 151 deletions
diff --git a/executor/common_bsd.h b/executor/common_bsd.h
index 16c919059..164d16a36 100644
--- a/executor/common_bsd.h
+++ b/executor/common_bsd.h
@@ -4,159 +4,19 @@
// This file is shared between executor and csource package.
#include <unistd.h>
-#if defined(SYZ_EXECUTOR) || defined(SYZ_THREADED) || defined(SYZ_COLLIDE)
-#include <pthread.h>
-#include <stdlib.h>
-#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT))
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <time.h>
-#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT) && defined(SYZ_USE_TMP_DIR))
-#include <dirent.h>
-#endif
-
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
- defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \
- defined(SYZ_SANDBOX_NAMESPACE) || defined(SYZ_SANDBOX_SETUID) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_FAULT_INJECTION) || defined(__NR_syz_kvm_setup_cpu)
-__attribute__((noreturn)) static void doexit(int status)
-{
- _exit(status);
- for (;;) {
- }
-}
-#endif
-
-#include "common.h"
-
-#if defined(SYZ_EXECUTOR) || defined(SYZ_HANDLE_SEGV)
-static __thread int skip_segv;
-static __thread jmp_buf segv_env;
-
-static void segv_handler(int sig, siginfo_t* info, void* uctx)
-{
- // Generated programs can contain bad (unmapped/protected) addresses,
- // which cause SIGSEGVs during copyin/copyout.
- // This handler ignores such crashes to allow the program to proceed.
- // We additionally opportunistically check that the faulty address
- // is not within executable data region, because such accesses can corrupt
- // output region and then fuzzer will fail on corrupted data.
- uintptr_t addr = (uintptr_t)info->si_addr;
- 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", (void*)addr);
- _longjmp(segv_env, 1);
- }
- debug("SIGSEGV on %p, exiting\n", (void*)addr);
- doexit(sig);
-}
-
-static void install_segv_handler()
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_sigaction = segv_handler;
- sa.sa_flags = SA_NODEFER | SA_SIGINFO;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGBUS, &sa, NULL);
-}
-
-#define NONFAILING(...) \
- { \
- __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
- if (_setjmp(segv_env) == 0) { \
- __VA_ARGS__; \
- } \
- __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
- }
-#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT))
-static uint64 current_time_ms()
-{
- struct timespec ts;
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts))
- fail("clock_gettime failed");
- return (uint64)ts.tv_sec * 1000 + (uint64)ts.tv_nsec / 1000000;
-}
-#endif
-
-#if defined(SYZ_EXECUTOR)
-static void sleep_ms(uint64 ms)
-{
- usleep(ms * 1000);
-}
-#endif
-
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT) && defined(SYZ_USE_TMP_DIR))
-static void remove_dir(const char* dir)
-{
- DIR* dp;
- struct dirent* ep;
- int iter = 0;
-retry:
- dp = opendir(dir);
- if (dp == NULL)
- return;
- while ((ep = readdir(dp))) {
- if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
- continue;
- char filename[FILENAME_MAX];
- snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
- struct stat st;
- if (lstat(filename, &st))
- return;
- 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;
- }
- }
- 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;
- }
-}
-#endif
-
-#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION)
-static int inject_fault(int nth)
-{
- return 0;
-}
-
-static int fault_injected(int fail_fd)
+#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
+static void loop();
+static int do_sandbox_none(void)
{
+ loop();
return 0;
}
#endif
+
+#define do_sandbox_setuid() 0
+#define do_sandbox_namespace() 0
+#define setup_loop()
+#define reset_loop()
+#define setup_test()
+#define reset_test()