]> granicus.if.org Git - llvm/commitdiff
[libFuzzer] Improve Signal Handler interface.
authorMarcos Pividori <mpividori@google.com>
Tue, 13 Dec 2016 17:45:20 +0000 (17:45 +0000)
committerMarcos Pividori <mpividori@google.com>
Tue, 13 Dec 2016 17:45:20 +0000 (17:45 +0000)
Add new flags to FuzzingOptions to represent the different conditions
on the signal handling. These options are passed when calling
SetSignalHandler().
This changes simplify the implementation of Windows's exception
handling. Now we can define a unique handler for all the exceptions.

Differential Revision: https://reviews.llvm.org/D27238

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289557 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerOptions.h
lib/Fuzzer/FuzzerUtil.h
lib/Fuzzer/FuzzerUtilPosix.cpp
lib/Fuzzer/FuzzerUtilWindows.cpp

index 2e94530e72138839c2b977059c126081cd1cf2e5..1ff822c6881be8f4decd3aec2c3fd0fb95db01af 100644 (file)
@@ -457,16 +457,14 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
 
   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 59126a231e3c6824f4631039d9bcd28ed069d915..f1cd4935be9c8219f0116c1e68e48751c4f6a5e3 100644 (file)
@@ -53,6 +53,13 @@ struct FuzzingOptions {
   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 eb425371a8f2656f76d91edb4ac34fc6df65a441..c237379b3acd8ac05236f9b070f367413df82939 100644 (file)
@@ -43,15 +43,7 @@ int NumberOfCpuCores();
 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 ad1e3044477a537f35eeacf4ac353d473fdd2cf0..abb2680abb019a0d4b5c538183c396f890604aa5 100644 (file)
@@ -64,13 +64,24 @@ void SetTimer(int Seconds) {
   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 c149699e588e9a518c4f3677002314fbaea1252e..f2dd6e6cca0228e9430f922f601746031c6cb198 100644 (file)
@@ -13,7 +13,6 @@
 #if LIBFUZZER_WINDOWS
 #include "FuzzerIO.h"
 #include "FuzzerInternal.h"
-#include <Psapi.h>
 #include <cassert>
 #include <chrono>
 #include <cstring>
 #include <stdio.h>
 #include <sys/types.h>
 #include <windows.h>
+#include <Psapi.h>
 
 namespace fuzzer {
 
-LONG WINAPI SEGVHandler(PEXCEPTION_POINTERS ExceptionInfo) {
-  switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
-  case EXCEPTION_ACCESS_VIOLATION:
-  case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-  case EXCEPTION_STACK_OVERFLOW:
-    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();
-    break;
-  }
-  return EXCEPTION_CONTINUE_SEARCH;
-}
+static const FuzzingOptions* HandlerOpt = nullptr;
 
-LONG WINAPI ILLHandler(PEXCEPTION_POINTERS ExceptionInfo) {
+LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
   switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
-  case EXCEPTION_ILLEGAL_INSTRUCTION:
-  case EXCEPTION_PRIV_INSTRUCTION:
-    Fuzzer::StaticCrashSignalCallback();
-    break;
+    case EXCEPTION_ACCESS_VIOLATION:
+    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+    case EXCEPTION_STACK_OVERFLOW:
+      if (HandlerOpt->HandleSegv)
+        Fuzzer::StaticCrashSignalCallback();
+      break;
+    case EXCEPTION_DATATYPE_MISALIGNMENT:
+    case EXCEPTION_IN_PAGE_ERROR:
+      if (HandlerOpt->HandleBus)
+        Fuzzer::StaticCrashSignalCallback();
+      break;
+    case EXCEPTION_ILLEGAL_INSTRUCTION:
+    case EXCEPTION_PRIV_INSTRUCTION:
+      if (HandlerOpt->HandleIll)
+        Fuzzer::StaticCrashSignalCallback();
+      break;
+    case EXCEPTION_FLT_DENORMAL_OPERAND:
+    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+    case EXCEPTION_FLT_INEXACT_RESULT:
+    case EXCEPTION_FLT_INVALID_OPERATION:
+    case EXCEPTION_FLT_OVERFLOW:
+    case EXCEPTION_FLT_STACK_CHECK:
+    case EXCEPTION_FLT_UNDERFLOW:
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+    case EXCEPTION_INT_OVERFLOW:
+      if (HandlerOpt->HandleFpe)
+        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:
-  case EXCEPTION_FLT_INVALID_OPERATION:
-  case EXCEPTION_FLT_OVERFLOW:
-  case EXCEPTION_FLT_STACK_CHECK:
-  case EXCEPTION_FLT_UNDERFLOW:
-  case EXCEPTION_INT_DIVIDE_BY_ZERO:
-  case EXCEPTION_INT_OVERFLOW:
-    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();
-    return TRUE;
-  default:
-    return FALSE;
-  }
-}
-
-BOOL WINAPI TERMHandler(DWORD dwCtrlType) {
-  switch (dwCtrlType) {
-  case CTRL_BREAK_EVENT:
-    Fuzzer::StaticInterruptCallback();
-    return TRUE;
-  default:
-    return FALSE;
+    case CTRL_C_EVENT:
+      if (HandlerOpt->HandleInt)
+        Fuzzer::StaticInterruptCallback();
+      return TRUE;
+    case CTRL_BREAK_EVENT:
+      if (HandlerOpt->HandleTerm)
+        Fuzzer::StaticInterruptCallback();
+      return TRUE;
   }
+  return FALSE;
 }
 
 void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
@@ -126,59 +108,34 @@ class TimerQ {
 
 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) { Sleep(Seconds * 1000); }