[llvm] r262415 - [libFuzzer] add generic signal handlers so that libFuzzer can report at least something if ASan is not handlig the signals for us. Remove abort_on_timeout flag.
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 1 14:19:21 PST 2016
Author: kcc
Date: Tue Mar 1 16:19:21 2016
New Revision: 262415
URL: http://llvm.org/viewvc/llvm-project?rev=262415&view=rev
Log:
[libFuzzer] add generic signal handlers so that libFuzzer can report at least something if ASan is not handlig the signals for us. Remove abort_on_timeout flag.
Modified:
llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
llvm/trunk/lib/Fuzzer/FuzzerFlags.def
llvm/trunk/lib/Fuzzer/FuzzerInternal.h
llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
llvm/trunk/lib/Fuzzer/test/fuzzer-timeout.test
llvm/trunk/lib/Fuzzer/test/fuzzer.test
Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Tue Mar 1 16:19:21 2016
@@ -265,7 +265,6 @@ static int FuzzerDriver(const std::vecto
Options.Verbosity = Flags.verbosity;
Options.MaxLen = Flags.max_len;
Options.UnitTimeoutSec = Flags.timeout;
- Options.AbortOnTimeout = Flags.abort_on_timeout;
Options.TimeoutExitCode = Flags.timeout_exitcode;
Options.MaxTotalTimeSec = Flags.max_total_time;
Options.DoCrossOver = Flags.cross_over;
@@ -322,6 +321,12 @@ static int FuzzerDriver(const std::vecto
// 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.test_single_input) {
RunOneTest(&F, Flags.test_single_input);
Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Tue Mar 1 16:19:21 2016
@@ -29,9 +29,10 @@ FUZZER_FLAG_INT(
timeout, 1200,
"Timeout in seconds (if positive). "
"If one unit runs more than this number of seconds the process will abort.")
-FUZZER_FLAG_INT(abort_on_timeout, 0, "If positive, call abort on timeout.")
FUZZER_FLAG_INT(timeout_exitcode, 77,
"Unless abort_on_timeout is set, use this exitcode on timeout.")
+FUZZER_FLAG_INT(error_exit_code, 77, "When libFuzzer's signal handlers are in "
+ "use exit with this exitcode after catching a deadly signal.")
FUZZER_FLAG_INT(max_total_time, 0, "If positive, indicates the maximal total "
"time in seconds to run the fuzzer.")
FUZZER_FLAG_INT(help, 0, "Print help.")
@@ -76,3 +77,9 @@ FUZZER_FLAG_INT(output_csv, 0, "Enable p
FUZZER_FLAG_INT(print_new_cov_pcs, 0, "If 1, print out new covered pcs.")
FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.")
+FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
+FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGSEGV.")
+FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
+FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
+FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
+FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Tue Mar 1 16:19:21 2016
@@ -83,6 +83,12 @@ void PrintASCII(const Unit &U, const cha
void PrintASCII(const Word &W, const char *PrintAfter = "");
std::string Hash(const Unit &U);
void SetTimer(int Seconds);
+void SetSigSegvHandler();
+void SetSigBusHandler();
+void SetSigAbrtHandler();
+void SetSigIllHandler();
+void SetSigFpeHandler();
+void SetSigIntHandler();
std::string Base64(const Unit &U);
int ExecuteCommand(const std::string &Command);
size_t GetPeakRSSMb();
@@ -270,8 +276,8 @@ public:
int Verbosity = 1;
int MaxLen = 0;
int UnitTimeoutSec = 300;
- bool AbortOnTimeout = false;
int TimeoutExitCode = 77;
+ int ErrorExitCode = 77;
int MaxTotalTimeSec = 0;
bool DoCrossOver = true;
int MutateDepth = 5;
@@ -331,6 +337,8 @@ public:
size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
static void StaticAlarmCallback();
+ static void StaticCrashSignalCallback();
+ static void StaticInterruptCallback();
void ExecuteCallback(const uint8_t *Data, size_t Size);
@@ -341,6 +349,8 @@ public:
private:
void AlarmCallback();
+ void CrashCallback();
+ void InterruptCallback();
void MutateAndTestOne();
void ReportNewCoverage(const Unit &U);
bool RunOne(const uint8_t *Data, size_t Size);
@@ -372,6 +382,7 @@ private:
void SetDeathCallback();
static void StaticDeathCallback();
+ void DumpCurrentUnit(const char *Prefix);
void DeathCallback();
uint8_t *CurrentUnitData;
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Mar 1 16:19:21 2016
@@ -83,15 +83,19 @@ void Fuzzer::StaticDeathCallback() {
F->DeathCallback();
}
-void Fuzzer::DeathCallback() {
- if (!CurrentUnitSize) return;
- Printf("DEATH:\n");
+void Fuzzer::DumpCurrentUnit(const char *Prefix) {
if (CurrentUnitSize <= kMaxUnitSizeToPrint) {
PrintHexArray(CurrentUnitData, CurrentUnitSize, "\n");
PrintASCII(CurrentUnitData, CurrentUnitSize, "\n");
}
WriteUnitToFileWithPrefix(
- {CurrentUnitData, CurrentUnitData + CurrentUnitSize}, "crash-");
+ {CurrentUnitData, CurrentUnitData + CurrentUnitSize}, Prefix);
+}
+
+void Fuzzer::DeathCallback() {
+ if (!CurrentUnitSize) return;
+ Printf("DEATH:\n");
+ DumpCurrentUnit("crash-");
PrintFinalStats();
}
@@ -100,6 +104,35 @@ void Fuzzer::StaticAlarmCallback() {
F->AlarmCallback();
}
+void Fuzzer::StaticCrashSignalCallback() {
+ assert(F);
+ F->CrashCallback();
+}
+
+void Fuzzer::StaticInterruptCallback() {
+ assert(F);
+ F->InterruptCallback();
+}
+
+void Fuzzer::CrashCallback() {
+ Printf("==%d== ERROR: libFuzzer: deadly signal\n", GetPid());
+ if (__sanitizer_print_stack_trace)
+ __sanitizer_print_stack_trace();
+ Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"
+ " Combine libFuzzer with AddressSanitizer or similar for better "
+ "crash reports.\n");
+ Printf("SUMMARY: libFuzzer: deadly signal\n");
+ DumpCurrentUnit("crash-");
+ PrintFinalStats();
+ exit(Options.ErrorExitCode);
+}
+
+void Fuzzer::InterruptCallback() {
+ Printf("==%d== libFuzzer: run interrupted; exiting\n", GetPid());
+ PrintFinalStats();
+ exit(0);
+}
+
void Fuzzer::AlarmCallback() {
assert(Options.UnitTimeoutSec > 0);
if (!CurrentUnitSize)
@@ -114,20 +147,13 @@ void Fuzzer::AlarmCallback() {
Printf("ALARM: working on the last Unit for %zd seconds\n", Seconds);
Printf(" and the timeout value is %d (use -timeout=N to change)\n",
Options.UnitTimeoutSec);
- if (CurrentUnitSize <= kMaxUnitSizeToPrint) {
- PrintHexArray(CurrentUnitData, CurrentUnitSize, "\n");
- PrintASCII(CurrentUnitData, CurrentUnitSize, "\n");
- }
- WriteUnitToFileWithPrefix(
- {CurrentUnitData, CurrentUnitData + CurrentUnitSize}, "timeout-");
+ DumpCurrentUnit("timeout-");
Printf("==%d== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),
Seconds);
if (__sanitizer_print_stack_trace)
__sanitizer_print_stack_trace();
Printf("SUMMARY: libFuzzer: timeout\n");
PrintFinalStats();
- if (Options.AbortOnTimeout)
- abort();
exit(Options.TimeoutExitCode);
}
}
Modified: llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp Tue Mar 1 16:19:21 2016
@@ -71,17 +71,37 @@ static void AlarmHandler(int, siginfo_t
Fuzzer::StaticAlarmCallback();
}
+static void CrashHandler(int, siginfo_t *, void *) {
+ Fuzzer::StaticCrashSignalCallback();
+}
+
+static void InterruptHandler(int, siginfo_t *, void *) {
+ Fuzzer::StaticInterruptCallback();
+}
+
+static void SetSigaction(int signum,
+ void (*callback)(int, siginfo_t *, void *)) {
+ struct sigaction sigact;
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_sigaction = callback;
+ int Res = sigaction(signum, &sigact, 0);
+ assert(Res == 0);
+}
+
void SetTimer(int Seconds) {
struct itimerval T {{Seconds, 0}, {Seconds, 0}};
int Res = setitimer(ITIMER_REAL, &T, nullptr);
assert(Res == 0);
- struct sigaction sigact;
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = AlarmHandler;
- Res = sigaction(SIGALRM, &sigact, 0);
- assert(Res == 0);
+ 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); }
+
int NumberOfCpuCores() {
FILE *F = popen("nproc", "r");
int N = 0;
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer-timeout.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-timeout.test?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-timeout.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-timeout.test Tue Mar 1 16:19:21 2016
@@ -11,5 +11,4 @@ RUN: not LLVMFuzzer-TimeoutTest -timeout
SingleInputTimeoutTest: ALARM: working on the last Unit for
SingleInputTimeoutTest-NOT: Test unit written to ./timeout-
-RUN: ASAN_OPTIONS=handle_abort=0 not --crash LLVMFuzzer-TimeoutTest -timeout=1 -abort_on_timeout=1
RUN: LLVMFuzzer-TimeoutTest -timeout=1 -timeout_exitcode=0
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer.test?rev=262415&r1=262414&r2=262415&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer.test Tue Mar 1 16:19:21 2016
@@ -15,6 +15,11 @@ NullDerefTestPrefix: Test unit written t
RUN: not LLVMFuzzer-NullDerefTest -artifact_prefix=ZZZ -exact_artifact_path=FOOBAR 2>&1 | FileCheck %s --check-prefix=NullDerefTestExactPath
NullDerefTestExactPath: Test unit written to FOOBAR
+RUN: ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
+LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
+LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
+LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
+
#not LLVMFuzzer-FullCoverageSetTest -timeout=15 -seed=1 -mutate_depth=2 -use_full_coverage_set=1 2>&1 | FileCheck %s
RUN: not LLVMFuzzer-CounterTest -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s
More information about the llvm-commits
mailing list