Skip to content

Commit

Permalink
[DFSan] Add zeroext attribute for callbacks with 8bit shadow variab…
Browse files Browse the repository at this point in the history
…le arguments

Add `zeroext` attribute for below callbacks' first parameter
(8bit shadow variable arguments) to conform to many platforms'
ABI calling convention and some compiler behavior.
- __dfsan_load_callback
- __dfsan_store_callback
- __dfsan_cmp_callback
- __dfsan_conditional_callback
- __dfsan_conditional_callback_origin
- __dfsan_reaches_function_callback
- __dfsan_reaches_function_callback_origin

The type of these callbacks' first parameter is u8 (see the
definition of `dfsan_label`). First, many platforms' ABI
requires unsigned integer data types (except unsigned int)
are zero-extended when stored in general-purpose register.
Second, the problem is that compiler optimization may assume
the arguments are zero-extended and, if not, misbehave, e.g.
it uses an `i8` argument to index into a jump table. If the
argument has non-zero high bits, the output executable may
crash at run-time. So we need to add the `zeroext` attribute
when declaring and calling them.

Reviewed By: browneee, MaskRay

Differential Revision: https://reviews.llvm.org/D140689
  • Loading branch information
SixWeining committed Dec 29, 2022
1 parent 2468b3f commit 14ce567
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 37 deletions.
83 changes: 60 additions & 23 deletions llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Expand Up @@ -1033,13 +1033,15 @@ void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &I,
}
IRBuilder<> IRB(&I);
Value *CondShadow = getShadow(Condition);
CallInst *CI;
if (DFS.shouldTrackOrigins()) {
Value *CondOrigin = getOrigin(Condition);
IRB.CreateCall(DFS.DFSanConditionalCallbackOriginFn,
{CondShadow, CondOrigin});
CI = IRB.CreateCall(DFS.DFSanConditionalCallbackOriginFn,
{CondShadow, CondOrigin});
} else {
IRB.CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
CI = IRB.CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
}
CI->addParamAttr(0, Attribute::ZExt);
}

void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
Expand Down Expand Up @@ -1078,6 +1080,7 @@ void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackFn, args);
}
CB->addParamAttr(0, Attribute::ZExt);
CB->setDebugLoc(dbgloc);
}

Expand Down Expand Up @@ -1413,25 +1416,53 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {

// Initializes event callback functions and declare them in the module
void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback",
DFSanLoadStoreCallbackFnTy);
DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback",
DFSanLoadStoreCallbackFnTy);
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanLoadCallbackFn = Mod->getOrInsertFunction(
"__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
}
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanStoreCallbackFn = Mod->getOrInsertFunction(
"__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
}
DFSanMemTransferCallbackFn = Mod->getOrInsertFunction(
"__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
DFSanCmpCallbackFn =
Mod->getOrInsertFunction("__dfsan_cmp_callback", DFSanCmpCallbackFnTy);

DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
"__dfsan_conditional_callback", DFSanConditionalCallbackFnTy);
DFSanConditionalCallbackOriginFn =
Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
DFSanConditionalCallbackOriginFnTy);
DFSanReachesFunctionCallbackFn = Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback", DFSanReachesFunctionCallbackFnTy);
DFSanReachesFunctionCallbackOriginFn =
Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
DFSanReachesFunctionCallbackOriginFnTy);
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
DFSanCmpCallbackFnTy, AL);
}
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
"__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
}
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanConditionalCallbackOriginFn =
Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
DFSanConditionalCallbackOriginFnTy, AL);
}
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanReachesFunctionCallbackFn =
Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
DFSanReachesFunctionCallbackFnTy, AL);
}
{
AttributeList AL;
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
DFSanReachesFunctionCallbackOriginFn =
Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
DFSanReachesFunctionCallbackOriginFnTy, AL);
}
}

void DataFlowSanitizer::injectMetadataGlobals(Module &M) {
Expand Down Expand Up @@ -2403,7 +2434,9 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
if (ClEventCallbacks) {
IRBuilder<> IRB(Pos);
Value *Addr8 = IRB.CreateBitCast(LI.getPointerOperand(), DFSF.DFS.Int8Ptr);
IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr8});
CallInst *CI =
IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr8});
CI->addParamAttr(0, Attribute::ZExt);
}

