Index: lib/Fuzzer/FuzzerDriver.cpp =================================================================== --- lib/Fuzzer/FuzzerDriver.cpp +++ lib/Fuzzer/FuzzerDriver.cpp @@ -456,16 +456,14 @@ StartRssThread(F, Flags.rss_limit_mb); - // 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(); + Options.HandleAbrt = Flags.handle_abrt; + Options.HandleBus = Flags.handle_bus; + Options.HandleFpe = Flags.handle_fpe; + Options.HandleIll = Flags.handle_ill; + Options.HandleInt = Flags.handle_int; + Options.HandleSegv = Flags.handle_segv; + Options.HandleTerm = Flags.handle_term; + SetSignalHandler(Options); if (Flags.minimize_crash_internal_step) return MinimizeCrashInputInternalStep(F, Corpus); Index: lib/Fuzzer/FuzzerOptions.h =================================================================== --- lib/Fuzzer/FuzzerOptions.h +++ lib/Fuzzer/FuzzerOptions.h @@ -53,6 +53,13 @@ bool PrintCoverage = false; bool DetectLeaks = true; int TraceMalloc = 0; + bool HandleAbrt = false; + bool HandleBus = false; + bool HandleFpe = false; + bool HandleIll = false; + bool HandleInt = false; + bool HandleSegv = false; + bool HandleTerm = false; }; } // namespace fuzzer Index: lib/Fuzzer/FuzzerUtil.h =================================================================== --- lib/Fuzzer/FuzzerUtil.h +++ lib/Fuzzer/FuzzerUtil.h @@ -43,15 +43,7 @@ bool ExecuteCommandAndReadOutput(const std::string &Command, std::string *Out); // Platform specific functions. -void SetTimer(int Seconds); - -void SetSigSegvHandler(); -void SetSigBusHandler(); -void SetSigAbrtHandler(); -void SetSigIllHandler(); -void SetSigFpeHandler(); -void SetSigIntHandler(); -void SetSigTermHandler(); +void SetSignalHandler(const FuzzingOptions& Options); void SleepSeconds(int Seconds); Index: lib/Fuzzer/FuzzerUtilPosix.cpp =================================================================== --- lib/Fuzzer/FuzzerUtilPosix.cpp +++ lib/Fuzzer/FuzzerUtilPosix.cpp @@ -53,7 +53,7 @@ } } -void SetTimer(int Seconds) { +static 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); @@ -62,13 +62,24 @@ SetSigaction(SIGALRM, AlarmHandler); } -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 SetSignalHandler(const FuzzingOptions& Options) { + if (Options.UnitTimeoutSec > 0) + SetTimer(Options.UnitTimeoutSec / 2 + 1); + if (Options.HandleInt) + SetSigaction(SIGINT, InterruptHandler); + if (Options.HandleTerm) + SetSigaction(SIGTERM, InterruptHandler); + if (Options.HandleSegv) + SetSigaction(SIGSEGV, CrashHandler); + if (Options.HandleBus) + SetSigaction(SIGBUS, CrashHandler); + if (Options.HandleAbrt) + SetSigaction(SIGABRT, CrashHandler); + if (Options.HandleIll) + SetSigaction(SIGILL, CrashHandler); + if (Options.HandleFpe) + SetSigaction(SIGFPE, CrashHandler); +} 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 @@ -27,39 +27,26 @@ namespace fuzzer { -LONG WINAPI SEGVHandler(PEXCEPTION_POINTERS ExceptionInfo) { +static const FuzzingOptions* HandlerOpt = nullptr; + +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->HandleSegv) + Fuzzer::StaticCrashSignalCallback(); 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->HandleBus) + Fuzzer::StaticCrashSignalCallback(); 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->HandleIll) + Fuzzer::StaticCrashSignalCallback(); 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,30 +56,25 @@ case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: - Fuzzer::StaticCrashSignalCallback(); + if (HandlerOpt->HandleFpe) + Fuzzer::StaticCrashSignalCallback(); 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->HandleInt) + Fuzzer::StaticInterruptCallback(); return TRUE; - default: - return FALSE; - } -} - -BOOL WINAPI TERMHandler(DWORD dwCtrlType) { - switch (dwCtrlType) { case CTRL_BREAK_EVENT: - Fuzzer::StaticInterruptCallback(); + if (HandlerOpt->HandleTerm) + Fuzzer::StaticInterruptCallback(); return TRUE; - default: - return FALSE; } + return FALSE; } void CALLBACK AlarmHandler(PVOID, BOOLEAN) { @@ -126,61 +108,36 @@ static TimerQ Timer; -void SetTimer(int Seconds) { - Timer.SetTimer(Seconds); - return; -} - -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(); } -void SetSigAbrtHandler() { signal(SIGABRT, CrashHandler); } +void SetSignalHandler(const FuzzingOptions& Options) { + HandlerOpt = &Options; -void SetSigIllHandler() { - if (!AddVectoredExceptionHandler(1, ILLHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} + if (Options.UnitTimeoutSec > 0) + Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1); -void SetSigFpeHandler() { - if (!AddVectoredExceptionHandler(1, FPEHandler)) { - Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); - exit(1); - } -} + if (Options.HandleInt || Options.HandleTerm) + 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 (Options.HandleSegv || Options.HandleBus || Options.HandleIll || + Options.HandleFpe) + 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 (Options.HandleAbrt) + if (SIG_ERR == signal(SIGABRT, CrashHandler)) { + Printf("libFuzzer: signal failed with %d\n", errno); + exit(1); + } } void SleepSeconds(int Seconds) {