diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/docs/LibFuzzer.rst | 13 | ||||
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerDriver.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerIO.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerInternal.h | 1 | ||||
-rw-r--r-- | llvm/lib/Fuzzer/test/fuzzer.test | 12 |
5 files changed, 58 insertions, 5 deletions
diff --git a/llvm/docs/LibFuzzer.rst b/llvm/docs/LibFuzzer.rst index b4c89197d82..914a78262a9 100644 --- a/llvm/docs/LibFuzzer.rst +++ b/llvm/docs/LibFuzzer.rst @@ -51,8 +51,16 @@ and is used to fuzz various parts of LLVM, but the Fuzzer itself does not (and should not) depend on any part of LLVM and can be used for other projects w/o requiring the rest of LLVM. -Flags -===== +Usage: +====== +To run fuzzing pass 0 or more directories:: + +./fuzzer [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ] + +To run individual tests without fuzzing pass 1 or more files:: + +./fuzzer [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...] + The most important flags are:: seed 0 Random seed. If 0, seed is generated. @@ -72,7 +80,6 @@ The most important flags are:: sync_timeout 600 Minimum timeout between syncs. use_traces 0 Experimental: use instruction traces only_ascii 0 If 1, generate only ASCII (isprint+isspace) inputs. - test_single_input "" Use specified file content as test input. Test will be run only once. Useful for debugging a particular case. artifact_prefix "" Write fuzzing artifacts (crash, timeout, or slow inputs) as $(artifact_prefix)file exact_artifact_path "" Write the single artifact on failure (crash, timeout) as $(exact_artifact_path). This overrides -artifact_prefix and will not use checksum in the file name. Do not use the same path for several parallel processes. diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp index e73feaf5cd8..8c81c9d54e8 100644 --- a/llvm/lib/Fuzzer/FuzzerDriver.cpp +++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp @@ -70,8 +70,14 @@ static std::vector<std::string> *Inputs; static std::string *ProgName; static void PrintHelp() { - Printf("Usage: %s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", - ProgName->c_str()); + Printf("Usage:\n"); + auto Prog = ProgName->c_str(); + Printf("\nTo run fuzzing pass 0 or more directories.\n"); + Printf("%s [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n", Prog); + + Printf("\nTo run individual tests without fuzzing pass 1 or more files:\n"); + Printf("%s [-flag1=val1 [-flag2=val2 ...] ] file1 [file2 ...]\n", Prog); + Printf("\nFlags: (strictly in form -flag=value)\n"); size_t MaxFlagLen = 0; for (size_t F = 0; F < kNumFlags; F++) @@ -227,6 +233,14 @@ int RunOneTest(Fuzzer *F, const char *InputFilePath) { return 0; } +static bool AllInputsAreFiles() { + if (Inputs->empty()) return false; + for (auto &Path : *Inputs) + if (!IsFile(Path)) + return false; + return true; +} + int FuzzerDriver(int argc, char **argv, UserCallback Callback) { FuzzerRandom_mt19937 Rand(0); SimpleUserSuppliedFuzzer SUSF(&Rand, Callback); @@ -320,6 +334,18 @@ int FuzzerDriver(const std::vector<std::string> &Args, exit(0); } + if (AllInputsAreFiles()) { + Printf("%s: Running %zd inputs.\n", ProgName->c_str(), Inputs->size()); + for (auto &Path : *Inputs) { + auto StartTime = system_clock::now(); + RunOneTest(&F, Path.c_str()); + auto StopTime = system_clock::now(); + auto MS = duration_cast<milliseconds>(StopTime - StartTime).count(); + Printf("%s: %zd ms\n", Path.c_str(), (long)MS); + } + exit(0); + } + if (Flags.save_minimized_corpus) { Printf("The flag -save_minimized_corpus is deprecated; use -merge=1\n"); exit(1); diff --git a/llvm/lib/Fuzzer/FuzzerIO.cpp b/llvm/lib/Fuzzer/FuzzerIO.cpp index cc65876f241..9df6837442c 100644 --- a/llvm/lib/Fuzzer/FuzzerIO.cpp +++ b/llvm/lib/Fuzzer/FuzzerIO.cpp @@ -20,6 +20,13 @@ namespace fuzzer { +bool IsFile(const std::string &Path) { + struct stat St; + if (stat(Path.c_str(), &St)) + return false; + return S_ISREG(St.st_mode); +} + static long GetEpoch(const std::string &Path) { struct stat St; if (stat(Path.c_str(), &St)) diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index d506f8fabab..07f45af08ff 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -62,6 +62,7 @@ private: typedef FixedWord<27> Word; // 28 bytes. +bool IsFile(const std::string &Path); std::string FileToString(const std::string &Path); Unit FileToVector(const std::string &Path); void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V, diff --git a/llvm/lib/Fuzzer/test/fuzzer.test b/llvm/lib/Fuzzer/test/fuzzer.test index 86ef32a2af3..3a617784b95 100644 --- a/llvm/lib/Fuzzer/test/fuzzer.test +++ b/llvm/lib/Fuzzer/test/fuzzer.test @@ -45,3 +45,15 @@ CHECK_SEED_MINUS_ONE: Seed: 4294967295 RUN: not LLVMFuzzer-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR NONEXISTENT_DIR: No such directory: NONEXISTENT_DIR; exiting + + +RUN: rm -rf %tmp/SINGLE_INPUTS +RUN: mkdir -p %tmp/SINGLE_INPUTS +RUN: echo aaa > %tmp/SINGLE_INPUTS/aaa +RUN: echo bbb > %tmp/SINGLE_INPUTS/bbb +RUN: LLVMFuzzer-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS +RUN: rm -rf %tmp/SINGLE_INPUTS +SINGLE_INPUTS: LLVMFuzzer-SimpleTest: Running 2 inputs. +SINGLE_INPUTS: aaa: +SINGLE_INPUTS: bbb: + |