Skip to content

Commit 94382c8

Browse files
committed
[llvm][StackProtector] Add noreturn to __stack_chk_fail call (#143976)
This is a reland for 99e53cb with the appropriate test fixes. 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 3a6ef8b commit 94382c8

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

llvm/lib/CodeGen/StackProtector.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,8 @@ BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI) {
731731
}
732732

733733
if (StackChkFail) {
734-
cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
735-
B.CreateCall(StackChkFail, Args);
734+
CallInst *Call = B.CreateCall(StackChkFail, Args);
735+
Call->addFnAttr(Attribute::NoReturn);
736736
}
737737

738738
B.CreateUnreachable();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
; REQUIRES: x86-registered-target
4+
; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=lowertypetests,cross-dso-cfi,stack-protector
5+
6+
define hidden void @__stack_chk_fail() !type !1{
7+
unreachable
8+
}
9+
10+
define void @store_captures() sspstrong {
11+
entry:
12+
%a = alloca i32, align 4
13+
%j = alloca ptr, align 8
14+
store ptr %a, ptr %j, align 8
15+
ret void
16+
}
17+
18+
define void @func(ptr %0) {
19+
entry:
20+
%1 = call i1 @llvm.type.test(ptr %0, metadata !"typeid")
21+
br i1 %1, label %cont, label %trap
22+
23+
trap: ; preds = %entry
24+
call void @llvm.trap()
25+
unreachable
26+
27+
cont: ; preds = %entry
28+
call void %0()
29+
ret void
30+
}
31+
32+
!llvm.module.flags = !{!0}
33+
!0 = !{i32 4, !"Cross-DSO CFI", i32 1}
34+
!1 = !{i64 0, !"typeid"}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
;; __stack_chk_fail should have the noreturn attr even if it is an alias
2+
; REQUIRES: x86-registered-target
3+
; RUN: opt -mtriple=x86_64-pc-linux-gnu %s -passes=stack-protector -S | FileCheck %s
4+
5+
define hidden void @__stack_chk_fail_impl() {
6+
unreachable
7+
}
8+
9+
@__stack_chk_fail = hidden alias void (), ptr @__stack_chk_fail_impl
10+
11+
; CHECK-LABEL: @store_captures(
12+
; CHECK: CallStackCheckFailBlk:
13+
; CHECK-NEXT: call void @__stack_chk_fail() [[ATTRS:#.*]]
14+
define void @store_captures() sspstrong {
15+
entry:
16+
%a = alloca i32, align 4
17+
%j = alloca ptr, align 8
18+
store ptr %a, ptr %j, align 8
19+
ret void
20+
}
21+
22+
; CHECK: attributes [[ATTRS]] = { noreturn }

0 commit comments

Comments
 (0)