Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit c438ef3

Browse files
committed
[libFuzzer] add -features_dir= flag to dump unique input features on disk
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@358317 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8fa4694 commit c438ef3

File tree

10 files changed

+60
-6
lines changed

10 files changed

+60
-6
lines changed

lib/fuzzer/FuzzerCorpus.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ class InputCorpus {
8585

8686
bool empty() const { return Inputs.empty(); }
8787
const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; }
88-
void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile,
89-
bool HasFocusFunction, const Vector<uint32_t> &FeatureSet,
90-
const DataFlowTrace &DFT, const InputInfo *BaseII) {
88+
InputInfo *AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile,
89+
bool HasFocusFunction,
90+
const Vector<uint32_t> &FeatureSet,
91+
const DataFlowTrace &DFT, const InputInfo *BaseII) {
9192
assert(!U.empty());
9293
if (FeatureDebug)
9394
Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures);
@@ -113,6 +114,7 @@ class InputCorpus {
113114
UpdateCorpusDistribution();
114115
PrintCorpus();
115116
// ValidateFeatureSet();
117+
return &II;
116118
}
117119

118120
// Debug-only

lib/fuzzer/FuzzerDriver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
659659
Options.FocusFunction = Flags.focus_function;
660660
if (Flags.data_flow_trace)
661661
Options.DataFlowTrace = Flags.data_flow_trace;
662+
if (Flags.features_dir)
663+
Options.FeaturesDir = Flags.features_dir;
662664
Options.LazyCounters = Flags.lazy_counters;
663665

664666
unsigned Seed = Flags.seed;

lib/fuzzer/FuzzerFlags.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ FUZZER_FLAG_INT(cleanse_crash, 0, "If 1, tries to cleanse the provided"
6767
" Use with -exact_artifact_path to specify the output."
6868
)
6969
FUZZER_FLAG_INT(minimize_crash_internal_step, 0, "internal flag")
70+
FUZZER_FLAG_STRING(features_dir, "internal flag. Used to dump feature sets on disk."
71+
"Every time a new input is added to the corpus, a corresponding file in the features_dir"
72+
" is created containing the unique features of that input."
73+
" Features are stored in binary format.")
7074
FUZZER_FLAG_INT(use_counters, 1, "Use coverage counters")
7175
FUZZER_FLAG_INT(use_memmem, 1,
7276
"Use hints from intercepting memmem, strstr, etc")

lib/fuzzer/FuzzerIO.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,14 @@ void CopyFileToErr(const std::string &Path) {
6161
}
6262

6363
void WriteToFile(const Unit &U, const std::string &Path) {
64+
WriteToFile(U.data(), U.size(), Path);
65+
}
66+
67+
void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
6468
// Use raw C interface because this function may be called from a sig handler.
6569
FILE *Out = fopen(Path.c_str(), "wb");
6670
if (!Out) return;
67-
fwrite(U.data(), sizeof(U[0]), U.size(), Out);
71+
fwrite(Data, sizeof(Data[0]), Size, Out);
6872
fclose(Out);
6973
}
7074

lib/fuzzer/FuzzerIO.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ std::string FileToString(const std::string &Path);
2424

2525
void CopyFileToErr(const std::string &Path);
2626

27+
void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path);
2728
void WriteToFile(const Unit &U, const std::string &Path);
2829

