FUZZER_FLAG_INT(use_traces, 0, "Experimental: use instruction traces")
FUZZER_FLAG_INT(use_memcmp, 1,
"Use hints from intercepting memcmp, strcmp, etc")
+FUZZER_FLAG_INT(use_memmem, 1,
+ "Use hints from intercepting memmem, strstr, etc")
FUZZER_FLAG_INT(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
" this number of jobs in separate worker processes"
" with stdout/stderr redirected to fuzz-JOB.log.")
#include <cstring>
#include <thread>
#include <map>
+#include <set>
#if !LLVM_FUZZER_SUPPORTS_DFSAN
// Stubs for dfsan for platforms where dfsan does not exist and weak
// Declared as static globals for faster checks inside the hooks.
static bool RecordingTraces = false;
static bool RecordingMemcmp = false;
+static bool RecordingMemmem = false;
class TraceState {
public:
return;
RecordingTraces = Options.UseTraces;
RecordingMemcmp = Options.UseMemcmp;
+ RecordingMemmem = Options.UseMemmem;
NumMutations = 0;
+ InterestingWords.clear();
MD.ClearAutoDictionary();
}
}
}
}
- MD.AddWordToAutoDictionary(M.W, M.Pos);
+ MD.AddWordToAutoDictionary({M.W, M.Pos});
}
+ for (auto &W : InterestingWords)
+ MD.AddWordToAutoDictionary({W});
}
void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {
AddMutation(Pos, Size, reinterpret_cast<uint8_t*>(&Data));
}
+ 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);
+ }
+
void EnsureDfsanLabels(size_t Size) {
for (; LastDfsanLabel < Size; LastDfsanLabel++) {
dfsan_label L = dfsan_create_label("input", (void *)(LastDfsanLabel + 1));
static const size_t kMaxMutations = 1 << 16;
size_t NumMutations;
TraceBasedMutation Mutations[kMaxMutations];
+ // TODO: std::set is too inefficient, need to have a custom DS here.
+ std::set<Word> InterestingWords;
LabelRange LabelRanges[1 << (sizeof(dfsan_label) * 8)];
size_t LastDfsanLabel = 0;
MutationDispatcher &MD;
reinterpret_cast<const uint8_t *>(s2));
}
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result) {
+ return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
+}
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+ const char *s2, int result) {
+ return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
+}
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+ const char *s2, char *result) {
+ TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
+}
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+ const char *s2, char *result) {
+ TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
+}
+void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
+ const void *s2, size_t len2, void *result) {
+ // TODO: can't hook memmem since memmem is used by libFuzzer.
+}
+
#endif // LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
__attribute__((visibility("default")))