From 9722d3200d0c6595ba33f9c109737709a3b18551 Mon Sep 17 00:00:00 2001 From: gtt1995 <1271159369@qq.com> Date: Thu, 8 Apr 2021 10:08:17 +0800 Subject: [PATCH] Divide the corpus into n parts according to the size, and each job executes each corpus in turn, that is, allocate more energy to the small seeds, trigger the common path in advance, and prefer to keep the small seeds. --- compiler-rt/lib/fuzzer/FuzzerDriver.cpp | 2 +- compiler-rt/lib/fuzzer/FuzzerFlags.def | 1 + compiler-rt/lib/fuzzer/FuzzerFork.cpp | 36 +++++++++++++++++++++---- compiler-rt/lib/fuzzer/FuzzerFork.h | 2 +- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index ceaa9070512f0..2058e25388fb0 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -867,7 +867,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { } if (Flags.fork) - FuzzWithFork(F->GetMD().GetRand(), Options, Args, *Inputs, Flags.fork); + FuzzWithFork(F->GetMD().GetRand(), Options, Args, *Inputs, Flags.fork, Flags.NumCorpuses); if (Flags.merge) Merge(F, Options, Args, *Inputs, Flags.merge_control_file); diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def index ab31da0ae5d60..03e5b0ef9048f 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFlags.def +++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -56,6 +56,7 @@ FUZZER_FLAG_INT(timeout_exitcode, 70, "When libFuzzer reports a timeout " 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.") +FUZZER_FLAG_INT(NumCorpuses, 1, "Divide the corpus into N parts according to size.") FUZZER_FLAG_INT(fork, 0, "Experimental mode where fuzzing happens " "in a subprocess") FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode") diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index 5134a5d979e6b..3dfc4385a4e68 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -114,7 +114,7 @@ struct GlobalEnv { .count(); } - FuzzJob *CreateNewJob(size_t JobId) { + FuzzJob *CreateNewJob(size_t JobId, int NumCorpuses) { Command Cmd(Args); Cmd.removeFlag("fork"); Cmd.removeFlag("runs"); @@ -133,7 +133,7 @@ struct GlobalEnv { } auto Job = new FuzzJob; std::string Seeds; - if (size_t CorpusSubsetSize = + /*if (size_t CorpusSubsetSize = std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) { auto Time1 = std::chrono::system_clock::now(); for (size_t i = 0; i < CorpusSubsetSize; i++) { @@ -145,6 +145,31 @@ struct GlobalEnv { auto DftTimeInSeconds = duration_cast(Time2 - Time1).count(); assert(DftTimeInSeconds < std::numeric_limits::max()); Job->DftTimeInSeconds = static_cast(DftTimeInSeconds); + }*/ + if (size_t CorpusSubsetSize = + std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) { + size_t AverageSize = Files.size()/NumCorpuses +1; + auto Time1 = std::chrono::system_clock::now(); + size_t StartIndex = ((JobId-1)%NumCorpuses) * AverageSize; + printf("\n Job %d Choose Corpus %d ",JobId,(JobId)%NumCorpuses); + for (size_t i = 0; i < CorpusSubsetSize; i++) { + size_t j = Rand->SkewTowardsLast(AverageSize); + size_t m = j + StartIndex; + if (m < Files.size()) { + auto &SF = Files[m]; + Seeds += (Seeds.empty() ? "" : ",") + SF; + CollectDFT(SF); + } + else { + auto &SF = Files[Rand->SkewTowardsLast(Files.size())]; + Seeds += (Seeds.empty() ? "" : ",") + SF; + CollectDFT(SF); + } + } + auto Time2 = std::chrono::system_clock::now(); + auto DftTimeInSeconds = duration_cast(Time2 - Time1).count(); + assert(DftTimeInSeconds < std::numeric_limits::max()); + Job->DftTimeInSeconds = static_cast(DftTimeInSeconds); } if (!Seeds.empty()) { Job->SeedListPath = @@ -284,7 +309,7 @@ void WorkerThread(JobQueue *FuzzQ, JobQueue *MergeQ) { // This is just a skeleton of an experimental -fork=1 feature. void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, const Vector &Args, - const Vector &CorpusDirs, int NumJobs) { + const Vector &CorpusDirs, int NumJobs, int NumCorpuses) { Printf("INFO: -fork=%d: fuzzing in separate process(s)\n", NumJobs); GlobalEnv Env; @@ -341,8 +366,9 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, Vector Threads; for (int t = 0; t < NumJobs; t++) { Threads.push_back(std::thread(WorkerThread, &FuzzQ, &MergeQ)); - FuzzQ.Push(Env.CreateNewJob(JobId++)); + FuzzQ.Push(Env.CreateNewJob(JobId++, NumCorpuses)); } + //printf("\n 创建%d个jobs\n",NumJobs); while (true) { std::unique_ptr Job(MergeQ.Pop()); @@ -399,7 +425,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, break; } - FuzzQ.Push(Env.CreateNewJob(JobId++)); + FuzzQ.Push(Env.CreateNewJob(JobId++, NumCorpuses)); } for (auto &T : Threads) diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.h b/compiler-rt/lib/fuzzer/FuzzerFork.h index b29a43e13fbc5..5bf40d0b13265 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.h +++ b/compiler-rt/lib/fuzzer/FuzzerFork.h @@ -18,7 +18,7 @@ namespace fuzzer { void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, const Vector &Args, - const Vector &CorpusDirs, int NumJobs); + const Vector &CorpusDirs, int NumJobs, int NumCorpuses); } // namespace fuzzer #endif // LLVM_FUZZER_FORK_H