diff options
author | Kostya Serebryany <kcc@google.com> | 2019-02-12 00:12:33 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2019-02-12 00:12:33 +0000 |
commit | 63f48717b58d76523fdbfdba6fa1e2c10ae9e3da (patch) | |
tree | 4d83c194d8dd5d507aac81d062664802b4df0929 /compiler-rt/lib/fuzzer/FuzzerDriver.cpp | |
parent | 9ebc9dbd3c7d8ce5fb35d3d166279b39808dac0b (diff) | |
download | bcm5719-llvm-63f48717b58d76523fdbfdba6fa1e2c10ae9e3da.tar.gz bcm5719-llvm-63f48717b58d76523fdbfdba6fa1e2c10ae9e3da.zip |
[libFuzzer] extend the -fork=1 functionality. Still not fully usable, but good enough for the first unit test
llvm-svn: 353775
Diffstat (limited to 'compiler-rt/lib/fuzzer/FuzzerDriver.cpp')
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerDriver.cpp | 66 |
1 files changed, 48 insertions, 18 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index c381fb84452..232b3a8732a 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -472,46 +472,76 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) { } // This is just a skeleton of an experimental -fork=1 feature. -void FuzzWithFork(const FuzzingOptions &Options, +void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options, const Vector<std::string> &Args, const Vector<std::string> &Corpora) { Printf("INFO: -fork=1: doing fuzzing in a separate process in order to " "be more resistant to crashes, timeouts, and OOMs\n"); + auto Rand = F->GetMD().GetRand(); Vector<SizedFile> Corpus; for (auto &Dir : Corpora) GetSizedFilesFromDir(Dir, &Corpus); std::sort(Corpus.begin(), Corpus.end()); + auto CFPath = TempPath(".fork"); Vector<std::string> Files; Set<uint32_t> Features; if (!Corpus.empty()) { - auto CFPath = TempPath(".fork"); CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath); RemoveFile(CFPath); } - Printf("INFO: -fork=1: %zd seeds, starting to fuzz\n", Files.size()); + auto TempDir = TempPath("Dir"); + MkDir(TempDir); + Printf("INFO: -fork=1: %zd seeds, starting to fuzz; scratch: %s\n", + Files.size(), TempDir.c_str()); - Command Cmd(Args); - Cmd.removeFlag("fork"); + Command BaseCmd(Args); + BaseCmd.removeFlag("fork"); for (auto &C : Corpora) // Remove all corpora from the args. - Cmd.removeArgument(C); - if (Files.size() >= 2) - Cmd.addFlag("seed_inputs", - Files.back() + "," + Files[Files.size() - 2]); - Cmd.addFlag("runs", "1000000"); - Cmd.addFlag("max_total_time", "30"); - for (size_t i = 0; i < 1000; i++) { + BaseCmd.removeArgument(C); + BaseCmd.addFlag("runs", "1000000"); + BaseCmd.addFlag("max_total_time", "30"); + BaseCmd.addArgument(TempDir); + int ExitCode = 0; + for (size_t i = 0; i < 1000000; i++) { + // TODO: take new files from disk e.g. those generated by another process. + Command Cmd(BaseCmd); + if (Files.size() >= 2) + Cmd.addFlag("seed_inputs", + Files[Rand.SkewTowardsLast(Files.size())] + "," + + Files[Rand.SkewTowardsLast(Files.size())]); Printf("RUN %s\n", Cmd.toString().c_str()); - int ExitCode = ExecuteCommand(Cmd); + RmFilesInDir(TempDir); + ExitCode = ExecuteCommand(Cmd); + Printf("Exit code: %d\n", ExitCode); if (ExitCode == Options.InterruptExitCode) - exit(0); - if (ExitCode == Options.TimeoutExitCode || ExitCode == Options.OOMExitCode) - continue; + break; + Vector<SizedFile> TempFiles; + Vector<std::string>FilesToAdd; + Set<uint32_t> NewFeatures; + GetSizedFilesFromDir(TempDir, &TempFiles); + CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features, + &NewFeatures, CFPath); + RemoveFile(CFPath); + for (auto &Path : FilesToAdd) { + auto NewPath = F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen)); + if (!NewPath.empty()) + Files.push_back(NewPath); + } + Features.insert(NewFeatures.begin(), NewFeatures.end()); + Printf("INFO: temp_files: %zd files_added: %zd newft: %zd ft: %zd\n", + TempFiles.size(), FilesToAdd.size(), NewFeatures.size(), + Features.size()); if (ExitCode != 0) break; } - exit(0); + RmFilesInDir(TempDir); + RmDir(TempDir); + + // Use the exit code from the last child process. + Printf("Fork: exiting: %d\n", ExitCode); + exit(ExitCode); } void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args, @@ -770,7 +800,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { } if (Flags.fork) - FuzzWithFork(Options, Args, *Inputs); + FuzzWithFork(F, Options, Args, *Inputs); if (Flags.merge) Merge(F, Options, Args, *Inputs, Flags.merge_control_file); |