From ad7b908b4ef973a139fc8b78dd95990e66aabbe3 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Fri, 31 Jan 2020 13:19:03 -0800 Subject: [PATCH] [libFuzzer] Make dataflow and focus functions more user friendly. Summary: - Fail loudly if SetFocusFunction failed when it should not. For more info see - https://github.com/google/oss-fuzz/issues/3311 - https://github.com/google/sanitizers/issues/1190 - Fail loudly if CollectDataFlow is called without seed corpus. Reviewers: kcc, metzman Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D73813 --- compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp | 5 +++++ compiler-rt/lib/fuzzer/FuzzerTracePC.cpp | 8 +++++++- compiler-rt/test/fuzzer/dataflow.test | 6 ++++++ .../test/fuzzer/{target-function.test => focus-function.test} | 4 ++-- 4 files changed, 20 insertions(+), 3 deletions(-) rename compiler-rt/test/fuzzer/{target-function.test => focus-function.test} (87%) diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp index 99ff918..48df8e6 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp @@ -248,6 +248,11 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath, const Vector &CorporaFiles) { Printf("INFO: collecting data flow: bin: %s dir: %s files: %zd\n", DFTBinary.c_str(), DirPath.c_str(), CorporaFiles.size()); + if (CorporaFiles.empty()) { + Printf("ERROR: can't collect data flow without corpus provided."); + return 1; + } + static char DFSanEnv[] = "DFSAN_OPTIONS=fast16labels=1:warn_unimplemented=0"; putenv(DFSanEnv); MkDir(DirPath); diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp index f03be7a..86649f9 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -240,7 +240,9 @@ void TracePC::IterateCoveredFunctions(CallBack CB) { void TracePC::SetFocusFunction(const std::string &FuncName) { // This function should be called once. assert(!FocusFunctionCounterPtr); - if (FuncName.empty()) + // "auto" is not a valid function name. If this function is called with "auto" + // that means the auto focus functionality failed. + if (FuncName.empty() || FuncName == "auto") return; for (size_t M = 0; M < NumModules; M++) { auto &PCTE = ModulePCTable[M]; @@ -256,6 +258,10 @@ void TracePC::SetFocusFunction(const std::string &FuncName) { return; } } + + Printf("ERROR: Failed to set focus function. Make sure the function name is " + "valid (%s) and symbolization is enabled.\n", FuncName.c_str()); + exit(1); } bool TracePC::ObservedFocusFunction() { diff --git a/compiler-rt/test/fuzzer/dataflow.test b/compiler-rt/test/fuzzer/dataflow.test index 57c4370..8227272 100644 --- a/compiler-rt/test/fuzzer/dataflow.test +++ b/compiler-rt/test/fuzzer/dataflow.test @@ -118,3 +118,9 @@ RUN: printf "%0.sA" {1..150001} > %t/IN/very_long_input RUN: rm -rf %t/OUT RUN: %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN/very_long_input RUN: rm %t/IN/very_long_input + +# Test that it fails explicitly when an empty corpus is provided. +RUN: rm -rf %t/IN && mkdir %t/IN +RUN: not %t-ThreeFunctionsTest -collect_data_flow=%t-ThreeFunctionsTestDF -data_flow_trace=%t/OUT %t/IN 2>&1 | FileCheck %s --check-prefix=EMPTY_CORPUS + +EMPTY_CORPUS: ERROR: can't collect data flow without corpus provided diff --git a/compiler-rt/test/fuzzer/target-function.test b/compiler-rt/test/fuzzer/focus-function.test similarity index 87% rename from compiler-rt/test/fuzzer/target-function.test rename to compiler-rt/test/fuzzer/focus-function.test index afd29ab..2485c6c 100644 --- a/compiler-rt/test/fuzzer/target-function.test +++ b/compiler-rt/test/fuzzer/focus-function.test @@ -10,9 +10,9 @@ RUN: %t-exe -runs=100 2>&1 | FileCheck %s --check-prefix=FOCUS_NONE FOCUS_NONE-NOT: INFO: Focus function is set to FOCUS_NONE-NOT: INFO: {{.*}} inputs touch the focus function -RUN: %t-exe -runs=100 -focus_function=WRONG 2>&1 | FileCheck %s --check-prefix=FOCUS_WRONG +RUN: not %t-exe -runs=100 -focus_function=WRONG 2>&1 | FileCheck %s --check-prefix=FOCUS_WRONG FOCUS_WRONG-NOT: INFO: Focus function is set to -FOCUS_WRONG: INFO: 0/1 inputs touch the focus function +FOCUS_WRONG: ERROR: Failed to set focus function RUN: %t-exe -runs=100 -focus_function=f0 2>&1 | FileCheck %s --check-prefix=FOCUS_F0 FOCUS_F0: INFO: Focus function is set to 'f0' -- 2.7.4