Skip to content

Commit d1449be

Browse files
author
kcc
committed
[libFuzzer] refactor the merging code, NFC
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@353576 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f259359 commit d1449be

File tree

3 files changed

+52
-37
lines changed

3 files changed

+52
-37
lines changed

FuzzerDriver.cpp

+36-18
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,21 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
471471
return 0;
472472
}
473473

474-
// This is just a sceleton of an experimental -fork=1 feature.
474+
// This is just a skeleton of an experimental -fork=1 feature.
475475
void FuzzWithFork(const FuzzingOptions &Options,
476476
const Vector<std::string> &Args,
477477
const Vector<std::string> &Corpora) {
478478
auto CFPath = TempPath(".fork");
479479
Printf("INFO: -fork=1: doing fuzzing in a separate process in order to "
480480
"be more resistant to crashes, timeouts, and OOMs\n");
481-
auto Files = CrashResistantMerge(Args, Corpora, CFPath);
481+
482+
483+
Vector<SizedFile> Corpus;
484+
for (auto &Dir : Corpora)
485+
GetSizedFilesFromDir(Dir, &Corpus);
486+
std::sort(Corpus.begin(), Corpus.end());
487+
488+
auto Files = CrashResistantMerge(Args, {}, Corpus, CFPath);
482489
Printf("INFO: -fork=1: seed corpus analyzed, %zd seeds chosen, starting to "
483490
"fuzz in separate processes\n", Files.size());
484491

@@ -500,6 +507,31 @@ void FuzzWithFork(const FuzzingOptions &Options,
500507
exit(0);
501508
}
502509

510+
void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
511+
const Vector<std::string> &Corpora, const char *CFPathOrNull) {
512+
if (Corpora.size() < 2) {
513+
Printf("INFO: Merge requires two or more corpus dirs\n");
514+
exit(0);
515+
}
516+
517+
Vector<SizedFile> OldCorpus, NewCorpus;
518+
GetSizedFilesFromDir(Corpora[0], &OldCorpus);
519+
for (size_t i = 1; i < Corpora.size(); i++)
520+
GetSizedFilesFromDir(Corpora[i], &NewCorpus);
521+
std::sort(OldCorpus.begin(), OldCorpus.end());
522+
std::sort(NewCorpus.begin(), NewCorpus.end());
523+
524+
std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath(".txt");
525+
auto Files = CrashResistantMerge(Args, OldCorpus, NewCorpus, CFPath);
526+
for (auto &Path : Files)
527+
F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
528+
// We are done, delete the control file if it was a temporary one.
529+
if (!Flags.merge_control_file)
530+
RemoveFile(CFPath);
531+
532+
exit(0);
533+
}
534+
503535
int AnalyzeDictionary(Fuzzer *F, const Vector<Unit>& Dict,
504536
UnitVector& Corpus) {
505537
Printf("Started dictionary minimization (up to %d tests)\n",
@@ -730,22 +762,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
730762
if (Flags.fork)
731763
FuzzWithFork(Options, Args, *Inputs);
732764

733-
if (Flags.merge) {
734-
if (Inputs->size() < 2) {
735-
Printf("INFO: Merge requires two or more corpus dirs\n");
736-
exit(0);
737-
}
738-
std::string CFPath =
739-
Flags.merge_control_file ? Flags.merge_control_file : TempPath(".txt");
740-
auto Files = CrashResistantMerge(Args, *Inputs, CFPath);
741-
for (auto &Path : Files)
742-
F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
743-
// We are done, delete the control file if it was a temporary one.
744-
if (!Flags.merge_control_file)
745-
RemoveFile(CFPath);
746-
747-
exit(0);
748-
}
765+
if (Flags.merge)
766+
Merge(F, Options, Args, *Inputs, Flags.merge_control_file);
749767

750768
if (Flags.merge_inner) {
751769
const size_t kDefaultMaxMergeLen = 1 << 20;

FuzzerMerge.cpp

+14-18
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {
230230
}
231231

232232
static void WriteNewControlFile(const std::string &CFPath,
233-
const Vector<SizedFile> &AllFiles,
234-
size_t NumFilesInFirstCorpus) {
233+
const Vector<SizedFile> &OldCorpus,
234+
const Vector<SizedFile> &NewCorpus) {
235235
RemoveFile(CFPath);
236236
std::ofstream ControlFile(CFPath);
237-
ControlFile << AllFiles.size() << "\n";
238-
ControlFile << NumFilesInFirstCorpus << "\n";
239-
for (auto &SF: AllFiles)
237+
ControlFile << (OldCorpus.size() + NewCorpus.size()) << "\n";
238+
ControlFile << OldCorpus.size() << "\n";
239+
for (auto &SF: OldCorpus)
240+
ControlFile << SF.File << "\n";
241+
for (auto &SF: NewCorpus)
240242
ControlFile << SF.File << "\n";
241243
if (!ControlFile) {
242244
Printf("MERGE-OUTER: failed to write to the control file: %s\n",
@@ -245,10 +247,11 @@ static void WriteNewControlFile(const std::string &CFPath,
245247
}
246248
}
247249

248-
// Outer process. Does not call the target code and thus sohuld not fail.
250+
// Outer process. Does not call the target code and thus should not fail.
249251
Vector<std::string>
250252
CrashResistantMerge(const Vector<std::string> &Args,
251-
const Vector<std::string> &Corpora,
253+
const Vector<SizedFile> &OldCorpus,
254+
const Vector<SizedFile> &NewCorpus,
252255
const std::string &CFPath) {
253256
size_t NumAttempts = 0;
254257
if (FileSize(CFPath)) {
@@ -277,17 +280,10 @@ CrashResistantMerge(const Vector<std::string> &Args,
277280

278281
if (!NumAttempts) {
279282
// The supplied control file is empty or bad, create a fresh one.
280-
Vector<SizedFile> AllFiles;
281-
GetSizedFilesFromDir(Corpora[0], &AllFiles);
282-
size_t NumFilesInFirstCorpus = AllFiles.size();
283-
std::sort(AllFiles.begin(), AllFiles.end());
284-
for (size_t i = 1; i < Corpora.size(); i++)
285-
GetSizedFilesFromDir(Corpora[i], &AllFiles);
286-
std::sort(AllFiles.begin() + NumFilesInFirstCorpus, AllFiles.end());
287-
Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n",
288-
AllFiles.size(), NumFilesInFirstCorpus);
289-
WriteNewControlFile(CFPath, AllFiles, NumFilesInFirstCorpus);
290-
NumAttempts = AllFiles.size();
283+
NumAttempts = OldCorpus.size() + NewCorpus.size();
284+
Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n", NumAttempts,
285+
OldCorpus.size());
286+
WriteNewControlFile(CFPath, OldCorpus, NewCorpus);
291287
}
292288

293289
// Execute the inner process until it passes.

FuzzerMerge.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ struct Merger {
7171

7272
Vector<std::string>
7373
CrashResistantMerge(const Vector<std::string> &Args,
74-
const Vector<std::string> &Corpora,
74+
const Vector<SizedFile> &OldCorpus,
75+
const Vector<SizedFile> &NewCorpus,
7576
const std::string &CFPath);
7677

7778
} // namespace fuzzer

0 commit comments

Comments
 (0)