summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Fuzzer/CMakeLists.txt1
-rw-r--r--llvm/lib/Fuzzer/FuzzerInternal.h10
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp4
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp6
-rw-r--r--llvm/lib/Fuzzer/FuzzerTracePC.cpp23
-rw-r--r--llvm/lib/Fuzzer/FuzzerTracePC.h23
-rw-r--r--llvm/lib/Fuzzer/FuzzerTraceState.cpp112
-rw-r--r--llvm/lib/Fuzzer/FuzzerUtil.cpp7
-rw-r--r--llvm/lib/Fuzzer/FuzzerUtil.h2
-rw-r--r--llvm/lib/Fuzzer/test/fuzzer-traces-hooks.test2
10 files changed, 61 insertions, 129 deletions
diff --git a/llvm/lib/Fuzzer/CMakeLists.txt b/llvm/lib/Fuzzer/CMakeLists.txt
index fa743c280e8..bc744890b99 100644
--- a/llvm/lib/Fuzzer/CMakeLists.txt
+++ b/llvm/lib/Fuzzer/CMakeLists.txt
@@ -46,7 +46,6 @@ if ( LLVM_USE_SANITIZE_COVERAGE OR CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux" )
FuzzerShmemPosix.cpp
FuzzerShmemWindows.cpp
FuzzerTracePC.cpp
- FuzzerTraceState.cpp
FuzzerUtil.cpp
FuzzerUtilDarwin.cpp
FuzzerUtilLinux.cpp
diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h
index a732f895375..549ebc0a3c3 100644
--- a/llvm/lib/Fuzzer/FuzzerInternal.h
+++ b/llvm/lib/Fuzzer/FuzzerInternal.h
@@ -38,7 +38,6 @@ public:
void Loop();
void MinimizeCrashLoop(const Unit &U);
void ShuffleAndMinimize(UnitVector *V);
- void InitializeTraceState();
void RereadOutputCorpus(size_t MaxSize);
size_t secondsSinceProcessStartUp() {
@@ -104,15 +103,6 @@ private:
void ShuffleCorpus(UnitVector *V);
void CheckExitOnSrcPosOrItem();
- // Trace-based fuzzing: we run a unit with some kind of tracing
- // enabled and record potentially useful mutations. Then
- // We apply these mutations one by one to the unit and run it again.
-
- // Start tracing; forget all previously proposed mutations.
- void StartTraceRecording();
- // Stop tracing.
- void StopTraceRecording();
-
static void StaticDeathCallback();
void DumpCurrentUnit(const char *Prefix);
void DeathCallback();
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index 6816f3af8a6..1693cd078a9 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -114,7 +114,6 @@ Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
: CB(CB), Corpus(Corpus), MD(MD), Options(Options) {
if (EF->__sanitizer_set_death_callback)
EF->__sanitizer_set_death_callback(StaticDeathCallback);
- InitializeTraceState();
assert(!F);
F = this;
TPC.ResetMaps();
@@ -600,13 +599,10 @@ void Fuzzer::MutateAndTestOne() {
assert(NewSize > 0 && "Mutator returned empty unit");
assert(NewSize <= CurrentMaxMutationLen && "Mutator return overisized unit");
Size = NewSize;
- if (i == 0)
- StartTraceRecording();
II.NumExecutedMutations++;
if (RunOne(CurrentUnitData, Size, /*MayDeleteFile=*/true, &II))
ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});
- StopTraceRecording();
TryDetectingAMemoryLeak(CurrentUnitData, Size,
/*DuringInitialCorpusExecution*/ false);
}
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index 53cb9027e45..bc2cf2c1bdb 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -251,7 +251,7 @@ size_t MutationDispatcher::Mutate_AddWordFromTORC(
uint8_t *Data, size_t Size, size_t MaxSize) {
Word W;
DictionaryEntry DE;
- switch (Rand(3)) {
+ switch (Rand(4)) {
case 0: {
auto X = TPC.TORC8.Get(Rand.Rand());
DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
@@ -267,6 +267,10 @@ size_t MutationDispatcher::Mutate_AddWordFromTORC(
auto X = TPC.TORCW.Get(Rand.Rand());
DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
} break;
+ case 3: if (Options.UseMemmem) {
+ auto X = TPC.MMT.Get(Rand.Rand());
+ DE = DictionaryEntry(X);
+ } break;
default:
assert(0);
}
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
index 909227ea7e0..ced0a213334 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
@@ -37,6 +37,8 @@ namespace fuzzer {
TracePC TPC;
+int ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr;
+
uint8_t *TracePC::Counters() const {
return __sancov_trace_pc_guard_8bit_counters;
}
@@ -475,4 +477,25 @@ void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
}
+
+ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+ const char *s2, char *result) {
+ if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
+ fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
+}
+
+ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+ const char *s2, char *result) {
+ if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
+ fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
+}
+
+ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
+void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
+ const void *s2, size_t len2, void *result) {
+ if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
+ fuzzer::TPC.MMT.Add(reinterpret_cast<const uint8_t *>(s2), len2);
+}
} // extern "C"
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.h b/llvm/lib/Fuzzer/FuzzerTracePC.h
index 5ec8c590b4d..b36c4f54306 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.h
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.h
@@ -45,6 +45,28 @@ struct TableOfRecentCompares {
Pair Table[kSize];
};
+template <size_t kSizeT>
+struct MemMemTable {
+ static const size_t kSize = kSizeT;
+ Word MemMemWords[kSize];
+ Word EmptyWord;
+
+ void Add(const uint8_t *Data, size_t Size) {
+ if (Size <= 2) return;
+ Size = std::min(Size, Word::GetMaxSize());
+ size_t Idx = SimpleFastHash(Data, Size) % kSize;
+ MemMemWords[Idx].Set(Data, Size);
+ }
+ const Word &Get(size_t Idx) {
+ for (size_t i = 0; i < kSize; i++) {
+ const Word &W = MemMemWords[(Idx + i) % kSize];
+ if (W.size()) return W;
+ }
+ EmptyWord.Set(nullptr, 0);
+ return EmptyWord;
+ }
+};
+
class TracePC {
public:
static const size_t kNumPCs = 1 << 21;
@@ -81,6 +103,7 @@ class TracePC {
TableOfRecentCompares<uint32_t, 32> TORC4;
TableOfRecentCompares<uint64_t, 32> TORC8;
TableOfRecentCompares<Word, 32> TORCW;
+ MemMemTable<1024> MMT;
void PrintNewPCs();
void InitializePrintNewPCs();
diff --git a/llvm/lib/Fuzzer/FuzzerTraceState.cpp b/llvm/lib/Fuzzer/FuzzerTraceState.cpp
deleted file mode 100644
index 101ab485c4e..00000000000
--- a/llvm/lib/Fuzzer/FuzzerTraceState.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- FuzzerTraceState.cpp - Trace-based fuzzer mutator ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Data tracing.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerDictionary.h"
-#include "FuzzerIO.h"
-#include "FuzzerInternal.h"
-#include "FuzzerMutate.h"
-#include "FuzzerTracePC.h"
-#include <algorithm>
-#include <cstring>
-#include <map>
-#include <set>
-#include <thread>
-
-namespace fuzzer {
-
-// Declared as static globals for faster checks inside the hooks.
-static bool RecordingMemmem = false;
-
-int ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr;
-
-class TraceState {
-public:
- TraceState(MutationDispatcher &MD, const FuzzingOptions &Options,
- const Fuzzer *F)
- : MD(MD), Options(Options), F(F) {}
-
- void StartTraceRecording() {
- if (!Options.UseMemmem)
- return;
- RecordingMemmem = true;
- InterestingWords.clear();
- MD.ClearAutoDictionary();
- }
-
- void StopTraceRecording() {
- if (!RecordingMemmem)
- return;
- for (auto &W : InterestingWords)
- MD.AddWordToAutoDictionary({W});
- }
-
- void AddInterestingWord(const uint8_t *Data, size_t Size) {
- if (!RecordingMemmem || !F->InFuzzingThread()) return;
- if (Size <= 1) return;
- Size = std::min(Size, Word::GetMaxSize());
- Word W(Data, Size);
- InterestingWords.insert(W);
- }
-
- private:
-
- // TODO: std::set is too inefficient, need to have a custom DS here.
- std::set<Word> InterestingWords;
- MutationDispatcher &MD;
- const FuzzingOptions Options;
- const Fuzzer *F;
-};
-
-static TraceState *TS;
-
-void Fuzzer::StartTraceRecording() {
- if (!TS) return;
- TS->StartTraceRecording();
-}
-
-void Fuzzer::StopTraceRecording() {
- if (!TS) return;
- TS->StopTraceRecording();
-}
-
-void Fuzzer::InitializeTraceState() {
- if (!Options.UseMemmem) return;
- TS = new TraceState(MD, Options, this);
-}
-
-} // namespace fuzzer
-
-using fuzzer::TS;
-
-extern "C" {
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
- const char *s2, char *result) {
- if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
- TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
- const char *s2, char *result) {
- if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
- TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
-}
-
-ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
-void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
- const void *s2, size_t len2, void *result) {
- if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
- TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), len2);
-}
-
-} // extern "C"
diff --git a/llvm/lib/Fuzzer/FuzzerUtil.cpp b/llvm/lib/Fuzzer/FuzzerUtil.cpp
index f5fd3a85187..2d95f40e46a 100644
--- a/llvm/lib/Fuzzer/FuzzerUtil.cpp
+++ b/llvm/lib/Fuzzer/FuzzerUtil.cpp
@@ -215,4 +215,11 @@ bool ExecuteCommandAndReadOutput(const std::string &Command, std::string *Out) {
return true;
}
+size_t SimpleFastHash(const uint8_t *Data, size_t Size) {
+ size_t Res = 0;
+ for (size_t i = 0; i < Size; i++)
+ Res = Res * 11 + Data[i];
+ return Res;
+}
+
} // namespace fuzzer
diff --git a/llvm/lib/Fuzzer/FuzzerUtil.h b/llvm/lib/Fuzzer/FuzzerUtil.h
index f84fd9ef0fc..c9fb1c12e08 100644
--- a/llvm/lib/Fuzzer/FuzzerUtil.h
+++ b/llvm/lib/Fuzzer/FuzzerUtil.h
@@ -71,6 +71,8 @@ std::string DisassembleCmd(const std::string &FileName);
std::string SearchRegexCmd(const std::string &Regex);
+size_t SimpleFastHash(const uint8_t *Data, size_t Size);
+
} // namespace fuzzer
#endif // LLVM_FUZZER_UTIL_H
diff --git a/llvm/lib/Fuzzer/test/fuzzer-traces-hooks.test b/llvm/lib/Fuzzer/test/fuzzer-traces-hooks.test
index f93a8b7199e..77ca4b47bd0 100644
--- a/llvm/lib/Fuzzer/test/fuzzer-traces-hooks.test
+++ b/llvm/lib/Fuzzer/test/fuzzer-traces-hooks.test
@@ -10,7 +10,7 @@ RUN: not LLVMFuzzer-StrstrTest -seed=1 -runs=2000000 2>&1 | File
RUN: not LLVMFuzzer-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
-RUN: LLVMFuzzer-RepeatedMemcmp -seed=11 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RUN: LLVMFuzzer-RepeatedMemcmp -seed=11 -runs=100000 -max_len=20 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
RECOMMENDED_DICT:###### Recommended dictionary. ######
RECOMMENDED_DICT-DAG: "foo"
RECOMMENDED_DICT-DAG: "bar"
OpenPOWER on IntegriCloud