[llvm] r257736 - [libFuzzer] suggest a dictionary to the user of some of the trace-based dictionary entries were successful
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 13 18:36:45 PST 2016
Author: kcc
Date: Wed Jan 13 20:36:44 2016
New Revision: 257736
URL: http://llvm.org/viewvc/llvm-project?rev=257736&view=rev
Log:
[libFuzzer] suggest a dictionary to the user of some of the trace-based dictionary entries were successful
Added:
llvm/trunk/lib/Fuzzer/test/RepeatedMemcmp.cpp
Modified:
llvm/trunk/lib/Fuzzer/FuzzerInterface.h
llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
llvm/trunk/lib/Fuzzer/test/MemcmpTest.cpp
llvm/trunk/lib/Fuzzer/test/fuzzer-dfsan.test
llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test
Modified: llvm/trunk/lib/Fuzzer/FuzzerInterface.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInterface.h?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInterface.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInterface.h Wed Jan 13 20:36:44 2016
@@ -76,6 +76,8 @@ class MutationDispatcher {
void StartMutationSequence();
/// Print the current sequence of mutations.
void PrintMutationSequence();
+ /// Indicate that the current sequence of mutations was successfull.
+ void RecordSuccessfulMutationSequence();
/// Mutates data by shuffling bytes.
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by erasing a byte.
@@ -91,9 +93,13 @@ class MutationDispatcher {
size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
size_t MaxSize);
- /// Mutates data by adding a word from the automatic dictionary.
- size_t Mutate_AddWordFromAutoDictionary(uint8_t *Data, size_t Size,
- size_t MaxSize);
+ /// Mutates data by adding a word from the temporary automatic dictionary.
+ size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size,
+ size_t MaxSize);
+
+ /// Mutates data by adding a word from the persistent automatic dictionary.
+ size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
+ size_t MaxSize);
/// Tries to find an ASCII integer in Data, changes it to another ASCII int.
size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
@@ -113,6 +119,7 @@ class MutationDispatcher {
void AddWordToAutoDictionary(const Unit &Word, size_t PositionHint);
void ClearAutoDictionary();
+ void PrintRecommendedDictionary();
void SetCorpus(const std::vector<Unit> *Corpus);
@@ -157,8 +164,6 @@ class UserSuppliedFuzzer {
UserSuppliedFuzzer(FuzzerRandomBase *Rand);
/// Executes the target function on 'Size' bytes of 'Data'.
virtual int TargetFunction(const uint8_t *Data, size_t Size) = 0;
- virtual void StartMutationSequence() { MD.StartMutationSequence(); }
- virtual void PrintMutationSequence() { MD.PrintMutationSequence(); }
virtual void SetCorpus(const std::vector<Unit> *Corpus) {
MD.SetCorpus(Corpus);
}
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Jan 13 20:36:44 2016
@@ -340,7 +340,7 @@ void Fuzzer::PrintStatusForNewUnit(const
PrintStats("NEW ", "");
if (Options.Verbosity) {
Printf(" L: %zd ", U.size());
- USF.PrintMutationSequence();
+ USF.GetMD().PrintMutationSequence();
Printf("\n");
}
}
@@ -348,6 +348,7 @@ void Fuzzer::PrintStatusForNewUnit(const
void Fuzzer::ReportNewCoverage(const Unit &U) {
Corpus.push_back(U);
UnitHashesAddedToCorpus.insert(Hash(U));
+ USF.GetMD().RecordSuccessfulMutationSequence();
PrintStatusForNewUnit(U);
WriteToOutputCorpus(U);
if (Options.ExitOnFirst)
@@ -387,7 +388,7 @@ void Fuzzer::Merge(const std::vector<std
}
void Fuzzer::MutateAndTestOne() {
- USF.StartMutationSequence();
+ USF.GetMD().StartMutationSequence();
auto U = ChooseUnitToMutate();
@@ -496,6 +497,7 @@ void Fuzzer::Loop() {
}
PrintStats("DONE ", "\n");
+ USF.GetMD().PrintRecommendedDictionary();
}
void Fuzzer::SyncCorpus() {
Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Wed Jan 13 20:36:44 2016
@@ -27,12 +27,28 @@ struct DictionaryEntry {
size_t PositionHint;
};
+struct Dictionary : public std::vector<DictionaryEntry>{
+ bool ContainsWord(const Unit &W) const {
+ return end() !=
+ std::find_if(begin(), end(), [&](const DictionaryEntry &DE) {
+ return DE.Word == W;
+ });
+ }
+};
+
struct MutationDispatcher::Impl {
- std::vector<DictionaryEntry> ManualDictionary;
- std::vector<DictionaryEntry> AutoDictionary;
+ // Dictionary provided by the user via -dict=DICT_FILE.
+ Dictionary ManualDictionary;
+ // Temporary dictionary modified by the fuzzer itself,
+ // recreated periodically.
+ Dictionary TempAutoDictionary;
+ // Persistent dictionary modified by the fuzzer, consists of
+ // entries that led to successfull discoveries in the past mutations.
+ Dictionary PersistentAutoDictionary;
+
std::vector<Mutator> Mutators;
std::vector<Mutator> CurrentMutatorSequence;
- std::vector<DictionaryEntry> CurrentDictionaryEntrySequence;
+ Dictionary CurrentDictionaryEntrySequence;
const std::vector<Unit> *Corpus = nullptr;
FuzzerRandomBase &Rand;
@@ -47,8 +63,10 @@ struct MutationDispatcher::Impl {
Add({&MutationDispatcher::Mutate_CrossOver, "CrossOver"});
Add({&MutationDispatcher::Mutate_AddWordFromManualDictionary,
"AddFromManualDict"});
- Add({&MutationDispatcher::Mutate_AddWordFromAutoDictionary,
- "AddFromAutoDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
+ "AddFromTempAutoDict"});
+ Add({&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
+ "AddFromPersAutoDict"});
}
void SetCorpus(const std::vector<Unit> *Corpus) { this->Corpus = Corpus; }
size_t AddWordFromDictionary(const std::vector<DictionaryEntry> &D,
@@ -126,10 +144,15 @@ size_t MutationDispatcher::Mutate_AddWor
MaxSize);
}
-size_t MutationDispatcher::Mutate_AddWordFromAutoDictionary(uint8_t *Data,
- size_t Size,
- size_t MaxSize) {
- return MDImpl->AddWordFromDictionary(MDImpl->AutoDictionary, Data, Size,
+size_t MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary(
+ uint8_t *Data, size_t Size, size_t MaxSize) {
+ return MDImpl->AddWordFromDictionary(MDImpl->TempAutoDictionary, Data, Size,
+ MaxSize);
+}
+
+size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
+ uint8_t *Data, size_t Size, size_t MaxSize) {
+ return MDImpl->AddWordFromDictionary(MDImpl->PersistentAutoDictionary, Data, Size,
MaxSize);
}
@@ -211,13 +234,36 @@ void MutationDispatcher::StartMutationSe
MDImpl->CurrentDictionaryEntrySequence.clear();
}
+// Copy successful dictionary entries to PersistentAutoDictionary.
+void MutationDispatcher::RecordSuccessfulMutationSequence() {
+ for (auto &DE : MDImpl->CurrentDictionaryEntrySequence)
+ // Linear search is fine here as this happens seldom.
+ if (!MDImpl->PersistentAutoDictionary.ContainsWord(DE.Word))
+ MDImpl->PersistentAutoDictionary.push_back(
+ {DE.Word, std::numeric_limits<size_t>::max()});
+}
+
+void MutationDispatcher::PrintRecommendedDictionary() {
+ std::vector<Unit> V;
+ for (auto &DE : MDImpl->PersistentAutoDictionary)
+ if (!MDImpl->ManualDictionary.ContainsWord(DE.Word))
+ V.push_back(DE.Word);
+ if (V.empty()) return;
+ Printf("###### Recommended dictionary. ######\n");
+ for (auto &U: V) {
+ Printf("\"");
+ PrintASCII(U, "\"\n");
+ }
+ Printf("###### End of recommended dictionary. ######\n");
+}
+
void MutationDispatcher::PrintMutationSequence() {
Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size());
for (auto M : MDImpl->CurrentMutatorSequence)
Printf("%s-", M.Name);
if (!MDImpl->CurrentDictionaryEntrySequence.empty()) {
Printf(" DE: ");
- for (auto DE : MDImpl->CurrentDictionaryEntrySequence) {
+ for (auto &DE : MDImpl->CurrentDictionaryEntrySequence) {
Printf("\"");
PrintASCII(DE.Word, "\"-");
}
@@ -261,12 +307,12 @@ void MutationDispatcher::AddWordToManual
void MutationDispatcher::AddWordToAutoDictionary(const Unit &Word,
size_t PositionHint) {
static const size_t kMaxAutoDictSize = 1 << 14;
- if (MDImpl->AutoDictionary.size() >= kMaxAutoDictSize) return;
- MDImpl->AutoDictionary.push_back({Word, PositionHint});
+ if (MDImpl->TempAutoDictionary.size() >= kMaxAutoDictSize) return;
+ MDImpl->TempAutoDictionary.push_back({Word, PositionHint});
}
void MutationDispatcher::ClearAutoDictionary() {
- MDImpl->AutoDictionary.clear();
+ MDImpl->TempAutoDictionary.clear();
}
MutationDispatcher::MutationDispatcher(FuzzerRandomBase &Rand) : Rand(Rand) {
Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Wed Jan 13 20:36:44 2016
@@ -20,6 +20,7 @@ set(Tests
FullCoverageSetTest
MemcmpTest
NullDerefTest
+ RepeatedMemcmp
SimpleCmpTest
SimpleDictionaryTest
SimpleHashTest
Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Wed Jan 13 20:36:44 2016
@@ -302,7 +302,7 @@ void TestAddWordFromDictionaryWithHint(M
TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {
TestAddWordFromDictionaryWithHint(
- &MutationDispatcher::Mutate_AddWordFromAutoDictionary, 1 << 5);
+ &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5);
}
TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {
Modified: llvm/trunk/lib/Fuzzer/test/MemcmpTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/MemcmpTest.cpp?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/MemcmpTest.cpp (original)
+++ llvm/trunk/lib/Fuzzer/test/MemcmpTest.cpp Wed Jan 13 20:36:44 2016
@@ -9,7 +9,7 @@ extern "C" int LLVMFuzzerTestOneInput(co
if (Size >= 8 && memcmp(Data, "01234567", 8) == 0) {
if (Size >= 12 && memcmp(Data + 8, "ABCD", 4) == 0) {
if (Size >= 14 && memcmp(Data + 12, "XY", 2) == 0) {
- if (Size >= 16 && memcmp(Data + 14, "KLM", 3) == 0) {
+ if (Size >= 17 && memcmp(Data + 14, "KLM", 3) == 0) {
if (Size >= 27 && memcmp(Data + 17, "ABCDE-GHIJ", 10) == 0){
fprintf(stderr, "BINGO %zd\n", Size);
for (size_t i = 0; i < Size; i++) {
Added: llvm/trunk/lib/Fuzzer/test/RepeatedMemcmp.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/RepeatedMemcmp.cpp?rev=257736&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/RepeatedMemcmp.cpp (added)
+++ llvm/trunk/lib/Fuzzer/test/RepeatedMemcmp.cpp Wed Jan 13 20:36:44 2016
@@ -0,0 +1,19 @@
+
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ int Matches = 0;
+ for (size_t i = 0; i + 2 < Size; i += 3) {
+ const char *Pat = i % 2 ? "foo" : "bar";
+ if (!memcmp(Data + i, Pat, 3))
+ Matches++;
+ }
+ if (Matches > 20) {
+ fprintf(stderr, "BINGO!\n");
+ exit(1);
+ }
+ return 0;
+}
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer-dfsan.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-dfsan.test?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-dfsan.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-dfsan.test Wed Jan 13 20:36:44 2016
@@ -10,7 +10,7 @@ CHECK_DFSanMemcmpCallback: DFSanMemcmpCa
RUN: not LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=1000000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK1
RUN: LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=100 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanCmpCallback
-RUN: not LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: not LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=100000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK2
RUN: LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanMemcmpCallback
RUN: not LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK3
Modified: llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test?rev=257736&r1=257735&r2=257736&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test Wed Jan 13 20:36:44 2016
@@ -18,3 +18,10 @@ RUN: LLVMFuzzer-SwitchTest
RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=10000000 2>&1 | FileCheck %s
RUN: LLVMFuzzer-SimpleHashTest -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=Done10000000
+
+RUN: LLVMFuzzer-RepeatedMemcmp -use_traces=1 -seed=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RECOMMENDED_DICT:###### Recommended dictionary. ######
+RECOMMENDED_DICT-DAG: "foo"
+RECOMMENDED_DICT-DAG: "bar"
+RECOMMENDED_DICT:###### End of recommended dictionary. ######
+
More information about the llvm-commits
mailing list