Index: lib/Fuzzer/FuzzerDriver.cpp =================================================================== --- lib/Fuzzer/FuzzerDriver.cpp +++ lib/Fuzzer/FuzzerDriver.cpp @@ -455,18 +455,21 @@ if (U.size() <= Word::GetMaxSize()) MD->AddWordToManualDictionary(Word(U.data(), U.size())); - StartRssThread(F, Flags.rss_limit_mb); + SignalHandlerOptions Opts; + if (Flags.timeout > 0) { + Opts.timeout = Flags.timeout / 2 + 1; + Opts.sigalrm_cb = Fuzzer::StaticAlarmCallback; + } + Opts.sigsegv_cb = Fuzzer::StaticCrashSignalCallback; + Opts.sigbus_cb = Fuzzer::StaticCrashSignalCallback; + Opts.sigabrt_cb = Fuzzer::StaticCrashSignalCallback; + Opts.sigill_cb = Fuzzer::StaticCrashSignalCallback; + Opts.sigfpe_cb = Fuzzer::StaticCrashSignalCallback; + Opts.sigint_cb = Fuzzer::StaticInterruptCallback; + Opts.sigterm_cb = Fuzzer::StaticInterruptCallback; + SetSignalHandler(Opts); - // Timer - if (Flags.timeout > 0) - SetTimer(Flags.timeout / 2 + 1); - if (Flags.handle_segv) SetSigSegvHandler(); - if (Flags.handle_bus) SetSigBusHandler(); - if (Flags.handle_abrt) SetSigAbrtHandler(); - if (Flags.handle_ill) SetSigIllHandler(); - if (Flags.handle_fpe) SetSigFpeHandler(); - if (Flags.handle_int) SetSigIntHandler(); - if (Flags.handle_term) SetSigTermHandler(); + StartRssThread(F, Flags.rss_limit_mb); if (Flags.minimize_crash_internal_step) return MinimizeCrashInputInternalStep(F, Corpus); Index: lib/Fuzzer/FuzzerUtil.h =================================================================== --- lib/Fuzzer/FuzzerUtil.h +++ lib/Fuzzer/FuzzerUtil.h @@ -41,15 +41,20 @@ int NumberOfCpuCores(); // Platform specific functions. -void SetTimer(int Seconds); - -void SetSigSegvHandler(); -void SetSigBusHandler(); -void SetSigAbrtHandler(); -void SetSigIllHandler(); -void SetSigFpeHandler(); -void SetSigIntHandler(); -void SetSigTermHandler(); +struct SignalHandlerOptions { + typedef void (*HandlerT)(); + int timeout = 0; + HandlerT sigalrm_cb = nullptr; + HandlerT sigsegv_cb = nullptr; + HandlerT sigbus_cb = nullptr; + HandlerT sigabrt_cb = nullptr; + HandlerT sigill_cb = nullptr; + HandlerT sigfpe_cb = nullptr; + HandlerT sigint_cb = nullptr; + HandlerT sigterm_cb = nullptr; +}; + +void SetSignalHandler(const SignalHandlerOptions& Opt); void SleepSeconds(int Seconds); Index: lib/Fuzzer/FuzzerUtilPosix.cpp =================================================================== --- lib/Fuzzer/FuzzerUtilPosix.cpp +++ lib/Fuzzer/FuzzerUtilPosix.cpp @@ -11,7 +11,7 @@ #include "FuzzerDefs.h" #if LIBFUZZER_POSIX -#include "FuzzerInternal.h" +#include "FuzzerUtil.h" #include "FuzzerIO.h" #include #include @@ -30,17 +30,7 @@ namespace fuzzer { -static void AlarmHandler(int, siginfo_t *, void *) { - Fuzzer::StaticAlarmCallback(); -} - -static void CrashHandler(int, siginfo_t *, void *) { - Fuzzer::StaticCrashSignalCallback(); -} - -static void InterruptHandler(int, siginfo_t *, void *) { - Fuzzer::StaticInterruptCallback(); -} +static SignalHandlerOptions HandlerOpt; static void SetSigaction(int signum, void (*callback)(int, siginfo_t *, void *)) { @@ -53,23 +43,33 @@ } } -void SetTimer(int Seconds) { - struct itimerval T {{Seconds, 0}, {Seconds, 0}}; - if (setitimer(ITIMER_REAL, &T, nullptr)) { - Printf("libFuzzer: setitimer failed with %d\n", errno); - exit(1); +void SetSignalHandler(const SignalHandlerOptions& Opt) { + HandlerOpt = Opt; + + if (Opt.timeout > 0 && Opt.sigalrm_cb) { + struct itimerval T {{Opt.timeout, 0}, {Opt.timeout, 0}}; + if (setitimer(ITIMER_REAL, &T, nullptr)) { + Printf("libFuzzer: setitimer failed with %d\n", errno); + exit(1); + } + SetSigaction(SIGALRM, [](int,siginfo_t*,void*) {HandlerOpt.sigalrm_cb();}); } - SetSigaction(SIGALRM, AlarmHandler); + if (Opt.sigint_cb) + SetSigaction(SIGINT, [](int,siginfo_t*,void*) {HandlerOpt.sigint_cb();}); + if (Opt.sigterm_cb) + SetSigaction(SIGTERM, [](int,siginfo_t*,void*) {HandlerOpt.sigterm_cb();}); + if (Opt.sigsegv_cb) + SetSigaction(SIGSEGV, [](int,siginfo_t*,void*) {HandlerOpt.sigsegv_cb();}); + if (Opt.sigbus_cb) + SetSigaction(SIGBUS, [](int,siginfo_t*,void*) {HandlerOpt.sigbus_cb();}); + if (Opt.sigabrt_cb) + SetSigaction(SIGABRT, [](int,siginfo_t*,void*) {HandlerOpt.sigabrt_cb();}); + if (Opt.sigill_cb) + SetSigaction(SIGILL, [](int,siginfo_t*,void*) {HandlerOpt.sigill_cb();}); + if (Opt.sigfpe_cb) + SetSigaction(SIGFPE, [](int,siginfo_t*,void*) {HandlerOpt.sigfpe_cb();}); } -void SetSigSegvHandler() { SetSigaction(SIGSEGV, CrashHandler); } -void SetSigBusHandler() { SetSigaction(SIGBUS, CrashHandler); } -void SetSigAbrtHandler() { SetSigaction(SIGABRT, CrashHandler); } -void SetSigIllHandler() { SetSigaction(SIGILL, CrashHandler); } -void SetSigFpeHandler() { SetSigaction(SIGFPE, CrashHandler); } -void SetSigIntHandler() { SetSigaction(SIGINT, InterruptHandler); } -void SetSigTermHandler() { SetSigaction(SIGTERM, InterruptHandler); } - void SleepSeconds(int Seconds) { sleep(Seconds); // Use C API to avoid coverage from instrumented libc++. } Index: lib/Fuzzer/FuzzerUtilWindows.cpp =================================================================== --- lib/Fuzzer/FuzzerUtilWindows.cpp +++ lib/Fuzzer/FuzzerUtilWindows.cpp @@ -11,7 +11,7 @@ #include "FuzzerDefs.h" #if LIBFUZZER_WINDOWS -#include "FuzzerInternal.h" +#include "FuzzerUtil.h" #include "FuzzerIO.h" #include #include @@ -27,39 +27,26 @@ namespace fuzzer { -LONG WINAPI SEGVHandler(PEXCEPTION_POINTERS ExceptionInfo) { +static SignalHandlerOptions HandlerOpt; + +LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: case EXCEPTION_STACK_OVERFLOW: - Fuzzer::StaticCrashSignalCallback(); + if (HandlerOpt.sigsegv_cb) + HandlerOpt.sigsegv_cb(); break; - } - return EXCEPTION_CONTINUE_SEARCH; -} - -LONG WINAPI BUSHandler(PEXCEPTION_POINTERS ExceptionInfo) { - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_DATATYPE_MISALIGNMENT: case EXCEPTION_IN_PAGE_ERROR: - Fuzzer::StaticCrashSignalCallback(); + if (HandlerOpt.sigbus_cb) + HandlerOpt.sigbus_cb(); break; - } - return EXCEPTION_CONTINUE_SEARCH; -} - -LONG WINAPI ILLHandler(PEXCEPTION_POINTERS ExceptionInfo) { - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ILLEGAL_INSTRUCTION: case EXCEPTION_PRIV_INSTRUCTION: - Fuzzer::StaticCrashSignalCallback(); + if (HandlerOpt.sigill_cb) + HandlerOpt.sigill_cb(); break; - } - return EXCEPTION_CONTINUE_SEARCH; -} - -LONG WINAPI FPEHandler(PEXCEPTION_POINTERS ExceptionInfo) { - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_FLT_DENORMAL_OPERAND: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_INEXACT_RESULT: @@ -69,34 +56,29 @@ case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: - Fuzzer::StaticCrashSignalCallback(); + if (HandlerOpt.sigfpe_cb) + HandlerOpt.sigfpe_cb(); break; } return EXCEPTION_CONTINUE_SEARCH; } -BOOL WINAPI INTHandler(DWORD dwCtrlType) { +BOOL WINAPI CtrlHandler(DWORD dwCtrlType) { switch (dwCtrlType) { case CTRL_C_EVENT: - Fuzzer::StaticInterruptCallback(); + if (HandlerOpt.sigint_cb) + HandlerOpt.sigint_cb(); return TRUE; - default: - return FALSE; - } -} - -BOOL WINAPI TERMHandler(DWORD dwCtrlType) { - switch (dwCtrlType) { case CTRL_BREAK_EVENT: - Fuzzer::StaticInterruptCallback(); + if (HandlerOpt.sigterm_cb) + HandlerOpt.sigterm_cb(); return TRUE; - default: - return FALSE; } + return FALSE; } void CALLBACK AlarmHandler(PVOID, BOOLEAN) { - Fuzzer::StaticAlarmCallback(); + HandlerOpt.sigalrm_cb(); } class TimerQ { @@ -126,61 +108,31 @@ static TimerQ Timer; -void SetTimer(int Seconds) { - Timer.SetTimer(Seconds); - return; -} +void SetSignalHandler(const SignalHandlerOptions& Opt) { + HandlerOpt = Opt; -void SetSigSegvHandler() { - if (!AddVectoredExceptionHandler(1, SEGVHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} - -void SetSigBusHandler() { - if (!AddVectoredExceptionHandler(1, BUSHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} - -static void CrashHandler(int) { - Fuzzer::StaticCrashSignalCallback(); -} + if (Opt.timeout > 0 && Opt.sigalrm_cb) + Timer.SetTimer(Opt.timeout); -void SetSigAbrtHandler() { signal(SIGABRT, CrashHandler); } - -void SetSigIllHandler() { - if (!AddVectoredExceptionHandler(1, ILLHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} - -void SetSigFpeHandler() { - if (!AddVectoredExceptionHandler(1, FPEHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} + if (Opt.sigint_cb || Opt.sigterm_cb) + if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { + DWORD LastError = GetLastError(); + Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n", + LastError); + exit(1); + } -void SetSigIntHandler() { - if (!SetConsoleCtrlHandler(INTHandler, TRUE)) { - DWORD LastError = GetLastError(); - Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n", - LastError); - exit(1); - } -} + if (Opt.sigsegv_cb || Opt.sigbus_cb || Opt.sigill_cb || Opt.sigfpe_cb) + if (!AddVectoredExceptionHandler(1, ExceptionHandler)) { + Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); + exit(1); + } -void SetSigTermHandler() { - if (!SetConsoleCtrlHandler(TERMHandler, TRUE)) { - DWORD LastError = GetLastError(); - Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n", - LastError); - exit(1); - } + if (Opt.sigabrt_cb) + if (SIG_ERR == signal(SIGABRT, [](int){HandlerOpt.sigabrt_cb();})) { + Printf("libFuzzer: signal failed with %d\n", errno); + exit(1); + } } void SleepSeconds(int Seconds) {