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 @@ -306,8 +306,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 ""; @@ -317,6 +316,19 @@ return S.substr(Beg, End - Beg); } +static int ExecuteCommandWithPopen(const Command &Cmd, std::string *CmdOutput) { + FILE *Pipe = OpenProcessPipe(Cmd.toString().c_str(), "r"); + if (!Pipe) + return 1; + + if (CmdOutput) { + char TmpBuffer[128]; + while (fgets(TmpBuffer, sizeof(TmpBuffer), Pipe)) + CmdOutput->append(TmpBuffer); + } + return CloseProcessPipe(Pipe); +} + int CleanseCrashInput(const Vector &Args, const FuzzingOptions &Options) { if (Inputs->size() != 1 || !Flags.exact_artifact_path) { @@ -332,10 +344,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; @@ -370,7 +381,6 @@ } if (!Changed) break; } - RemoveFile(LogFilePath); return 0; } @@ -393,8 +403,6 @@ BaseCmd.addFlag("max_total_time", "600"); } - auto LogFilePath = TempPath(".txt"); - BaseCmd.setOutputFile(LogFilePath); BaseCmd.combineOutAndErr(); std::string CurrentFilePath = InputFilePath; @@ -406,9 +414,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); @@ -416,7 +424,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()); @@ -426,10 +434,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; @@ -439,7 +447,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()); @@ -456,7 +464,6 @@ CurrentFilePath = ArtifactPath; Printf("*********************************\n"); } - RemoveFile(LogFilePath); return 0; } @@ -491,7 +498,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,8 @@ [](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(), 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); } diff --git a/compiler-rt/lib/fuzzer/FuzzerUtil.h b/compiler-rt/lib/fuzzer/FuzzerUtil.h --- a/compiler-rt/lib/fuzzer/FuzzerUtil.h +++ b/compiler-rt/lib/fuzzer/FuzzerUtil.h @@ -59,6 +59,7 @@ int ExecuteCommand(const Command &Cmd); FILE *OpenProcessPipe(const char *Command, const char *Mode); +int CloseProcessPipe(FILE *F); const void *SearchMemory(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp --- a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp @@ -149,6 +149,10 @@ return popen(Command, Mode); } +int CloseProcessPipe(FILE *F) { + return pclose(F); +} + const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, size_t PattLen) { return memmem(Data, DataLen, Patt, PattLen); diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilWindows.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilWindows.cpp --- a/compiler-rt/lib/fuzzer/FuzzerUtilWindows.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilWindows.cpp @@ -152,6 +152,10 @@ return _popen(Command, Mode); } +int CloseProcessPipe(FILE *F) { + return _pclose(F); +} + int ExecuteCommand(const Command &Cmd) { std::string CmdLine = Cmd.toString(); return system(CmdLine.c_str());