Skip to content

Commit 99e53cb

Browse files
authored
[llvm][StackProtector] Add noreturn to __stack_chk_fail call (#143976)
It's possible for __stack_chk_fail to be an alias when using CrossDSOCFI since it will make a jump table entry for this function and replace it with an alias. StackProtector can crash since it always expects this to be a regular function. Instead add the noreturn attribute to the call.
1 parent 6e12442 commit 99e53cb

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

llvm/lib/CodeGen/StackProtector.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,8 @@ BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
725725
StackChkFail =
726726
M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
727727
}
728-
cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
729-
B.CreateCall(StackChkFail, Args);
728+
CallInst *Call = B.CreateCall(StackChkFail, Args);
729+
Call->addFnAttr(Attribute::NoReturn);
730730
B.CreateUnreachable();
731731
return FailBB;
732732
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
;; This is a minimal reproducer that caused StackProtector to crash with a bad cast when
2+
;; CrossDSOCFI is used. This test just needs to not crash.
3+
; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=lowertypetests,cross-dso-cfi,stack-protector
4+
5+
define hidden void @__stack_chk_fail() !type !1{
6+
unreachable
7+
}
8+
9+
define void @store_captures() sspstrong {
10+
entry:
11+
%a = alloca i32, align 4
12+
%j = alloca ptr, align 8
13+
store ptr %a, ptr %j, align 8
14+
ret void
15+
}
16+
17+
define void @func(ptr %0) {
18+
entry:
19+
%1 = call i1 @llvm.type.test(ptr %0, metadata !"typeid")
20+
br i1 %1, label %cont, label %trap
21+
22+
trap: ; preds = %entry
23+
call void @llvm.trap()
24+
unreachable
25+
26+
cont: ; preds = %entry
27+
call void %0()
28+
ret void
29+
}
30+
31+
!llvm.module.flags = !{!0}
32+
!0 = !{i32 4, !"Cross-DSO CFI", i32 1}
33+
!1 = !{i64 0, !"typeid"}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
;; __stack_chk_fail should have the noreturn attr even if it is an alias
2+
; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=stack-protector -S | FileCheck %s
3+
4+
define hidden void @__stack_chk_fail_impl() {
5+
unreachable
6+
}
7+
8+
@__stack_chk_fail = hidden alias void (), ptr @__stack_chk_fail_impl
9+
10+
; CHECK-LABEL: @store_captures(
11+
; CHECK: CallStackCheckFailBlk:
12+
; CHECK-NEXT: call void @__stack_chk_fail() [[ATTRS:#.*]]
13+
define void @store_captures() sspstrong {
14+
entry:
15+
%a = alloca i32, align 4
16+
%j = alloca ptr, align 8
17+
store ptr %a, ptr %j, align 8
18+
ret void
19+
}
20+
21+
; CHECK: attributes [[ATTRS]] = { noreturn }

0 commit comments

Comments
 (0)