diff options
author | Kostya Serebryany <kcc@google.com> | 2019-05-23 00:22:46 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2019-05-23 00:22:46 +0000 |
commit | b7cc3d9953312b1f31b673429fcd49864cae118b (patch) | |
tree | 48338cb7ce5c0696ca543e9b5fb80bf990dc38aa /compiler-rt/lib | |
parent | 020d7f1abbcbdf1e3b72140d77c8e63a0280add7 (diff) | |
download | bcm5719-llvm-b7cc3d9953312b1f31b673429fcd49864cae118b.tar.gz bcm5719-llvm-b7cc3d9953312b1f31b673429fcd49864cae118b.zip |
[libFuzzer] automatically collect the data flow trace (DFT) in the fork mode if -collect_data_flow= is given
llvm-svn: 361448
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerDriver.cpp | 4 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerFork.cpp | 36 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerMerge.cpp | 1 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerOptions.h | 1 |
5 files changed, 41 insertions, 3 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp index 975a98afc50..74bfa8f32df 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp @@ -174,6 +174,8 @@ bool DataFlowTrace::Init(const std::string &DirPath, if (*FocusFunction == L) FocusFuncIdx = NumFunctions - 1; } + if (!NumFunctions) + return false; if (*FocusFunction == "auto") { // AUTOFOCUS works like this: diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index 95ce8bbe994..d55caf4c6ec 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -700,6 +700,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Options.DataFlowTrace = Flags.data_flow_trace; if (Flags.features_dir) Options.FeaturesDir = Flags.features_dir; + if (Flags.collect_data_flow) + Options.CollectDataFlow = Flags.collect_data_flow; Options.LazyCounters = Flags.lazy_counters; unsigned Seed = Flags.seed; @@ -710,7 +712,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { if (Flags.verbosity) Printf("INFO: Seed: %u\n", Seed); - if (Flags.collect_data_flow) { + if (Flags.collect_data_flow && !Flags.fork && !Flags.merge) { if (RunIndividualFiles) return CollectDataFlow(Flags.collect_data_flow, Flags.data_flow_trace, ReadCorpora({}, *Inputs)); diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index dd16ec1e288..870a2244850 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -86,6 +86,8 @@ struct GlobalEnv { Vector<std::string> CorpusDirs; std::string MainCorpusDir; std::string TempDir; + std::string DFTDir; + std::string DataFlowBinary; Set<uint32_t> Features, Cov; Vector<std::string> Files; Random *Rand; @@ -109,13 +111,18 @@ struct GlobalEnv { Command Cmd(Args); Cmd.removeFlag("fork"); Cmd.removeFlag("runs"); + Cmd.removeFlag("collect_data_flow"); for (auto &C : CorpusDirs) // Remove all corpora from the args. Cmd.removeArgument(C); Cmd.addFlag("reload", "0"); // working in an isolated dir, no reload. Cmd.addFlag("print_final_stats", "1"); Cmd.addFlag("print_funcs", "0"); // no need to spend time symbolizing. Cmd.addFlag("max_total_time", std::to_string(std::min((size_t)300, JobId))); - + if (!DataFlowBinary.empty()) { + Cmd.addFlag("data_flow_trace", DFTDir); + if (!Cmd.hasFlag("focus_function")) + Cmd.addFlag("focus_function", "auto"); + } auto Job = new FuzzJob; std::string Seeds; if (size_t CorpusSubsetSize = @@ -124,7 +131,8 @@ struct GlobalEnv { Seeds += (Seeds.empty() ? "" : ",") + Files[Rand->SkewTowardsLast(Files.size())]; if (!Seeds.empty()) { - Job->SeedListPath = std::to_string(JobId) + ".seeds"; + Job->SeedListPath = + DirPlusFile(TempDir, std::to_string(JobId) + ".seeds"); WriteToFile(Seeds, Job->SeedListPath); Cmd.addFlag("seed_inputs", "@" + Job->SeedListPath); } @@ -188,6 +196,7 @@ struct GlobalEnv { auto NewPath = DirPlusFile(MainCorpusDir, Hash(U)); WriteToFile(U, NewPath); Files.push_back(NewPath); + CollectDFT(NewPath); } Features.insert(NewFeatures.begin(), NewFeatures.end()); Cov.insert(NewCov.begin(), NewCov.end()); @@ -204,6 +213,23 @@ struct GlobalEnv { Stats.average_exec_per_sec, NumOOMs, NumTimeouts, NumCrashes, secondsSinceProcessStartUp()); } + + + void CollectDFT(const std::string &InputPath) { + if (DataFlowBinary.empty()) return; + Command Cmd(Args); + Cmd.removeFlag("fork"); + Cmd.removeFlag("runs"); + Cmd.addFlag("data_flow_trace", DFTDir); + Cmd.addArgument(InputPath); + for (auto &C : CorpusDirs) // Remove all corpora from the args. + Cmd.removeArgument(C); + Cmd.setOutputFile(DirPlusFile(TempDir, "dft.log")); + Cmd.combineOutAndErr(); + // Printf("CollectDFT: %s %s\n", InputPath.c_str(), Cmd.toString().c_str()); + ExecuteCommand(Cmd); + } + }; struct JobQueue { @@ -248,14 +274,17 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, Env.Rand = &Rand; Env.Verbosity = Options.Verbosity; Env.ProcessStartTime = std::chrono::system_clock::now(); + Env.DataFlowBinary = Options.CollectDataFlow; Vector<SizedFile> SeedFiles; for (auto &Dir : CorpusDirs) GetSizedFilesFromDir(Dir, &SeedFiles); std::sort(SeedFiles.begin(), SeedFiles.end()); Env.TempDir = TempPath(".dir"); + Env.DFTDir = DirPlusFile(Env.TempDir, "DFT"); RmDirRecursive(Env.TempDir); // in case there is a leftover from old runs. MkDir(Env.TempDir); + MkDir(Env.DFTDir); if (CorpusDirs.empty()) @@ -267,6 +296,9 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, CrashResistantMerge(Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features, {}, &Env.Cov, CFPath, false); + for (auto &F : Env.Files) + Env.CollectDFT(F); + RemoveFile(CFPath); Printf("INFO: -fork=%d: %zd seed inputs, starting to fuzz in %s\n", NumJobs, Env.Files.size(), Env.TempDir.c_str()); diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp index dace45ece1d..75b2b5d59b9 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp @@ -324,6 +324,7 @@ void CrashResistantMerge(const Vector<std::string> &Args, Command BaseCmd(Args); BaseCmd.removeFlag("merge"); BaseCmd.removeFlag("fork"); + BaseCmd.removeFlag("collect_data_flow"); for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) { Fuzzer::MaybeExitGracefully(); VPrintf(V, "MERGE-OUTER: attempt %zd\n", Attempt); diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h index d48439daaf4..687f2ffa732 100644 --- a/compiler-rt/lib/fuzzer/FuzzerOptions.h +++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h @@ -51,6 +51,7 @@ struct FuzzingOptions { std::string ExitOnItem; std::string FocusFunction; std::string DataFlowTrace; + std::string CollectDataFlow; std::string FeaturesDir; bool SaveArtifacts = true; bool PrintNEW = true; // Print a status line when new units are found; |