Skip to content

Commit 8907144

Browse files
committed
[llvm][StackProtector] Add noreturn to __stack_chk_fail aliassee
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. I think it should be safe to continue treating this as an alias since we only call into it, and we can apply the noreturn attr to the underlying function if it is an alias.
1 parent 4e765b7 commit 8907144

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)