2930
void ReadDirToVectorOfUnits(const char *Path, Vector<Unit> *V,
@@ -89,6 +90,7 @@ int CloseFile(int Fd);
8990
int DuplicateFile(int Fd);
9091

9192
void RemoveFile(const std::string &Path);
93+
void RenameFile(const std::string &OldPath, const std::string &NewPath);
9294

9395
void DiscardOutput(int Fd);
9496

lib/fuzzer/FuzzerIOPosix.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ void RemoveFile(const std::string &Path) {
120120
unlink(Path.c_str());
121121
}
122122

123+
void RenameFile(const std::string &OldPath, const std::string &NewPath) {
124+
rename(OldPath.c_str(), NewPath.c_str());
125+
}
126+
123127
void DiscardOutput(int Fd) {
124128
FILE* Temp = fopen("/dev/null", "w");
125129
if (!Temp)

lib/fuzzer/FuzzerIOWindows.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ void RemoveFile(const std::string &Path) {
219219
_unlink(Path.c_str());
220220
}
221221

222+
void RenameFile(const std::string &OldPath, const std::string &NewPath) {
223+
rename(OldPath.c_str(), NewPath.c_str());
224+
}
225+
222226
void DiscardOutput(int Fd) {
223227
FILE* Temp = fopen("nul", "w");
224228
if (!Temp)

lib/fuzzer/FuzzerLoop.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,24 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
445445
}
446446
}
447447

448+
static void WriteFeatureSetToFile(const std::string &FeaturesDir,
449+
const uint8_t Sha1[],
450+
const Vector<uint32_t> &FeatureSet) {
451+
if (FeaturesDir.empty() || FeatureSet.empty()) return;
452+
WriteToFile(reinterpret_cast<const uint8_t *>(FeatureSet.data()),
453+
FeatureSet.size() * sizeof(FeatureSet[0]),
454+
DirPlusFile(FeaturesDir, Sha1ToString(Sha1)));
455+
Printf("Features: %s\n", Sha1ToString(Sha1).c_str());
456+
}
457+
458+
static void RenameFeatureSetFile(const std::string &FeaturesDir,
459+
const std::string &OldFile,
460+
const std::string &NewFile) {
461+
if (FeaturesDir.empty()) return;
462+
RenameFile(DirPlusFile(FeaturesDir, OldFile),
463+
DirPlusFile(FeaturesDir, NewFile));
464+
}
465+
448466
bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
449467
InputInfo *II, bool *FoundUniqFeatures) {
450468
if (!Size)
@@ -469,15 +487,21 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
469487
size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
470488
if (NumNewFeatures) {
471489
TPC.UpdateObservedPCs();
472-
Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile,
473-
TPC.ObservedFocusFunction(), UniqFeatureSetTmp, DFT, II);
490+
auto NewII = Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures,
491+
MayDeleteFile, TPC.ObservedFocusFunction(),
492+
UniqFeatureSetTmp, DFT, II);
493+
WriteFeatureSetToFile(Options.FeaturesDir, NewII->Sha1,
494+
NewII->UniqFeatureSet);
474495
return true;
475496
}
476497
if (II && FoundUniqFeaturesOfII &&
477498
II->DataFlowTraceForFocusFunction.empty() &&
478499
FoundUniqFeaturesOfII == II->UniqFeatureSet.size() &&
479500
II->U.size() > Size) {
501+
auto OldFeaturesFile = Sha1ToString(II->Sha1);
480502
Corpus.Replace(II, {Data, Data + Size});
503+
RenameFeatureSetFile(Options.FeaturesDir, OldFeaturesFile,
504+
Sha1ToString(II->Sha1));
481505
return true;
482506
}
483507
return false;

lib/fuzzer/FuzzerOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct FuzzingOptions {
5151
std::string ExitOnItem;
5252
std::string FocusFunction;
5353
std::string DataFlowTrace;
54+
std::string FeaturesDir;
5455
bool SaveArtifacts = true;
5556
bool PrintNEW = true; // Print a status line when new units are found;
5657
bool PrintNewCovPcs = false;

test/fuzzer/features_dir.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Tests -features_dir=F
2+
# REQUIRES: linux
3+
RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
4+
RUN: rm -rf %t-C %t-F
5+
RUN: mkdir %t-C %t-F
6+
RUN: not %run %t-SimpleTest %t-C -features_dir=%t-F
7+
RUN: for c in %t-C/*; do f=%t-F/$(basename $c); echo looking for $f; [ -a $f ]; done

0 commit comments

Comments
 (0)