[PATCH] D141556: Disable check noreturn call in stack protector

Xiang Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 11 17:20:08 PST 2023


xiangzhangllvm created this revision.
xiangzhangllvm added a reviewer: smeenai.
Herald added a subscriber: hiraditya.
Herald added a project: All.
xiangzhangllvm requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

**Background**
We enhance the stack protector at D139254 <https://reviews.llvm.org/D139254> 
>From then, tack protector will check the stack before return and call no-return function.
(Before, we only check before return, this give attack space in our user's code, and uses
hope we can fix it.)
In D139254 <https://reviews.llvm.org/D139254> smeenai hope to use a option come back
to the previous action (only check for return) by consider the code size in their project. So I
implemented this patch.
To encourage users to use strict stack protect (both check for return and no-return call), I only
implement the option as a LLVM option first. If we have more requirements as smeenai do. We
will consider add a standard FE option.


https://reviews.llvm.org/D141556

Files:
  llvm/lib/CodeGen/StackProtector.cpp
  llvm/test/CodeGen/X86/stack-protector-no-return.ll


Index: llvm/test/CodeGen/X86/stack-protector-no-return.ll
===================================================================
--- llvm/test/CodeGen/X86/stack-protector-no-return.ll
+++ llvm/test/CodeGen/X86/stack-protector-no-return.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -o - -verify-dom-info | FileCheck %s
+; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -disable-check-noreturn-call=true -o - -verify-dom-info | FileCheck --check-prefix=DISNOTET %s
 
 ; Function Attrs: sspreq
 define void @_Z7catchesv() #0 personality i8* null {
@@ -39,6 +40,39 @@
 ; CHECK-NEXT:  .LBB0_6: # %CallStackCheckFailBlk
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __stack_chk_fail at PLT
+;
+; DISNOTET-LABEL: _Z7catchesv:
+; DISNOTET:       # %bb.0: # %entry
+; DISNOTET-NEXT:    pushq %rax
+; DISNOTET-NEXT:    .cfi_def_cfa_offset 16
+; DISNOTET-NEXT:    movq %fs:40, %rax
+; DISNOTET-NEXT:    movq %rax, (%rsp)
+; DISNOTET-NEXT:  .Ltmp0:
+; DISNOTET-NEXT:    xorl %eax, %eax
+; DISNOTET-NEXT:    xorl %edi, %edi
+; DISNOTET-NEXT:    xorl %esi, %esi
+; DISNOTET-NEXT:    xorl %edx, %edx
+; DISNOTET-NEXT:    callq *%rax
+; DISNOTET-NEXT:  .Ltmp1:
+; DISNOTET-NEXT:  # %bb.1: # %invoke.cont
+; DISNOTET-NEXT:  .Ltmp2:
+; DISNOTET-NEXT:    xorl %eax, %eax
+; DISNOTET-NEXT:    xorl %edi, %edi
+; DISNOTET-NEXT:    callq *%rax
+; DISNOTET-NEXT:  .Ltmp3:
+; DISNOTET-NEXT:  # %bb.2: # %invoke.cont2
+; DISNOTET-NEXT:  .LBB0_3: # %lpad1
+; DISNOTET-NEXT:  .Ltmp4:
+; DISNOTET-NEXT:    movq %fs:40, %rax
+; DISNOTET-NEXT:    cmpq (%rsp), %rax
+; DISNOTET-NEXT:    jne .LBB0_5
+; DISNOTET-NEXT:  # %bb.4: # %SP_return
+; DISNOTET-NEXT:    popq %rax
+; DISNOTET-NEXT:    .cfi_def_cfa_offset 8
+; DISNOTET-NEXT:    retq
+; DISNOTET-NEXT:  .LBB0_5: # %CallStackCheckFailBlk
+; DISNOTET-NEXT:    .cfi_def_cfa_offset 16
+; DISNOTET-NEXT:    callq __stack_chk_fail at PLT
 entry:
   %call = invoke i64 null(i32 0, i8* null, i64 0)
           to label %invoke.cont unwind label %lpad1
Index: llvm/lib/CodeGen/StackProtector.cpp
===================================================================
--- llvm/lib/CodeGen/StackProtector.cpp
+++ llvm/lib/CodeGen/StackProtector.cpp
@@ -60,6 +60,8 @@
 
 static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",
                                           cl::init(true), cl::Hidden);
+static cl::opt<bool> DisableCheckNoReturn("disable-check-noreturn-call",
+                                          cl::init(false), cl::Hidden);
 
 char StackProtector::ID = 0;
 
@@ -453,7 +455,7 @@
     if (&BB == FailBB)
       continue;
     Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
-    if (!CheckLoc) {
+    if (!CheckLoc && !DisableCheckNoReturn) {
       for (auto &Inst : BB) {
         auto *CB = dyn_cast<CallBase>(&Inst);
         if (!CB)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D141556.488428.patch
Type: text/x-patch
Size: 2910 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230112/17c46bae/attachment.bin>


More information about the llvm-commits mailing list