Skip to content

Commit 52f889a

Browse files
committed
[DFSan] Add __dfsan_load_callback.
Summary: When -dfsan-event-callbacks is specified, insert a call to __dfsan_load_callback() on every load. Reviewers: vitalybuka, pcc, kcc Reviewed By: vitalybuka, kcc Subscribers: hiraditya, #sanitizers, llvm-commits, eugenis, kcc Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D75363
1 parent 53f51da commit 52f889a

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

compiler-rt/test/dfsan/event_callbacks.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_dfsan -fno-sanitize=dataflow -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
2-
// RUN: %clang_dfsan -mllvm -dfsan-event-callbacks %s %t-callbacks.o -o %t
1+
// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
2+
// RUN: %clang_dfsan -O2 -mllvm -dfsan-event-callbacks %s %t-callbacks.o -o %t
33
// RUN: %run %t 2>&1 | FileCheck %s
44

55
// Tests that callbacks are inserted for store events when
@@ -35,12 +35,16 @@ void __dfsan_store_callback(dfsan_label Label) {
3535
assert(0);
3636
}
3737

38-
// CHECK: Label 1 stored to memory
39-
// CHECK: Label 2 stored to memory
40-
// CHECK: Label 3 stored to memory
4138
fprintf(stderr, "Label %u stored to memory\n", Label);
4239
}
4340

41+
void __dfsan_load_callback(dfsan_label Label) {
42+
if (!Label)
43+
return;
44+
45+
fprintf(stderr, "Label %u loaded from memory\n", Label);
46+
}
47+
4448
#else
4549
// Compile this code with DFSan and -dfsan-event-callbacks to insert the
4650
// callbacks.
@@ -57,10 +61,25 @@ int main(void) {
5761
dfsan_set_label(LabelJ, &J, sizeof(J));
5862
LabelIJ = dfsan_union(LabelI, LabelJ);
5963

64+
// CHECK: Label 1 stored to memory
6065
volatile int Sink = I;
66+
67+
// CHECK: Label 1 loaded from memory
68+
assert(Sink == 1);
69+
70+
// CHECK: Label 2 stored to memory
6171
Sink = J;
72+
73+
// CHECK: Label 2 loaded from memory
74+
assert(Sink == 2);
75+
76+
// CHECK: Label 2 loaded from memory
77+
// CHECK: Label 3 stored to memory
6278
Sink += I;
6379

80+
// CHECK: Label 3 loaded from memory
81+
assert(Sink == 3);
82+
6483
return 0;
6584
}
6685

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,11 @@ static cl::opt<bool> ClDebugNonzeroLabels(
163163
cl::Hidden);
164164

165165
// Experimental feature that inserts callbacks for certain data events.
166-
// Currently callbacks are only inserted for stores.
166+
// Currently callbacks are only inserted for loads and stores.
167167
//
168168
// If this flag is set to true, the user must provide definitions for the
169169
// following callback functions:
170+
// void __dfsan_load_callback(dfsan_label Label);
170171
// void __dfsan_store_callback(dfsan_label Label);
171172
static cl::opt<bool> ClEventCallbacks(
172173
"dfsan-event-callbacks",
@@ -356,14 +357,15 @@ class DataFlowSanitizer : public ModulePass {
356357
FunctionType *DFSanSetLabelFnTy;
357358
FunctionType *DFSanNonzeroLabelFnTy;
358359
FunctionType *DFSanVarargWrapperFnTy;
359-
FunctionType *DFSanStoreCallbackFnTy;
360+
FunctionType *DFSanLoadStoreCallbackFnTy;
360361
FunctionCallee DFSanUnionFn;
361362
FunctionCallee DFSanCheckedUnionFn;
362363
FunctionCallee DFSanUnionLoadFn;
363364
FunctionCallee DFSanUnimplementedFn;
364365
FunctionCallee DFSanSetLabelFn;
365366
FunctionCallee DFSanNonzeroLabelFn;
366367
FunctionCallee DFSanVarargWrapperFn;
368+
FunctionCallee DFSanLoadCallbackFn;
367369
FunctionCallee DFSanStoreCallbackFn;
368370
MDNode *ColdCallWeights;
369371
DFSanABIList ABIList;
@@ -596,7 +598,7 @@ bool DataFlowSanitizer::doInitialization(Module &M) {
596598
Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
597599
DFSanVarargWrapperFnTy = FunctionType::get(
598600
Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
599-
DFSanStoreCallbackFnTy =
601+
DFSanLoadStoreCallbackFnTy =
600602
FunctionType::get(Type::getVoidTy(*Ctx), ShadowTy, /*isVarArg=*/false);
601603

602604
if (GetArgTLSPtr) {
@@ -798,8 +800,10 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
798800
DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper",
799801
DFSanVarargWrapperFnTy);
800802

803+
DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback",
804+
DFSanLoadStoreCallbackFnTy);
801805
DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback",
802-
DFSanStoreCallbackFnTy);
806+
DFSanLoadStoreCallbackFnTy);
803807

804808
std::vector<Function *> FnsToInstrument;
805809
SmallPtrSet<Function *, 2> FnsWithNativeABI;
@@ -812,6 +816,7 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
812816
&i != DFSanSetLabelFn.getCallee()->stripPointerCasts() &&
813817
&i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() &&
814818
&i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts() &&
819+
&i != DFSanLoadCallbackFn.getCallee()->stripPointerCasts() &&
815820
&i != DFSanStoreCallbackFn.getCallee()->stripPointerCasts())
816821
FnsToInstrument.push_back(&i);
817822
}
@@ -1344,6 +1349,10 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
13441349
DFSF.NonZeroChecks.push_back(Shadow);
13451350

13461351
DFSF.setShadow(&LI, Shadow);
1352+
if (ClEventCallbacks) {
1353+
IRBuilder<> IRB(&LI);
1354+
IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, Shadow);
1355+
}
13471356
}
13481357

13491358
void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, Align Alignment,

0 commit comments

Comments
 (0)