[PATCH] D49675: [cfi-verify] Detect more protected calls using cross-DSO.

Joel Galenson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 23 09:39:53 PDT 2018


jgalenson created this revision.
jgalenson added reviewers: pcc, vlad.tsyrklevich.
Herald added a reviewer: javed.absar.
Herald added subscribers: llvm-commits, kristof.beyls.

When using cross-DSO, some indirect calls are not guarded by a branch to a trap but instead follow a call to __cfi_slowpath.  For example:

      

if (!InlinedFastCheck(f)) {

  call *f

} else {

  __cfi_slowpath(CallSiteTypeId, f);
  call *f

}

      

In this case, the second call to f is not marked as protected by the current code.  We thus recognize if an indirect call directly follows a call to a trap function and treat them as protected.

      

We also ignore indirect calls in the PLT, since on AArch64 each entry contains an indirect call that should not be protected by CFI.


Repository:
  rL LLVM

https://reviews.llvm.org/D49675

Files:
  test/tools/llvm-cfi-verify/X86/Inputs/function-only-check.o
  test/tools/llvm-cfi-verify/X86/function_only_check.s
  tools/llvm-cfi-verify/lib/FileAnalysis.cpp
  tools/llvm-cfi-verify/lib/GraphBuilder.cpp


Index: tools/llvm-cfi-verify/lib/GraphBuilder.cpp
===================================================================
--- tools/llvm-cfi-verify/lib/GraphBuilder.cpp
+++ tools/llvm-cfi-verify/lib/GraphBuilder.cpp
@@ -311,6 +311,24 @@
     Result.ConditionalBranchNodes.push_back(BranchNode);
   }
 
+  // When using cross-DSO, some indirect calls are not guarded by a branch to a
+  // trap but instead follow a call to __cfi_slowpath.  For example:
+  // if (!InlinedFastCheck(f))
+  //    call *f
+  //  else {
+  //    __cfi_slowpath(CallSiteTypeId, f);
+  //    call *f
+  //  }
+  // To mark the second call as protected, we recognize indirect calls that
+  // directly follow calls to the trap function.
+  if (CFCrossRefs.empty()) {
+    const Instr *PrevInstr = Analysis.getPrevInstructionSequential(ChildMeta);
+    if (PrevInstr && Analysis.isTrapCall(*PrevInstr)) {
+      Result.IntermediateNodes[PrevInstr->VMAddress] = Address;
+      HasValidCrossRef = true;
+    }
+  }
+
   if (!HasValidCrossRef)
     Result.OrphanedNodes.push_back(Address);
 
Index: tools/llvm-cfi-verify/lib/FileAnalysis.cpp
===================================================================
--- tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -452,6 +452,11 @@
     if (!(object::ELFSectionRef(Section).getFlags() & ELF::SHF_EXECINSTR))
       continue;
 
+    // Avoid checking the PLT since it produces spurious failures on AArch64.
+    StringRef SectionName;
+    if (!Section.getName(SectionName) && SectionName == ".plt")
+      continue;
+
     StringRef SectionContents;
     if (Section.getContents(SectionContents))
       return make_error<StringError>("Failed to retrieve section contents",
Index: test/tools/llvm-cfi-verify/X86/function_only_check.s
===================================================================
--- /dev/null
+++ test/tools/llvm-cfi-verify/X86/function_only_check.s
@@ -0,0 +1,8 @@
+# RUN: llvm-cfi-verify -trap-function=__cfi_slowpath at plt %S/Inputs/function-only-check.o | FileCheck %s
+
+# CHECK-LABEL: {{^Instruction: .* \(PROTECTED\)}}
+
+# CHECK: Expected Protected: 1 (100.00%)
+# CHECK: Unexpected Protected: 0 (0.00%)
+# CHECK: Expected Unprotected: 0 (0.00%)
+# CHECK: Unexpected Unprotected (BAD): 0 (0.00%)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49675.156807.patch
Type: text/x-patch
Size: 2287 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180723/409d08c7/attachment.bin>


More information about the llvm-commits mailing list