[libFuzzer] allow passing 1 or more files as individual inputs

llvm-svn: 259459
This commit is contained in:
Kostya Serebryany 2016-02-02 03:03:47 +00:00
parent 74937fcd00
commit bfbe7fc404
5 changed files with 58 additions and 5 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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))

View File

@ -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,

View File

@ -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: