From abe2ee53b68036a5be3064f262e0a43092a89e3c Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 15 Dec 2016 06:21:21 +0000 Subject: [PATCH] [libFuzzer] enable the failure-resistant merge by default (with trace-pc-guard only) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289772 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Fuzzer/FuzzerDriver.cpp | 20 +++++++++----------- lib/Fuzzer/FuzzerFlags.def | 2 -- lib/Fuzzer/FuzzerMerge.cpp | 4 ++-- lib/Fuzzer/test/merge.test | 32 ++++++++++++++++++++------------ 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index fb86cbc1efa..8a8c12fd6cb 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -15,6 +15,7 @@ #include "FuzzerIO.h" #include "FuzzerMutate.h" #include "FuzzerRandom.h" +#include "FuzzerTracePC.h" #include #include #include @@ -493,17 +494,14 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { if (Flags.merge) { if (Options.MaxLen == 0) F->SetMaxInputLen(kMaxSaneLen); - F->Merge(*Inputs); - exit(0); - } - - if (Flags.experimental_merge) { - if (Options.MaxLen == 0) - F->SetMaxInputLen(kMaxSaneLen); - if (Flags.merge_control_file) - F->CrashResistantMergeInternalStep(Flags.merge_control_file); - else - F->CrashResistantMerge(Args, *Inputs); + if (TPC.UsingTracePcGuard()) { + if (Flags.merge_control_file) + F->CrashResistantMergeInternalStep(Flags.merge_control_file); + else + F->CrashResistantMerge(Args, *Inputs); + } else { + F->Merge(*Inputs); + } exit(0); } diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index d32d6fca1ec..68dc820caa3 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -37,8 +37,6 @@ FUZZER_FLAG_INT(help, 0, "Print help.") 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.") -FUZZER_FLAG_INT(experimental_merge, 0, "Experimental crash-resistant, " - "may eventually replace -merge.") FUZZER_FLAG_STRING(merge_control_file, "internal flag") FUZZER_FLAG_INT(minimize_crash, 0, "If 1, minimizes the provided" " crash input. Use with -runs=N or -max_total_time=N to limit " diff --git a/lib/Fuzzer/FuzzerMerge.cpp b/lib/Fuzzer/FuzzerMerge.cpp index 855eef8ffc6..38479953a77 100644 --- a/lib/Fuzzer/FuzzerMerge.cpp +++ b/lib/Fuzzer/FuzzerMerge.cpp @@ -176,8 +176,8 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app); for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) { auto U = FileToVector(M.Files[i].Name); - if (U.size() > Options.MaxLen) { - U.resize(Options.MaxLen); + if (U.size() > MaxInputLen) { + U.resize(MaxInputLen); U.shrink_to_fit(); } std::ostringstream StartedLine; diff --git a/lib/Fuzzer/test/merge.test b/lib/Fuzzer/test/merge.test index ac07b79b34d..1f1810eb019 100644 --- a/lib/Fuzzer/test/merge.test +++ b/lib/Fuzzer/test/merge.test @@ -8,8 +8,8 @@ RUN: echo ..Z... > %tmp/T1/3 # T1 has 3 elements, T2 is empty. RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1 -CHECK1: === Minimizing the initial corpus of 3 units -CHECK1: === Merge: written 0 units +CHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus +CHECK1: MERGE-OUTER: 0 new files with 0 new features added RUN: echo ...Z.. > %tmp/T2/1 RUN: echo ....E. > %tmp/T2/2 @@ -20,19 +20,27 @@ RUN: echo ..Z... > %tmp/T2/c # T1 has 3 elements, T2 has 6 elements, only 3 are new. RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2 -CHECK2: === Minimizing the initial corpus of 3 units -CHECK2: === Merging extra 6 units -CHECK2: === Merge: written 3 units +CHECK2: MERGE-OUTER: 9 files, 3 in the initial corpus +CHECK2: MERGE-OUTER: 3 new files with 3 new features added # Now, T1 has 6 units and T2 has no new interesting units. RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3 -CHECK3: === Minimizing the initial corpus of 6 units -CHECK3: === Merge: written 0 units +CHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus +CHECK3: MERGE-OUTER: 0 new files with 0 new features added # Check that we respect max_len during the merge and don't crash. -RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=4 +RUN: rm %tmp/T1/??* +RUN: echo looooooooong > %tmp/T2/looooooooong +RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN +MAX_LEN: MERGE-OUTER: 3 new files -# Check that when merge fails we print an error message. -RUN: echo 'Hi!' > %tmp/T1/HiI -RUN: not LLVMFuzzer-NullDerefTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_FAIL -MERGE_FAIL: NOTE: merge did not succeed due to a failure on one of the inputs. +# Check that merge tolerates failures. +RUN: rm %tmp/T1/??* +RUN: echo 'FUZZER' > %tmp/T2/FUZZER +RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH +MERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s) +MERGE_WITH_CRASH: MERGE-OUTER: 3 new files + +# Check that we actually limit the size with max_len +RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5 +MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s) -- 2.11.0