IRBuilder<> IRB(AfterLi);
Expand Down Expand Up @@ -2663,7 +2696,9 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) {
if (ClEventCallbacks) {
IRBuilder<> IRB(&SI);
Value *Addr8 = IRB.CreateBitCast(SI.getPointerOperand(), DFSF.DFS.Int8Ptr);
IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr8});
CallInst *CI =
IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr8});
CI->addParamAttr(0, Attribute::ZExt);
}
}

Expand Down Expand Up @@ -2725,7 +2760,9 @@ void DFSanVisitor::visitCmpInst(CmpInst &CI) {
if (ClEventCallbacks) {
IRBuilder<> IRB(&CI);
Value *CombinedShadow = DFSF.getShadow(&CI);
IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
CallInst *CallI =
IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
CallI->addParamAttr(0, Attribute::ZExt);
}
}

Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Instrumentation/DataFlowSanitizer/array.ll
Expand Up @@ -81,7 +81,7 @@ define [1 x i1] @load_array1(ptr %p) {

; EVENT_CALLBACKS: @load_array1.dfsan
; EVENT_CALLBACKS: [[L:%.*]] = or i[[#SBITS]]
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[L]], ptr {{.*}})
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] zeroext [[L]], ptr {{.*}})

; FAST: @load_array1.dfsan
; FAST: [[P:%.*]] = load i[[#SBITS]], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
Expand All @@ -107,7 +107,7 @@ define [2 x i1] @load_array2(ptr %p) {
; EVENT_CALLBACKS: @load_array2.dfsan
; EVENT_CALLBACKS: [[O1:%.*]] = or i[[#SBITS]]
; EVENT_CALLBACKS: [[O2:%.*]] = or i[[#SBITS]] [[O1]]
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[O2]], ptr {{.*}})
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] zeroext [[O2]], ptr {{.*}})

; FAST: @load_array2.dfsan
; FAST: [[P:%.*]] = load i[[#SBITS]], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
Expand All @@ -134,7 +134,7 @@ define [4 x i1] @load_array4(ptr %p) {
; EVENT_CALLBACKS: [[O1:%.*]] = or i[[#mul(4, SBITS)]] [[O0]]
; EVENT_CALLBACKS: [[O2:%.*]] = trunc i[[#mul(4, SBITS)]] [[O1]] to i[[#SBITS]]
; EVENT_CALLBACKS: [[O3:%.*]] = or i[[#SBITS]] [[O2]]
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[O3]], ptr {{.*}})
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] zeroext [[O3]], ptr {{.*}})

; FAST: @load_array4.dfsan
; FAST: [[T:%.*]] = trunc i[[#mul(4, SBITS)]] {{.*}} to i[[#SBITS]]
Expand Down Expand Up @@ -196,7 +196,7 @@ define void @store_zero_array(ptr %p) {
define void @store_array2([2 x i1] %a, ptr %p) {
; EVENT_CALLBACKS: @store_array2.dfsan
; EVENT_CALLBACKS: [[E12:%.*]] = or i[[#SBITS]]
; EVENT_CALLBACKS: call void @__dfsan_store_callback(i[[#SBITS]] [[E12]], ptr %p)
; EVENT_CALLBACKS: call void @__dfsan_store_callback(i[[#SBITS]] zeroext [[E12]], ptr %p)

; FAST: @store_array2.dfsan
; FAST: [[S:%.*]] = load [2 x i[[#SBITS]]], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
Expand Up @@ -30,10 +30,10 @@ define void @store(ptr %p) {
ret void
}

; CHECK: declare void @__dfsan_load_callback(i[[#SBITS]], ptr)
; CHECK: declare void @__dfsan_store_callback(i[[#SBITS]], ptr)
; CHECK: declare void @__dfsan_load_callback(i[[#SBITS]] zeroext, ptr)
; CHECK: declare void @__dfsan_store_callback(i[[#SBITS]] zeroext, ptr)
; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]])
; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]] zeroext)

; CHECK: ; Function Attrs: nounwind memory(read)
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load(ptr, i64)
Expand Down
17 changes: 13 additions & 4 deletions llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
Expand Up @@ -6,7 +6,7 @@ target triple = "x86_64-unknown-linux-gnu"
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]

define i8 @load8(ptr %p) {
; CHECK: call void @__dfsan_load_callback(i[[#SBITS]] %[[LABEL:.*]], ptr %p)
; CHECK: call void @__dfsan_load_callback(i[[#SBITS]] zeroext %[[LABEL:.*]], ptr %p)
; CHECK: %a = load i8, ptr %p
; CHECK: store i[[#SBITS]] %[[LABEL]], ptr @__dfsan_retval_tls

Expand All @@ -16,18 +16,27 @@ define i8 @load8(ptr %p) {

define void @store8(ptr %p, i8 %a) {
; CHECK: store i[[#SBITS]] %[[LABEL:.*]], ptr %{{.*}}
; CHECK: call void @__dfsan_store_callback(i[[#SBITS]] %[[LABEL]], ptr %p)
; CHECK: call void @__dfsan_store_callback(i[[#SBITS]] zeroext %[[LABEL]], ptr %p)
; CHECK: store i8 %a, ptr %p

store i8 %a, ptr %p
ret void
}

define i1 @cmp(i8 %a, i8 %b) {
; CHECK: call void @__dfsan_cmp_callback(i[[#SBITS]] %[[CMPLABEL:.*]])
; CHECK: call void @__dfsan_cmp_callback(i[[#SBITS]] zeroext %[[CMPLABEL:.*]])
; CHECK: %c = icmp ne i8 %a, %b
; CHECK: store i[[#SBITS]] %[[CMPLABEL]], ptr @__dfsan_retval_tls

%c = icmp ne i8 %a, %b
ret i1 %c
}
}

; CHECK: declare void @__dfsan_load_callback(i[[#SBITS]] zeroext, ptr)
; CHECK: declare void @__dfsan_store_callback(i[[#SBITS]] zeroext, ptr)
; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]] zeroext)
; CHECK: declare void @__dfsan_conditional_callback(i[[#SBITS]] zeroext)
; CHECK: declare void @__dfsan_conditional_callback_origin(i[[#SBITS]] zeroext, i32)
; CHECK: declare void @__dfsan_reaches_function_callback(i[[#SBITS]] zeroext, ptr, i32, ptr)
; CHECK: declare void @__dfsan_reaches_function_callback_origin(i[[#SBITS]] zeroext, i32, ptr, i32, ptr)
Expand Up @@ -26,4 +26,4 @@ define void @call() {
ret void
}

; CHECK-LABEL: @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
; CHECK-LABEL: @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
4 changes: 2 additions & 2 deletions llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
Expand Up @@ -133,7 +133,7 @@ define {i1, i1} @load_struct(ptr %p) {
; EVENT_CALLBACKS: [[OL0:%.*]] = or i[[#SBITS]]
; EVENT_CALLBACKS: [[OL1:%.*]] = or i[[#SBITS]] [[OL0]],
; EVENT_CALLBACKS: [[S0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] [[OL1]], 0
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] [[OL1]]
; EVENT_CALLBACKS: call void @__dfsan_load_callback(i[[#SBITS]] zeroext [[OL1]]

%s = load {i1, i1}, ptr %p
ret {i1, i1} %s
Expand All @@ -152,7 +152,7 @@ define void @store_struct(ptr %p, {i1, i1} %s) {

; EVENT_CALLBACKS: @store_struct.dfsan
; EVENT_CALLBACKS: [[OL:%.*]] = or i[[#SBITS]]
; EVENT_CALLBACKS: call void @__dfsan_store_callback(i[[#SBITS]] [[OL]]
; EVENT_CALLBACKS: call void @__dfsan_store_callback(i[[#SBITS]] zeroext [[OL]]

; COMBINE_STORE_PTR: @store_struct.dfsan
; COMBINE_STORE_PTR: [[PL:%.*]] = load i[[#SBITS]], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
Expand Down

0 comments on commit 14ce567

Please sign in to comment.