mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 14:20:29 +00:00
[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.
llvm-svn: 262415
This commit is contained in:
parent
9cb02b1f3e
commit
d5755334e5
@ -265,7 +265,6 @@ static int FuzzerDriver(const std::vector<std::string> &Args,
|
||||
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::vector<std::string> &Args,
|
||||
// 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);
|
||||
|
@ -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 pulse output in CSV format.")
|
||||
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.")
|
||||
|
@ -83,6 +83,12 @@ void PrintASCII(const Unit &U, const char *PrintAfter = "");
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -71,17 +71,37 @@ 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 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;
|
||||
|
@ -11,5 +11,4 @@ RUN: not LLVMFuzzer-TimeoutTest -timeout=1 -test_single_input=%S/hi.txt 2>&1 | F
|
||||
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
|
||||
|
@ -15,6 +15,11 @@ NullDerefTestPrefix: Test unit written to ZZZcrash-
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user