llvm/lib/Fuzzer/FuzzerTraceState.cpp
Chandler Carruth e3e43d9d57 Sort the remaining #include lines in include/... and lib/....
I did this a long time ago with a janky python script, but now
clang-format has built-in support for this. I fed clang-format every
line with a #include and let it re-sort things according to the precise
LLVM rules for include ordering baked into clang-format these days.

I've reverted a number of files where the results of sorting includes
isn't healthy. Either places where we have legacy code relying on
particular include ordering (where possible, I'll fix these separately)
or where we have particular formatting around #include lines that
I didn't want to disturb in this patch.

This patch is *entirely* mechanical. If you get merge conflicts or
anything, just ignore the changes in this patch and run clang-format
over your #include lines in the files.

Sorry for any noise here, but it is important to keep these things
stable. I was seeing an increasing number of patches with irrelevant
re-ordering of #include lines because clang-format was used. This patch
at least isolates that churn, makes it easy to skip when resolving
conflicts, and gets us to a clean baseline (again).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304787 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-06 11:49:48 +00:00

182 lines
5.9 KiB
C++

//===- 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);
}
static size_t InternalStrnlen(const char *S, size_t MaxLen) {
size_t Len = 0;
for (; Len < MaxLen && S[Len]; Len++) {}
return Len;
}
// Finds min of (strlen(S1), strlen(S2)).
// Needed bacause one of these strings may actually be non-zero terminated.
static size_t InternalStrnlen2(const char *S1, const char *S2) {
size_t Len = 0;
for (; S1[Len] && S2[Len]; Len++) {}
return Len;
}
} // namespace fuzzer
using fuzzer::TS;
extern "C" {
// We may need to avoid defining weak hooks to stay compatible with older clang.
#ifndef LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
# define LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS 1
#endif
#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
const void *s2, size_t n, int result) {
if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
if (result == 0) return; // No reason to mutate.
if (n <= 1) return; // Not interesting.
fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n, /*StopAtZero*/false);
}
ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
const char *s2, size_t n, int result) {
if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
if (result == 0) return; // No reason to mutate.
size_t Len1 = fuzzer::InternalStrnlen(s1, n);
size_t Len2 = fuzzer::InternalStrnlen(s2, n);
n = std::min(n, Len1);
n = std::min(n, Len2);
if (n <= 1) return; // Not interesting.
fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n, /*StopAtZero*/true);
}
ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
const char *s2, int result) {
if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
if (result == 0) return; // No reason to mutate.
size_t N = fuzzer::InternalStrnlen2(s1, s2);
if (N <= 1) return; // Not interesting.
fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, N, /*StopAtZero*/true);
}
ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
const char *s2, size_t n, int result) {
if (fuzzer::ScopedDoingMyOwnMemOrStr::DoingMyOwnMemOrStr) return;
return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
}
ATTRIBUTE_INTERFACE ATTRIBUTE_NO_SANITIZE_MEMORY
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
const char *s2, int result) {
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;
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);
}
#endif // LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
} // extern "C"