diff options
Diffstat (limited to 'compiler-rt/lib/fuzzer/FuzzerFork.cpp')
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerFork.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index 20c9950b349..9f315e8c125 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -11,6 +11,7 @@ #include "FuzzerCommand.h" #include "FuzzerFork.h" #include "FuzzerIO.h" +#include "FuzzerInternal.h" #include "FuzzerMerge.h" #include "FuzzerSHA1.h" #include "FuzzerTracePC.h" @@ -63,6 +64,7 @@ struct FuzzJob { // Inputs. Command Cmd; std::string CorpusDir; + std::string FeaturesDir; std::string LogPath; std::string CFPath; @@ -73,6 +75,7 @@ struct FuzzJob { RemoveFile(CFPath); RemoveFile(LogPath); RmDirRecursive(CorpusDir); + RmDirRecursive(FeaturesDir); } }; @@ -122,12 +125,17 @@ struct GlobalEnv { Cmd.addFlag("seed_inputs", Seeds); Job->LogPath = DirPlusFile(TempDir, std::to_string(JobId) + ".log"); Job->CorpusDir = DirPlusFile(TempDir, "C" + std::to_string(JobId)); + Job->FeaturesDir = DirPlusFile(TempDir, "F" + std::to_string(JobId)); Job->CFPath = DirPlusFile(TempDir, std::to_string(JobId) + ".merge"); Cmd.addArgument(Job->CorpusDir); - RmDirRecursive(Job->CorpusDir); - MkDir(Job->CorpusDir); + Cmd.addFlag("features_dir", Job->FeaturesDir); + + for (auto &D : {Job->CorpusDir, Job->FeaturesDir}) { + RmDirRecursive(D); + MkDir(D); + } Cmd.setOutputFile(Job->LogPath); Cmd.combineOutAndErr(); @@ -142,12 +150,30 @@ struct GlobalEnv { } void RunOneMergeJob(FuzzJob *Job) { - Vector<SizedFile> TempFiles; + Vector<SizedFile> TempFiles, MergeCandidates; + // Read all newly created inputs and their feature sets. + // Choose only those inputs that have new features. GetSizedFilesFromDir(Job->CorpusDir, &TempFiles); + std::sort(TempFiles.begin(), TempFiles.end()); + for (auto &F : TempFiles) { + auto FeatureFile = F.File; + FeatureFile.replace(0, Job->CorpusDir.size(), Job->FeaturesDir); + auto FeatureBytes = FileToVector(FeatureFile, 0, false); + assert((FeatureBytes.size() % sizeof(uint32_t)) == 0); + Vector<uint32_t> NewFeatures(FeatureBytes.size() / sizeof(uint32_t)); + memcpy(NewFeatures.data(), FeatureBytes.data(), FeatureBytes.size()); + for (auto Ft : NewFeatures) { + if (!Features.count(Ft)) { + MergeCandidates.push_back(F); + break; + } + } + } + if (MergeCandidates.empty()) return; Vector<std::string> FilesToAdd; Set<uint32_t> NewFeatures, NewCov; - CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features, + CrashResistantMerge(Args, {}, MergeCandidates, &FilesToAdd, Features, &NewFeatures, Cov, &NewCov, Job->CFPath, false); for (auto &Path : FilesToAdd) { auto U = FileToVector(Path); @@ -265,6 +291,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, Stop = true; break; } + Fuzzer::MaybeExitGracefully(); Env.RunOneMergeJob(Job.get()); |