[llvm] 772851c - [HWASan] Disable stack, globals and force callbacks for x86_64.

Matt Morehouse via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 22 08:02:39 PDT 2021


Author: Matt Morehouse
Date: 2021-03-22T08:02:27-07:00
New Revision: 772851ca4e509982c333d9724b6f8d4456df42af

URL: https://github.com/llvm/llvm-project/commit/772851ca4e509982c333d9724b6f8d4456df42af
DIFF: https://github.com/llvm/llvm-project/commit/772851ca4e509982c333d9724b6f8d4456df42af.diff

LOG: [HWASan] Disable stack, globals and force callbacks for x86_64.

Subsequent patches will implement page-aliasing mode for x86_64, which
will initially only work for the primary heap allocator.  We force
callback instrumentation to simplify the initial aliasing
implementation.

Reviewed By: vitalybuka, eugenis

Differential Revision: https://reviews.llvm.org/D98069

Added: 
    

Modified: 
    compiler-rt/test/hwasan/TestCases/deep-recursion.c
    compiler-rt/test/hwasan/TestCases/global.c
    compiler-rt/test/hwasan/TestCases/longjmp.c
    compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
    compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp
    compiler-rt/test/hwasan/TestCases/rich-stack.c
    compiler-rt/test/hwasan/TestCases/stack-history-length.c
    compiler-rt/test/hwasan/TestCases/stack-oob.c
    compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c
    compiler-rt/test/hwasan/TestCases/stack-uar-realign.c
    compiler-rt/test/hwasan/TestCases/stack-uar.c
    compiler-rt/test/hwasan/TestCases/use-after-free.c
    llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
    llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll
    llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll
    llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll

Removed: 
    


################################################################################
diff  --git a/compiler-rt/test/hwasan/TestCases/deep-recursion.c b/compiler-rt/test/hwasan/TestCases/deep-recursion.c
index 2fe77a7bdaaf..081becabdbfd 100644
--- a/compiler-rt/test/hwasan/TestCases/deep-recursion.c
+++ b/compiler-rt/test/hwasan/TestCases/deep-recursion.c
@@ -7,6 +7,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdlib.h>
 // At least -O1 is needed for this function to not have a stack frame on
 // AArch64.

diff  --git a/compiler-rt/test/hwasan/TestCases/global.c b/compiler-rt/test/hwasan/TestCases/global.c
index 7b6bbad3b191..5a1dcb47ad3a 100644
--- a/compiler-rt/test/hwasan/TestCases/global.c
+++ b/compiler-rt/test/hwasan/TestCases/global.c
@@ -5,6 +5,9 @@
 // RUN: not %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LSYM %s
 // RUN: not %env_hwasan_opts=symbolize=0 %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LNOSYM %s
 
