diff --git a/compiler-rt/lib/fuzzer/FuzzerCommand.h b/compiler-rt/lib/fuzzer/FuzzerCommand.h --- a/compiler-rt/lib/fuzzer/FuzzerCommand.h +++ b/compiler-rt/lib/fuzzer/FuzzerCommand.h @@ -66,6 +66,17 @@ Args.insert(endMutableArgs(), Arg); } + // Add the given path argument before "-ignore_remaining_args=1", or at the + // end if that flag isn't present. + void addPathArgument(const std::string &Path) { +#ifdef LIBFUZZER_WINDOWS + addArgument(Path); +#else + // Wrap the path with single quotes to avoid shell injection into system(). + addArgument("'" + Path + "'"); +#endif // LIBFUZZER_WINDOWS + } + // Adds all given arguments before "-ignore_remaining_args=1", or at the end // if that flag isn't present. void addArguments(const Vector &ArgsToAdd) { @@ -172,7 +183,6 @@ // If not empty, stdout is redirected to the named file. std::string OutputFile; }; - } // namespace fuzzer #endif // LLVM_FUZZER_COMMAND_H diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp --- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp @@ -266,9 +266,9 @@ std::unordered_map> DFTMap; std::unordered_set Cov; Command Cmd; - Cmd.addArgument(DFTBinary); - Cmd.addArgument(F.File); - Cmd.addArgument(OutPath); + Cmd.addPathArgument(DFTBinary); + Cmd.addPathArgument(F.File); + Cmd.addPathArgument(OutPath); Printf("CMD: %s\n", Cmd.toString().c_str()); ExecuteCommand(Cmd); } @@ -276,7 +276,7 @@ auto FunctionsTxtPath = DirPlusFile(DirPath, kFunctionsTxt); if (FileToString(FunctionsTxtPath).empty()) { Command Cmd; - Cmd.addArgument(DFTBinary); + Cmd.addPathArgument(DFTBinary); Cmd.setOutputFile(FunctionsTxtPath); ExecuteCommand(Cmd); } 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 @@ -399,7 +399,7 @@ CurrentFilePath.c_str(), U.size()); Command Cmd(BaseCmd); - Cmd.addArgument(CurrentFilePath); + Cmd.addPathArgument(CurrentFilePath); Printf("CRASH_MIN: executing: %s\n", Cmd.toString().c_str()); std::string CmdOutput; 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 @@ -156,8 +156,7 @@ Job->CFPath = DirPlusFile(TempDir, std::to_string(JobId) + ".merge"); Job->JobId = JobId; - - Cmd.addArgument(Job->CorpusDir); + Cmd.addPathArgument(Job->CorpusDir); Cmd.addFlag("features_dir", Job->FeaturesDir); for (auto &D : {Job->CorpusDir, Job->FeaturesDir}) { @@ -237,7 +236,7 @@ Cmd.removeFlag("fork"); Cmd.removeFlag("runs"); Cmd.addFlag("data_flow_trace", DFTDir); - Cmd.addArgument(InputPath); + Cmd.addPathArgument(InputPath); for (auto &C : CorpusDirs) // Remove all corpora from the args. Cmd.removeArgument(C); Cmd.setOutputFile(DirPlusFile(TempDir, "dft.log")); 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 @@ -105,7 +105,6 @@ X = X & ~Mask; return reinterpret_cast(X); } - } // namespace fuzzer #endif // LLVM_FUZZER_UTIL_H diff --git a/compiler-rt/test/fuzzer/minimize_crash.test b/compiler-rt/test/fuzzer/minimize_crash.test --- a/compiler-rt/test/fuzzer/minimize_crash.test +++ b/compiler-rt/test/fuzzer/minimize_crash.test @@ -15,3 +15,7 @@ MIN1: Test unit written to {{.*}}exact_minimized_path MIN1: INFO: The input is small enough, exiting MIN1: CRASH_MIN: failed to minimize beyond {{.*}}exact_minimized_path (1 bytes), exiting + +RUN: echo -n 'Hi!AAA' > '%t.dir/bad;(%file)name' +RUN: %run %t-NullDerefTest -minimize_crash=1 '%t.dir/bad;(%file)name' -max_total_time=2 2>&1 | FileCheck %s --check-prefix=BAD_FILENAME +BAD_FILENAME: failed to minimize beyond