diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-09-24 11:13:37 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-09-25 15:19:06 +0200 |
| commit | af442a22d956464e7df703b290fa49d78dda3dfa (patch) | |
| tree | b50403630f29373cfb711a711fbfd24d632ce2ba /executor/common_linux.h | |
| parent | 255e8b5e54e93fc77302a546dbb7a932412d1bde (diff) | |
executor, sys/windows: initial windows support
Diffstat (limited to 'executor/common_linux.h')
| -rw-r--r-- | executor/common_linux.h | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index dd7d0ac31..3ad7d374f 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -9,6 +9,19 @@ #include <sys/syscall.h> #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)) #include <sys/prctl.h> #endif @@ -113,6 +126,7 @@ __attribute__((noreturn)) static void doexit(int status) for (i = 0;; i++) { } } +#define NORETURN __attribute__((noreturn)) #endif #if defined(SYZ_EXECUTOR) @@ -124,6 +138,30 @@ __attribute__((noreturn)) static void doexit(int status) #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", addr); + _longjmp(segv_env, 1); + } + debug("SIGSEGV on %p, exiting\n", addr); + doexit(sig); + for (;;) { + } +} + static void install_segv_handler() { struct sigaction sa; @@ -142,6 +180,33 @@ static void install_segv_handler() 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_t current_time_ms() +{ + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts)) + fail("clock_gettime failed"); + return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; +} +#endif + +#if defined(SYZ_EXECUTOR) +static void sleep_ms(uint64_t ms) +{ + usleep(ms * 1000); +} #endif #if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR) |