+// Global aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 int x = 1;
 
 int main(int argc, char **argv) {

diff  --git a/compiler-rt/test/hwasan/TestCases/longjmp.c b/compiler-rt/test/hwasan/TestCases/longjmp.c
index 8d847b54b275..2e3431ca6abe 100644
--- a/compiler-rt/test/hwasan/TestCases/longjmp.c
+++ b/compiler-rt/test/hwasan/TestCases/longjmp.c
@@ -3,6 +3,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdlib.h>
 #include <assert.h>
 #include <sanitizer/hwasan_interface.h>

diff  --git a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
index 9c4ca4fa3efe..4466ca2e4f02 100644
--- a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
+++ b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
@@ -5,6 +5,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>

diff  --git a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp
index 8fff9876a642..5b218e11c7ad 100644
--- a/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp
+++ b/compiler-rt/test/hwasan/TestCases/register-dump-no-fp.cpp
@@ -16,7 +16,7 @@
 __attribute__((noinline)) void f(int *p) { *p = 3; }
 
 // CHECK: ERROR: HWAddressSanitizer:
-// CHECK: #0 {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]]
+// CHECK: #{{[0-9]}} {{.*}} in f(int*) {{.*}}register-dump-no-fp.cpp:[[@LINE-3]]
 
 int main() {
   __hwasan_enable_allocator_tagging();
@@ -24,5 +24,5 @@ int main() {
   int *volatile a = new int;
   a = (int *)__hwasan_tag_pointer(a, 0);
   f(a);
-  // CHECK: #1 {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]]
+  // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}register-dump-no-fp.cpp:[[@LINE-1]]
 }

diff  --git a/compiler-rt/test/hwasan/TestCases/rich-stack.c b/compiler-rt/test/hwasan/TestCases/rich-stack.c
index 6787d57769f4..ce04709f0cc9 100644
--- a/compiler-rt/test/hwasan/TestCases/rich-stack.c
+++ b/compiler-rt/test/hwasan/TestCases/rich-stack.c
@@ -2,6 +2,10 @@
 // RUN: %clang_hwasan %s -o %t
 // RUN: not %run %t 3 2 -1 2>&1 | FileCheck %s --check-prefix=R321
 // REQUIRES: stable-runtime
+
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdint.h>
 #include <stdlib.h>
 void USE(void *x) { // pretend_to_do_something(void *x)

diff  --git a/compiler-rt/test/hwasan/TestCases/stack-history-length.c b/compiler-rt/test/hwasan/TestCases/stack-history-length.c
index 584046ee6cea..14a085e509ef 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-history-length.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-history-length.c
@@ -4,6 +4,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdlib.h>
 
 void USE(void *x) { // pretend_to_do_something(void *x)

diff  --git a/compiler-rt/test/hwasan/TestCases/stack-oob.c b/compiler-rt/test/hwasan/TestCases/stack-oob.c
index 8c8c11055492..46cf8c0e919d 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-oob.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-oob.c
@@ -9,6 +9,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 #include <stdlib.h>
 #include <sanitizer/hwasan_interface.h>
 

diff  --git a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c
index 4fb8a9006045..ae453f66c4c4 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c
@@ -4,6 +4,9 @@
 // still be using FP-relative debug info locations that we can use to find stack
 // objects.
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 __attribute((noinline))
 char *buggy(int b) {
   char c[64];

diff  --git a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c
index fdd95651f957..fa602404d256 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-uar-realign.c
@@ -6,6 +6,9 @@
 // be able to handle this case somehow (e.g. by using a 
diff erent register for
 // DW_AT_frame_base) but at least we shouldn't get confused by it.
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 __attribute((noinline))
 char *buggy() {
   _Alignas(64) char c[64];

diff  --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c
index 9a7e357f1b26..d251995d2e85 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-uar.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c
@@ -4,6 +4,9 @@
 
 // REQUIRES: stable-runtime
 
+// Stack aliasing is not implemented on x86.
+// XFAIL: x86_64
+
 void USE(void *x) { // pretend_to_do_something(void *x)
   __asm__ __volatile__("" : : "r" (x) : "memory");
 }

diff  --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c
index 2b2562d60122..8d47acf4d5c3 100644
--- a/compiler-rt/test/hwasan/TestCases/use-after-free.c
+++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c
@@ -23,7 +23,7 @@ int main() {
   int r = 0;
   if (ISREAD) r = x[5]; else x[5] = 42;  // should be on the same line.
   // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem)
-  // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]]
+  // CHECK: #{{[0-9]}} {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]]
   // Offset is 5 or 11 depending on left/right alignment.
   // CHECK: is a small unallocated heap chunk; size: 32 offset: {{5|11}}
   // CHECK: is located 5 bytes inside of 10-byte region
@@ -37,6 +37,6 @@ int main() {
   // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]]
   // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
   // CHECK: =>{{.*}}[[MEM_TAG]]
-  // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main
+  // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch
   return r;
 }

diff  --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 27715ff86ff2..1c368e7cd139 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -267,7 +267,7 @@ class HWAddressSanitizer {
     bool InGlobal;
     bool InTls;
 
-    void init(Triple &TargetTriple);
+    void init(Triple &TargetTriple, bool InstrumentWithCalls);
     unsigned getObjectAlignment() const { return 1U << Scale; }
   };
   ShadowMapping Mapping;
@@ -284,6 +284,9 @@ class HWAddressSanitizer {
   bool OutlinedChecks;
   bool UseShortGranules;
   bool InstrumentLandingPads;
+  bool InstrumentWithCalls;
+  bool InstrumentStack;
+  bool UsePageAliases;
 
   bool HasMatchAllTag = false;
   uint8_t MatchAllTag = 0;
@@ -479,7 +482,13 @@ void HWAddressSanitizer::initializeModule() {
 
   TargetTriple = Triple(M.getTargetTriple());
 
-  Mapping.init(TargetTriple);
+  // x86_64 uses userspace pointer aliases, currently heap-only with callback
+  // instrumentation only.
+  UsePageAliases = TargetTriple.getArch() == Triple::x86_64;
+  InstrumentWithCalls = UsePageAliases ? true : ClInstrumentWithCalls;
+  InstrumentStack = UsePageAliases ? false : ClInstrumentStack;
+
+  Mapping.init(TargetTriple, InstrumentWithCalls);
 
   C = &(M.getContext());
   IRBuilder<> IRB(*C);
@@ -521,7 +530,7 @@ void HWAddressSanitizer::initializeModule() {
     createHwasanCtorComdat();
     bool InstrumentGlobals =
         ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime;
-    if (InstrumentGlobals)
+    if (InstrumentGlobals && !UsePageAliases)
       instrumentGlobals();
 
     bool InstrumentPersonalityFunctions =
@@ -721,6 +730,7 @@ Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
 void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
                                                    unsigned AccessSizeIndex,
                                                    Instruction *InsertBefore) {
+  assert(!UsePageAliases);
   const int64_t AccessInfo =
       (CompileKernel << HWASanAccessInfo::CompileKernelShift) +
       (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) +
@@ -849,7 +859,7 @@ bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
       (!O.Alignment || *O.Alignment >= (1ULL << Mapping.Scale) ||
        *O.Alignment >= O.TypeSize / 8)) {
     size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize);
-    if (ClInstrumentWithCalls) {
+    if (InstrumentWithCalls) {
       IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
                      IRB.CreatePointerCast(Addr, IntptrTy));
     } else {
@@ -884,7 +894,7 @@ bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI,
     Size = AlignedSize;
 
   Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
-  if (ClInstrumentWithCalls) {
+  if (InstrumentWithCalls) {
     IRB.CreateCall(HwasanTagMemoryFunc,
                    {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag,
                     ConstantInt::get(IntptrTy, AlignedSize)});
@@ -976,6 +986,7 @@ Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
 // Add a tag to an address.
 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
                                       Value *PtrLong, Value *Tag) {
+  assert(!UsePageAliases);
   Value *TaggedPtrLong;
   if (CompileKernel) {
     // Kernel addresses have 0xFF in the most significant byte.
@@ -1207,7 +1218,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
   DenseMap<AllocaInst *, std::vector<DbgVariableIntrinsic *>> AllocaDbgMap;
   for (auto &BB : F) {
     for (auto &Inst : BB) {
-      if (ClInstrumentStack)
+      if (InstrumentStack)
         if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
           if (isInterestingAlloca(*AI))
             AllocasToInstrument.push_back(AI);
@@ -1343,6 +1354,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
 }
 
 void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
+  assert(!UsePageAliases);
   Constant *Initializer = GV->getInitializer();
   uint64_t SizeInBytes =
       M.getDataLayout().getTypeAllocSize(Initializer->getType());
@@ -1515,13 +1527,14 @@ void HWAddressSanitizer::instrumentPersonalityFunctions() {
   }
 }
 
-void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) {
+void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple,
+                                             bool InstrumentWithCalls) {
   Scale = kDefaultShadowScale;
   if (ClMappingOffset.getNumOccurrences() > 0) {
     InGlobal = false;
     InTls = false;
     Offset = ClMappingOffset;
-  } else if (ClEnableKhwasan || ClInstrumentWithCalls) {
+  } else if (ClEnableKhwasan || InstrumentWithCalls) {
     InGlobal = false;
     InTls = false;
     Offset = 0;

diff  --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll
index 56676b6fd432..ce2c187cf039 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/atomic.ll
@@ -9,7 +9,7 @@ define void @atomicrmw(i64* %ptr) sanitize_hwaddress {
 ; CHECK-LABEL: @atomicrmw(
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64
 
-; CHECK: call void asm sideeffect "int3\0Anopl 83(%rax)", "{rdi}"(i64 %[[A]])
+; CHECK: call void @__hwasan_store8(i64 %[[A]])
 
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64
 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935
@@ -26,7 +26,7 @@ define void @cmpxchg(i64* %ptr, i64 %compare_to, i64 %new_value) sanitize_hwaddr
 ; CHECK-LABEL: @cmpxchg(
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64
 
-; CHECK: call void asm sideeffect "int3\0Anopl 83(%rax)", "{rdi}"(i64 %[[A]])
+; CHECK: call void @__hwasan_store8(i64 %[[A]])
 
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %ptr to i64
 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935

diff  --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll
index a35dcff87381..e93ebb766252 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll
@@ -12,10 +12,8 @@ define i8 @test_load8(i8* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load8(
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 
-; ABORT: call void asm sideeffect "int3\0Anopl 64(%rax)", "{rdi}"(i64 %[[A]])
-; ABORT: unreachable
-; RECOVER: call void asm sideeffect "int3\0Anopl 96(%rax)", "{rdi}"(i64 %[[A]])
-; RECOVER: br label
+; ABORT: call void @__hwasan_load1(i64 %[[A]])
+; RECOVER: call void @__hwasan_load1_noabort(i64 %[[A]])
 
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935
@@ -50,10 +48,8 @@ define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
 ; CHECK-LABEL: @test_store8(
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 
-; ABORT: call void asm sideeffect "int3\0Anopl 80(%rax)", "{rdi}"(i64 %[[A]])
-; ABORT: unreachable
-; RECOVER: call void asm sideeffect "int3\0Anopl 112(%rax)", "{rdi}"(i64 %[[A]])
-; RECOVER: br label
+; ABORT: call void @__hwasan_store1(i64 %[[A]])
+; RECOVER: call void @__hwasan_store1_noabort(i64 %[[A]])
 
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 ; CHECK: %[[UNTAGGED:[^ ]*]] = and i64 %[[A]], 72057594037927935

diff  --git a/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll b/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll
index 06ec63c859b1..66e13daf68ff 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/X86/kernel.ll
@@ -15,10 +15,8 @@ define i8 @test_load(i8* %a) sanitize_hwaddress {
 ; CHECK-LABEL: @test_load(
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 
-; ABORT: call void asm sideeffect "int3\0Anopl 64(%rax)", "{rdi}"(i64 %[[A]])
-; ABORT: unreachable
-; RECOVER: call void asm sideeffect "int3\0Anopl 96(%rax)", "{rdi}"(i64 %[[A]])
-; RECOVER: br label
+; ABORT: call void @__hwasan_load1(i64 %[[A]])
+; RECOVER: call void @__hwasan_load1_noabort(i64 %[[A]])
 
 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
 ; CHECK: %[[UNTAGGED:[^ ]*]] = or i64 %[[A]], -72057594037927936


        


More information about the llvm-commits mailing list