Skip to content

Commit 2252625

Browse files
committed
[lib/Fuzzer] rename FuzzerDFSan.cpp to FuzzerTraceState.cpp; update comments. NFC expected
llvm-svn: 237050
1 parent d7b3ef6 commit 2252625

File tree

4 files changed

+54
-44
lines changed

4 files changed

+54
-44
lines changed

llvm/lib/Fuzzer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "${LIBFUZZER_FLAGS_BASE} -O2 -fno-sanitize=all")
44
if( LLVM_USE_SANITIZE_COVERAGE )
55
add_library(LLVMFuzzerNoMain OBJECT
66
FuzzerCrossOver.cpp
7-
FuzzerDFSan.cpp
7+
FuzzerTraceState.cpp
88
FuzzerDriver.cpp
99
FuzzerIO.cpp
1010
FuzzerLoop.cpp

llvm/lib/Fuzzer/FuzzerInternal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Fuzzer {
6767
void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
6868
void Loop(size_t NumIterations);
6969
void ShuffleAndMinimize();
70-
void InitializeDFSan();
70+
void InitializeTraceState();
7171
size_t CorpusSize() const { return Corpus.size(); }
7272
void ReadDir(const std::string &Path, long *Epoch) {
7373
ReadDirToVectorOfUnits(Path.c_str(), &Corpus, Epoch);

llvm/lib/Fuzzer/FuzzerLoop.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static Fuzzer *F;
2222
Fuzzer::Fuzzer(UserCallback Callback, FuzzingOptions Options)
2323
: Callback(Callback), Options(Options) {
2424
SetDeathCallback();
25-
InitializeDFSan();
25+
InitializeTraceState();
2626
assert(!F);
2727
F = this;
2828
}
Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
1-
//===- FuzzerDFSan.cpp - DFSan-based fuzzer mutator -----------------------===//
1+
//===- FuzzerTraceState.cpp - Trace-based fuzzer mutator ------------------===//
22
//
33
// The LLVM Compiler Infrastructure
44
//
55
// This file is distributed under the University of Illinois Open Source
66
// License. See LICENSE.TXT for details.
77
//
88
//===----------------------------------------------------------------------===//
9+
// This file implements a mutation algorithm based on instruction traces and
10+
// on taint analysis feedback from DFSan.
11+
//
12+
// Instruction traces are special hooks inserted by the compiler around
13+
// interesting instructions. Currently supported traces:
14+
// * __sanitizer_cov_trace_cmp -- inserted before every ICMP instruction,
15+
// receives the type, size and arguments of ICMP.
16+
//
17+
// Every time a traced event is intercepted we analyse the data involved
18+
// in the event and suggest a mutation for future executions.
19+
// For example if 4 bytes of data that derive from input bytes {4,5,6,7}
20+
// are compared with a constant 12345,
21+
// we try to insert 12345, 12344, 12346 into bytes
22+
// {4,5,6,7} of the next fuzzed inputs.
23+
//
24+
// The fuzzer can work only with the traces, or with both traces and DFSan.
25+
//
926
// DataFlowSanitizer (DFSan) is a tool for
1027
// generalised dynamic data flow (taint) analysis:
1128
// http://clang.llvm.org/docs/DataFlowSanitizer.html .
1229
//
13-
// This file implements a mutation algorithm based on taint
14-
// analysis feedback from DFSan.
15-
//
16-
// The approach has some similarity to "Taint-based Directed Whitebox Fuzzing"
30+
// The approach with DFSan-based fuzzing has some similarity to
31+
// "Taint-based Directed Whitebox Fuzzing"
1732
// by Vijay Ganesh & Tim Leek & Martin Rinard:
1833
// http://dspace.mit.edu/openaccess-disseminate/1721.1/59320,
1934
// but it uses a full blown LLVM IR taint analysis and separate instrumentation
2035
// to analyze all of the "attack points" at once.
2136
//
22-
// Workflow:
37+
// Workflow with DFSan:
2338
// * lib/Fuzzer/Fuzzer*.cpp is compiled w/o any instrumentation.
24-
// * The code under test is compiled with DFSan *and* with special extra hooks
25-
// that are inserted before dfsan. Currently supported hooks:
26-
// - __sanitizer_cov_trace_cmp: inserted before every ICMP instruction,
27-
// receives the type, size and arguments of ICMP.
39+
// * The code under test is compiled with DFSan *and* with instruction traces.
2840
// * Every call to HOOK(a,b) is replaced by DFSan with
2941
// __dfsw_HOOK(a, b, label(a), label(b)) so that __dfsw_HOOK
3042
// gets all the taint labels for the arguments.
@@ -34,14 +46,10 @@
3446
// * The __dfsw_* functions (implemented in this file) record the
3547
// parameters (i.e. the application data and the corresponding taint labels)
3648
// in a global state.
37-
// * Fuzzer::MutateWithDFSan() tries to use the data recorded by __dfsw_*
38-
// hooks to guide the fuzzing towards new application states.
39-
// For example if 4 bytes of data that derive from input bytes {4,5,6,7}
40-
// are compared with a constant 12345 and the comparison always yields
41-
// the same result, we try to insert 12345, 12344, 12346 into bytes
42-
// {4,5,6,7} of the next fuzzed inputs.
49+
// * Fuzzer::ApplyTraceBasedMutation() tries to use the data recorded
50+
// by __dfsw_* hooks to guide the fuzzing towards new application states.
4351
//
44-
// This code does not function when DFSan is not linked in.
52+
// Parts of this code will not function when DFSan is not linked in.
4553
// Instead of using ifdefs and thus requiring a separate build of lib/Fuzzer
4654
// we redeclare the dfsan_* interface functions as weak and check if they
4755
// are nullptr before calling.
@@ -53,7 +61,7 @@
5361
// like test/dfsan/DFSanSimpleCmpTest.cpp.
5462
//===----------------------------------------------------------------------===//
5563

56-
/* Example of manual usage:
64+
/* Example of manual usage (-fsanitize=dataflow is optional):
5765
(
5866
cd $LLVM/lib/Fuzzer/
5967
clang -fPIC -c -g -O2 -std=c++11 Fuzzer*.cpp
@@ -168,9 +176,9 @@ struct TraceBasedMutation {
168176
uint64_t Data;
169177
};
170178

171-
class DFSanState {
179+
class TraceState {
172180
public:
173-
DFSanState(const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
181+
TraceState(const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
174182
: Options(Options), CurrentUnit(CurrentUnit) {}
175183

176184
LabelRange GetLabelRange(dfsan_label L);
@@ -208,7 +216,7 @@ class DFSanState {
208216
const Unit &CurrentUnit;
209217
};
210218

211-
LabelRange DFSanState::GetLabelRange(dfsan_label L) {
219+
LabelRange TraceState::GetLabelRange(dfsan_label L) {
212220
LabelRange &LR = LabelRanges[L];
213221
if (LR.Beg < LR.End || L == 0)
214222
return LR;
@@ -218,7 +226,7 @@ LabelRange DFSanState::GetLabelRange(dfsan_label L) {
218226
return LR = LabelRange::Singleton(LI);
219227
}
220228

221-
void DFSanState::ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U) {
229+
void TraceState::ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U) {
222230
assert(Idx < Mutations.size());
223231
auto &M = Mutations[Idx];
224232
if (Options.Verbosity >= 3)
@@ -227,7 +235,7 @@ void DFSanState::ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U) {
227235
memcpy(U->data() + M.Pos, &M.Data, M.Size);
228236
}
229237

230-
void DFSanState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
238+
void TraceState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
231239
uint64_t Arg1, uint64_t Arg2, dfsan_label L1,
232240
dfsan_label L2) {
233241
assert(ReallyHaveDFSan());
@@ -263,7 +271,7 @@ void DFSanState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
263271
<< "\n";
264272
}
265273

266-
int DFSanState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
274+
int TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
267275
size_t DataSize) {
268276
int Res = 0;
269277
const uint8_t *Beg = CurrentUnit.data();
@@ -284,7 +292,7 @@ int DFSanState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
284292
return Res;
285293
}
286294

287-
void DFSanState::TraceCmpCallback(size_t CmpSize, size_t CmpType, uint64_t Arg1,
295+
void TraceState::TraceCmpCallback(size_t CmpSize, size_t CmpType, uint64_t Arg1,
288296
uint64_t Arg2) {
289297
if (!Options.UseTraces) return;
290298
int Added = 0;
@@ -298,29 +306,29 @@ void DFSanState::TraceCmpCallback(size_t CmpSize, size_t CmpType, uint64_t Arg1,
298306
}
299307
}
300308

301-
static DFSanState *DFSan;
309+
static TraceState *TS;
302310

303311
void Fuzzer::StartTraceRecording() {
304-
if (!DFSan) return;
305-
DFSan->StartTraceRecording();
312+
if (!TS) return;
313+
TS->StartTraceRecording();
306314
}
307315

308316
size_t Fuzzer::StopTraceRecording() {
309-
if (!DFSan) return 0;
310-
return DFSan->StopTraceRecording();
317+
if (!TS) return 0;
318+
return TS->StopTraceRecording();
311319
}
312320

313321
void Fuzzer::ApplyTraceBasedMutation(size_t Idx, Unit *U) {
314-
assert(DFSan);
315-
DFSan->ApplyTraceBasedMutation(Idx, U);
322+
assert(TS);
323+
TS->ApplyTraceBasedMutation(Idx, U);
316324
}
317325

318-
void Fuzzer::InitializeDFSan() {
319-
if (!Options.UseDFSan) return;
320-
DFSan = new DFSanState(Options, CurrentUnit);
326+
void Fuzzer::InitializeTraceState() {
327+
if (!Options.UseTraces && !Options.UseDFSan) return;
328+
TS = new TraceState(Options, CurrentUnit);
321329
CurrentUnit.resize(Options.MaxLen);
322330
// The rest really requires DFSan.
323-
if (!ReallyHaveDFSan()) return;
331+
if (!ReallyHaveDFSan() || !Options.UseDFSan) return;
324332
for (size_t i = 0; i < static_cast<size_t>(Options.MaxLen); i++) {
325333
dfsan_label L = dfsan_create_label("input", (void*)(i + 1));
326334
// We assume that no one else has called dfsan_create_label before.
@@ -331,38 +339,40 @@ void Fuzzer::InitializeDFSan() {
331339

332340
} // namespace fuzzer
333341

334-
using fuzzer::DFSan;
342+
using fuzzer::TS;
335343

336344
extern "C" {
337345
void __dfsw___sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
338346
uint64_t Arg2, dfsan_label L0,
339347
dfsan_label L1, dfsan_label L2) {
348+
assert(TS);
340349
assert(L0 == 0);
341350
uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
342351
uint64_t CmpSize = (SizeAndType >> 32) / 8;
343352
uint64_t Type = (SizeAndType << 32) >> 32;
344-
DFSan->DFSanCmpCallback(PC, CmpSize, Type, Arg1, Arg2, L1, L2);
353+
TS->DFSanCmpCallback(PC, CmpSize, Type, Arg1, Arg2, L1, L2);
345354
}
346355

347356
void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,
348357
size_t n, dfsan_label s1_label,
349358
dfsan_label s2_label, dfsan_label n_label) {
359+
assert(TS);
350360
uintptr_t PC = reinterpret_cast<uintptr_t>(caller_pc);
351361
uint64_t S1 = 0, S2 = 0;
352362
// Simplification: handle only first 8 bytes.
353363
memcpy(&S1, s1, std::min(n, sizeof(S1)));
354364
memcpy(&S2, s2, std::min(n, sizeof(S2)));
355365
dfsan_label L1 = dfsan_read_label(s1, n);
356366
dfsan_label L2 = dfsan_read_label(s2, n);
357-
DFSan->DFSanCmpCallback(PC, n, fuzzer::ICMP_EQ, S1, S2, L1, L2);
367+
TS->DFSanCmpCallback(PC, n, fuzzer::ICMP_EQ, S1, S2, L1, L2);
358368
}
359369

360370
void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
361371
uint64_t Arg2) {
362-
if (!DFSan) return;
372+
if (!TS) return;
363373
uint64_t CmpSize = (SizeAndType >> 32) / 8;
364374
uint64_t Type = (SizeAndType << 32) >> 32;
365-
DFSan->TraceCmpCallback(CmpSize, Type, Arg1, Arg2);
375+
TS->TraceCmpCallback(CmpSize, Type, Arg1, Arg2);
366376
}
367377

368378
} // extern "C"

0 commit comments

Comments
 (0)