diff options
| -rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerDriver.cpp | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerFlags.def | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerMerge.cpp | 6 | ||||
| -rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerOptions.h | 2 | ||||
| -rw-r--r-- | compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp | 22 | ||||
| -rw-r--r-- | compiler-rt/test/fuzzer/fork.test | 15 | ||||
| -rw-r--r-- | compiler-rt/test/fuzzer/merge.test | 3 |
7 files changed, 47 insertions, 11 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index 232b3a8732a..8ad99d0a3c2 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -533,6 +533,12 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options, Printf("INFO: temp_files: %zd files_added: %zd newft: %zd ft: %zd\n", TempFiles.size(), FilesToAdd.size(), NewFeatures.size(), Features.size()); + // Continue if our crash is one of the ignorred ones. + if (Options.IgnoreTimeouts && ExitCode == Options.TimeoutExitCode) + continue; + if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode) + continue; + // And exit if we don't ignore this crash. if (ExitCode != 0) break; } @@ -681,6 +687,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Options.UnitTimeoutSec = Flags.timeout; Options.ErrorExitCode = Flags.error_exitcode; Options.TimeoutExitCode = Flags.timeout_exitcode; + Options.IgnoreTimeouts = Flags.ignore_timeouts; + Options.IgnoreOOMs = Flags.ignore_ooms; Options.MaxTotalTimeSec = Flags.max_total_time; Options.DoCrossOver = Flags.cross_over; Options.MutateDepth = Flags.mutate_depth; diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def index caf541be820..d194a894f94 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFlags.def +++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -43,6 +43,8 @@ FUZZER_FLAG_INT(max_total_time, 0, "If positive, indicates the maximal total " FUZZER_FLAG_INT(help, 0, "Print help.") FUZZER_FLAG_INT(fork, 0, "Experimental mode where fuzzing happens " "in a subprocess") +FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode") +FUZZER_FLAG_INT(ignore_ooms, 1, "Ignore OOMs in fork mode") FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be " "merged into the 1-st corpus. Only interesting units will be taken. " "This flag can be used to minimize a corpus.") diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp index 4d00f7ed905..c61169a3ae8 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp @@ -299,7 +299,6 @@ void CrashResistantMerge(const Vector<std::string> &Args, Command BaseCmd(Args); BaseCmd.removeFlag("merge"); BaseCmd.removeFlag("fork"); - bool Success = false; for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) { Fuzzer::MaybeExitGracefully(); Printf("MERGE-OUTER: attempt %zd\n", Attempt); @@ -309,14 +308,9 @@ void CrashResistantMerge(const Vector<std::string> &Args, auto ExitCode = ExecuteCommand(Cmd); if (!ExitCode) { Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt); - Success = true; break; } } - if (!Success) { - Printf("MERGE-OUTER: zero succesfull attempts, exiting\n"); - exit(1); - } // Read the control file and do the merge. Merger M; std::ifstream IF(CFPath); diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h index 868327d58d0..628603ff520 100644 --- a/compiler-rt/lib/fuzzer/FuzzerOptions.h +++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h @@ -23,6 +23,8 @@ struct FuzzingOptions { int OOMExitCode = 71; int InterruptExitCode = 72; int ErrorExitCode = 77; + bool IgnoreTimeouts = 1; + bool IgnoreOOMs = 1; int MaxTotalTimeSec = 0; int RssLimitMb = 0; int MallocLimitMb = 0; diff --git a/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp b/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp new file mode 100644 index 00000000000..197fffa5e00 --- /dev/null +++ b/compiler-rt/test/fuzzer/ShallowOOMDeepCrash.cpp @@ -0,0 +1,22 @@ +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Simple test for a fuzzer. +// Here the target has a shallow OOM bug and a deeper crash. +// Make sure we can find the crash while ignoring OOMs. +#include <cstddef> +#include <cstdint> + +static volatile int *Sink; +static volatile int *Zero; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size >= 3 && Data[0] == 'O' && Data[1] == 'O' && Data[2] == 'M') + Sink = new int[1 << 28]; // instant OOM with -rss_limit_mb=128. + if (Size >= 4 && Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' && + Data[3] == 'Z') // a bit deeper crash. + *Zero = 42; + return 0; +} + diff --git a/compiler-rt/test/fuzzer/fork.test b/compiler-rt/test/fuzzer/fork.test index 8ce543c2c76..c267bee3fd1 100644 --- a/compiler-rt/test/fuzzer/fork.test +++ b/compiler-rt/test/fuzzer/fork.test @@ -1,5 +1,16 @@ # REQUIRES: linux -CHECK: BINGO +BINGO: BINGO RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest +RUN: not %run %t-SimpleTest -fork=1 2>&1 | FileCheck %s --check-prefix=BINGO -RUN: not %run %t-SimpleTest -fork=1 2>&1 | FileCheck %s +TIMEOUT: ERROR: libFuzzer: timeout +RUN: %cpp_compiler %S/TimeoutTest.cpp -o %t-TimeoutTest +RUN: not %run %t-TimeoutTest -fork=1 -timeout=1 -ignore_timeouts=0 2>&1 | FileCheck %s --check-prefix=TIMEOUT + +OOM: ERROR: libFuzzer: out-of-memory +RUN: %cpp_compiler %S/OutOfMemoryTest.cpp -o %t-OutOfMemoryTest +RUN: not %run %t-OutOfMemoryTest -fork=1 -ignore_ooms=0 -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=OOM + +CRASH: SEGV on unknown address 0x000000000000 +RUN: %cpp_compiler %S/ShallowOOMDeepCrash.cpp -o %t-ShallowOOMDeepCrash +RUN: not %run %t-ShallowOOMDeepCrash -fork=1 -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=CRASH diff --git a/compiler-rt/test/fuzzer/merge.test b/compiler-rt/test/fuzzer/merge.test index 24adda25f28..5e97d006d4b 100644 --- a/compiler-rt/test/fuzzer/merge.test +++ b/compiler-rt/test/fuzzer/merge.test @@ -65,6 +65,3 @@ RUN: not grep FUZZER %t/T1/* RUN: grep FUZZE %t/T1/* MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s) -RUN: rm -rf %t/T1/* %t/T2/* -RUN: not %run %t-FullCoverageSetTest -merge=1 %t/T1 %t/T2 2>&1 | FileCheck %s --check-prefix=EMPTY -EMPTY: MERGE-OUTER: zero succesfull attempts, exiting |

