// * The __dfsw_* functions (implemented in this file) record the
// parameters (i.e. the application data and the corresponding taint labels)
// in a global state.
-// * Fuzzer::ApplyTraceBasedMutation() tries to use the data recorded
-// by __dfsw_* hooks to guide the fuzzing towards new application states.
//
// Parts of this code will not function when DFSan is not linked in.
// Instead of using ifdefs and thus requiring a separate build of lib/Fuzzer
class TraceState {
public:
- TraceState(const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
- : Options(Options), CurrentUnit(CurrentUnit) {
+ TraceState(UserSuppliedFuzzer &USF,
+ const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
+ : USF(USF), Options(Options), CurrentUnit(CurrentUnit) {
// Current trace collection is not thread-friendly and it probably
// does not have to be such, but at least we should not crash in presence
// of threads. So, just ignore all traces coming from all threads but one.
if (!Options.UseTraces) return;
RecordingTraces = true;
NumMutations = 0;
+ USF.GetMD().ClearAutoDictionary();
}
- size_t StopTraceRecording(FuzzerRandomBase &Rand) {
+ void StopTraceRecording() {
+ if (!RecordingTraces) return;
RecordingTraces = false;
- return NumMutations;
+ for (size_t i = 0; i < NumMutations; i++) {
+ auto &M = Mutations[i];
+ USF.GetMD().AddWordToAutoDictionary(Unit(M.Data, M.Data + M.Size), M.Pos);
+ }
}
- void ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U);
-
void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {
if (NumMutations >= kMaxMutations) return;
assert(Size <= TraceBasedMutation::kMaxSize);
size_t NumMutations;
TraceBasedMutation Mutations[kMaxMutations];
LabelRange LabelRanges[1 << (sizeof(dfsan_label) * 8)];
+ UserSuppliedFuzzer &USF;
const Fuzzer::FuzzingOptions &Options;
const Unit &CurrentUnit;
static thread_local bool IsMyThread;
return LR = LabelRange::Singleton(LI);
}
-void TraceState::ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U) {
- assert(Idx < NumMutations);
- auto &M = Mutations[Idx];
- if (Options.Verbosity >= 3) {
- Printf("TBM Pos %u Size %u ", M.Pos, M.Size);
- for (uint32_t i = 0; i < M.Size; i++)
- Printf("%02x", M.Data[i]);
- Printf("\n");
- }
- if (M.Pos + M.Size > U->size()) return;
- memcpy(U->data() + M.Pos, &M.Data[0], M.Size);
-}
-
void TraceState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
uint64_t Arg1, uint64_t Arg2, dfsan_label L1,
dfsan_label L2) {
TS->StartTraceRecording();
}
-size_t Fuzzer::StopTraceRecording() {
- if (!TS) return 0;
- return TS->StopTraceRecording(USF.GetRand());
-}
-
-void Fuzzer::ApplyTraceBasedMutation(size_t Idx, Unit *U) {
- assert(TS);
- TS->ApplyTraceBasedMutation(Idx, U);
+void Fuzzer::StopTraceRecording() {
+ if (!TS) return;
+ TS->StopTraceRecording();
}
void Fuzzer::InitializeTraceState() {
if (!Options.UseTraces) return;
- TS = new TraceState(Options, CurrentUnit);
+ TS = new TraceState(USF, Options, CurrentUnit);
CurrentUnit.resize(Options.MaxLen);
// The rest really requires DFSan.
if (!ReallyHaveDFSan()) return;