summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2017-11-09 01:05:29 +0000
committerKostya Serebryany <kcc@google.com>2017-11-09 01:05:29 +0000
commite29c4b614a3c51fe462fb88e1a61c7efc435e295 (patch)
treeb8358ea9775d99956563675ed77823344ac57758 /lib
parent1a158e7ba1e130a8bbdfb1a20771adf60a85cbd5 (diff)
[libFuzzer] allow user to specify the merge control file
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317747 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/fuzzer/FuzzerDriver.cpp18
-rw-r--r--lib/fuzzer/FuzzerFlags.def5
-rw-r--r--lib/fuzzer/FuzzerInternal.h3
-rw-r--r--lib/fuzzer/FuzzerMerge.cpp22
4 files changed, 30 insertions, 18 deletions
diff --git a/lib/fuzzer/FuzzerDriver.cpp b/lib/fuzzer/FuzzerDriver.cpp
index 18c73ca75..abc314420 100644
--- a/lib/fuzzer/FuzzerDriver.cpp
+++ b/lib/fuzzer/FuzzerDriver.cpp
@@ -701,20 +701,22 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
}
if (Flags.merge) {
+ F->CrashResistantMerge(Args, *Inputs,
+ Flags.load_coverage_summary,
+ Flags.save_coverage_summary,
+ Flags.merge_control_file);
+ exit(0);
+ }
+
+ if (Flags.merge_inner) {
const size_t kDefaultMaxMergeLen = 1 << 20;
if (Options.MaxLen == 0)
F->SetMaxInputLen(kDefaultMaxMergeLen);
-
- if (Flags.merge_control_file)
- F->CrashResistantMergeInternalStep(Flags.merge_control_file);
- else
- F->CrashResistantMerge(Args, *Inputs,
- Flags.load_coverage_summary,
- Flags.save_coverage_summary);
+ assert(Flags.merge_control_file);
+ F->CrashResistantMergeInternalStep(Flags.merge_control_file);
exit(0);
}
-
if (Flags.analyze_dict) {
size_t MaxLen = INT_MAX; // Large max length.
UnitVector InitialCorpus;
diff --git a/lib/fuzzer/FuzzerFlags.def b/lib/fuzzer/FuzzerFlags.def
index e4bca46f0..db8c9eda0 100644
--- a/lib/fuzzer/FuzzerFlags.def
+++ b/lib/fuzzer/FuzzerFlags.def
@@ -38,7 +38,10 @@ FUZZER_FLAG_INT(help, 0, "Print help.")
FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be "
"merged into the 1-st corpus. Only interesting units will be taken. "
"This flag can be used to minimize a corpus.")
-FUZZER_FLAG_STRING(merge_control_file, "internal flag")
+FUZZER_FLAG_STRING(merge_inner, "internal flag")
+FUZZER_FLAG_STRING(merge_control_file,
+ "Specify a control file used for the merge proccess. "
+ "By default a temporary file will be used.")
FUZZER_FLAG_STRING(save_coverage_summary, "Experimental:"
" save coverage summary to a given file."
" Used with -merge=1")
diff --git a/lib/fuzzer/FuzzerInternal.h b/lib/fuzzer/FuzzerInternal.h
index 97c14085e..371624408 100644
--- a/lib/fuzzer/FuzzerInternal.h
+++ b/lib/fuzzer/FuzzerInternal.h
@@ -73,7 +73,8 @@ public:
void CrashResistantMerge(const Vector<std::string> &Args,
const Vector<std::string> &Corpora,
const char *CoverageSummaryInputPathOrNull,
- const char *CoverageSummaryOutputPathOrNull);
+ const char *CoverageSummaryOutputPathOrNull,
+ const char *MergeControlFilePathOrNull);
void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
MutationDispatcher &GetMD() { return MD; }
void PrintFinalStats();
diff --git a/lib/fuzzer/FuzzerMerge.cpp b/lib/fuzzer/FuzzerMerge.cpp
index 03cf00a56..e6e935dfc 100644
--- a/lib/fuzzer/FuzzerMerge.cpp
+++ b/lib/fuzzer/FuzzerMerge.cpp
@@ -260,7 +260,8 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {
void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args,
const Vector<std::string> &Corpora,
const char *CoverageSummaryInputPathOrNull,
- const char *CoverageSummaryOutputPathOrNull) {
+ const char *CoverageSummaryOutputPathOrNull,
+ const char *MergeControlFilePathOrNull) {
if (Corpora.size() <= 1) {
Printf("Merge requires two or more corpus dirs\n");
return;
@@ -274,8 +275,11 @@ void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args,
std::sort(AllFiles.begin() + NumFilesInFirstCorpus, AllFiles.end());
Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n",
AllFiles.size(), NumFilesInFirstCorpus);
- auto CFPath = DirPlusFile(TmpDir(),
- "libFuzzerTemp." + std::to_string(GetPid()) + ".txt");
+ auto CFPath =
+ MergeControlFilePathOrNull
+ ? MergeControlFilePathOrNull
+ : DirPlusFile(TmpDir(),
+ "libFuzzerTemp." + std::to_string(GetPid()) + ".txt");
// Write the control file.
RemoveFile(CFPath);
std::ofstream ControlFile(CFPath);
@@ -293,12 +297,13 @@ void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args,
// Execute the inner process untill it passes.
// Every inner process should execute at least one input.
auto BaseCmd = SplitBefore("-ignore_remaining_args=1",
- CloneArgsWithoutX(Args, "keep-all-flags"));
+ CloneArgsWithoutX(Args, "merge"));
bool Success = false;
for (size_t i = 1; i <= AllFiles.size(); i++) {
Printf("MERGE-OUTER: attempt %zd\n", i);
- auto ExitCode = ExecuteCommand(BaseCmd.first + " -merge_control_file=" +
- CFPath + " " + BaseCmd.second);
+ auto ExitCode =
+ ExecuteCommand(BaseCmd.first + " -merge_control_file=" + CFPath +
+ " -merge_inner=1 " + BaseCmd.second);
if (!ExitCode) {
Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", i);
Success = true;
@@ -338,8 +343,9 @@ void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args,
NewFiles.size(), NumNewFeatures);
for (auto &F: NewFiles)
WriteToOutputCorpus(FileToVector(F));
- // We are done, delete the control file.
- RemoveFile(CFPath);
+ // We are done, delete the control file if it was a temporary one.
+ if (!MergeControlFilePathOrNull)
+ RemoveFile(CFPath);
}
} // namespace fuzzer