diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -33,8 +33,12 @@ #if LIBFUZZER_MSVC extern "C" void __libfuzzer_is_present() {} #pragma comment(linker, "/include:__libfuzzer_is_present") +#define POPEN _popen +#define PCLOSE _pclose #else extern "C" __attribute__((used)) void __libfuzzer_is_present() {} +#define POPEN popen +#define PCLOSE pclose #endif // LIBFUZZER_MSVC namespace fuzzer { @@ -303,8 +307,7 @@ return true; } -static std::string GetDedupTokenFromFile(const std::string &Path) { - auto S = FileToString(Path); +static std::string GetDedupTokenFromCmdOutput(const std::string &S) { auto Beg = S.find("DEDUP_TOKEN:"); if (Beg == std::string::npos) return ""; @@ -314,6 +317,19 @@ return S.substr(Beg, End - Beg); } +static int ExecuteCommandWithPopen(const Command &Cmd, std::string *CmdOutput) { + FILE *Pipe = POPEN(Cmd.toString().c_str(), "r"); + if(!Pipe) + return 1; + + if (CmdOutput) { + char TmpBuffer[128]; + while(fgets(TmpBuffer, 128, Pipe)) + CmdOutput->append(TmpBuffer); + } + return PCLOSE(Pipe); +} + int CleanseCrashInput(const Vector &Args, const FuzzingOptions &Options) { if (Inputs->size() != 1 || !Flags.exact_artifact_path) { @@ -329,10 +345,9 @@ assert(Cmd.hasArgument(InputFilePath)); Cmd.removeArgument(InputFilePath); - auto LogFilePath = TempPath(".txt"); - auto TmpFilePath = TempPath(".repro"); + auto TmpFilePath = TempPath("CleanseCrashInput", ".repro"); Cmd.addArgument(TmpFilePath); - Cmd.setOutputFile(LogFilePath); + Cmd.setOutputFile(getDevNull()); Cmd.combineOutAndErr(); std::string CurrentFilePath = InputFilePath; @@ -367,7 +382,6 @@ } if (!Changed) break; } - RemoveFile(LogFilePath); return 0; } @@ -390,8 +404,6 @@ BaseCmd.addFlag("max_total_time", "600"); } - auto LogFilePath = TempPath(".txt"); - BaseCmd.setOutputFile(LogFilePath); BaseCmd.combineOutAndErr(); std::string CurrentFilePath = InputFilePath; @@ -403,9 +415,9 @@ Command Cmd(BaseCmd); Cmd.addArgument(CurrentFilePath); - std::string CommandLine = Cmd.toString(); - Printf("CRASH_MIN: executing: %s\n", CommandLine.c_str()); - int ExitCode = ExecuteCommand(Cmd); + Printf("CRASH_MIN: executing: %s\n", Cmd.toString().c_str()); + std::string CmdOutput; + int ExitCode = ExecuteCommandWithPopen(Cmd, &CmdOutput); if (ExitCode == 0) { Printf("ERROR: the input %s did not crash\n", CurrentFilePath.c_str()); exit(1); @@ -413,7 +425,7 @@ Printf("CRASH_MIN: '%s' (%zd bytes) caused a crash. Will try to minimize " "it further\n", CurrentFilePath.c_str(), U.size()); - auto DedupToken1 = GetDedupTokenFromFile(LogFilePath); + auto DedupToken1 = GetDedupTokenFromCmdOutput(CmdOutput); if (!DedupToken1.empty()) Printf("CRASH_MIN: DedupToken1: %s\n", DedupToken1.c_str()); @@ -423,10 +435,10 @@ : Options.ArtifactPrefix + "minimized-from-" + Hash(U); Cmd.addFlag("minimize_crash_internal_step", "1"); Cmd.addFlag("exact_artifact_path", ArtifactPath); - CommandLine = Cmd.toString(); - Printf("CRASH_MIN: executing: %s\n", CommandLine.c_str()); - ExitCode = ExecuteCommand(Cmd); - CopyFileToErr(LogFilePath); + Printf("CRASH_MIN: executing: %s\n", Cmd.toString().c_str()); + CmdOutput.clear(); + ExitCode = ExecuteCommandWithPopen(Cmd, &CmdOutput); + Printf("%s", CmdOutput.c_str()); if (ExitCode == 0) { if (Flags.exact_artifact_path) { CurrentFilePath = Flags.exact_artifact_path; @@ -436,7 +448,7 @@ CurrentFilePath.c_str(), U.size()); break; } - auto DedupToken2 = GetDedupTokenFromFile(LogFilePath); + auto DedupToken2 = GetDedupTokenFromCmdOutput(CmdOutput); if (!DedupToken2.empty()) Printf("CRASH_MIN: DedupToken2: %s\n", DedupToken2.c_str()); @@ -453,7 +465,6 @@ CurrentFilePath = ArtifactPath; Printf("*********************************\n"); } - RemoveFile(LogFilePath); return 0; } @@ -488,7 +499,7 @@ std::sort(OldCorpus.begin(), OldCorpus.end()); std::sort(NewCorpus.begin(), NewCorpus.end()); - std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath(".txt"); + std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath("Merge", ".txt"); Vector NewFiles; Set NewFeatures, NewCov; CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures, diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -297,7 +297,7 @@ for (auto &Dir : CorpusDirs) GetSizedFilesFromDir(Dir, &SeedFiles); std::sort(SeedFiles.begin(), SeedFiles.end()); - Env.TempDir = TempPath(".dir"); + Env.TempDir = TempPath("FuzzWithFork", ".dir"); Env.DFTDir = DirPlusFile(Env.TempDir, "DFT"); RmDirRecursive(Env.TempDir); // in case there is a leftover from old runs. MkDir(Env.TempDir); diff --git a/compiler-rt/lib/fuzzer/FuzzerIO.h b/compiler-rt/lib/fuzzer/FuzzerIO.h --- a/compiler-rt/lib/fuzzer/FuzzerIO.h +++ b/compiler-rt/lib/fuzzer/FuzzerIO.h @@ -42,7 +42,7 @@ // Returns path to a TmpDir. std::string TmpDir(); -std::string TempPath(const char *Extension); +std::string TempPath(const char *Prefix, const char *Extension); bool IsInterestingCoverageFile(const std::string &FileName); diff --git a/compiler-rt/lib/fuzzer/FuzzerIO.cpp b/compiler-rt/lib/fuzzer/FuzzerIO.cpp --- a/compiler-rt/lib/fuzzer/FuzzerIO.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerIO.cpp @@ -151,9 +151,9 @@ [](const std::string &Path) { RemoveFile(Path); }); } -std::string TempPath(const char *Extension) { - return DirPlusFile(TmpDir(), - "libFuzzerTemp." + std::to_string(GetPid()) + Extension); +std::string TempPath(const char *Prefix, const char *Extension) { + return DirPlusFile(TmpDir(), std::string("libFuzzerTemp.") + Prefix + + std::to_string(GetPid()) + Extension); } } // namespace fuzzer diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp --- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -256,7 +256,7 @@ void Fuzzer::MaybeExitGracefully() { if (!F->GracefulExitRequested) return; Printf("==%lu== INFO: libFuzzer: exiting as requested\n", GetPid()); - RmDirRecursive(TempPath(".dir")); + RmDirRecursive(TempPath("FuzzWithFork", ".dir")); F->PrintFinalStats(); _Exit(0); } @@ -265,7 +265,7 @@ Printf("==%lu== libFuzzer: run interrupted; exiting\n", GetPid()); PrintFinalStats(); ScopedDisableMsanInterceptorChecks S; // RmDirRecursive may call opendir(). - RmDirRecursive(TempPath(".dir")); + RmDirRecursive(TempPath("FuzzWithFork", ".dir")); // Stop right now, don't perform any at-exit actions. _Exit(Options.InterruptExitCode); }