From af442a22d956464e7df703b290fa49d78dda3dfa Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sun, 24 Sep 2017 11:13:37 +0200 Subject: executor, sys/windows: initial windows support --- executor/common_fuchsia.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'executor/common_fuchsia.h') diff --git a/executor/common_fuchsia.h b/executor/common_fuchsia.h index e6ccddffe..004046020 100644 --- a/executor/common_fuchsia.h +++ b/executor/common_fuchsia.h @@ -3,14 +3,53 @@ // This file is shared between executor and csource package. +#include #include #include +#if defined(SYZ_EXECUTOR) || defined(SYZ_THREADED) || defined(SYZ_COLLIDE) +#include +#include +#endif +#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) +#include +#include +#include +#include +#include +#include +#include +#endif #define doexit exit +#define NORETURN __attribute__((noreturn)) #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; @@ -21,6 +60,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_FAULT_INJECTION) -- cgit mrf-deployment