[llvm] r322429 - [hwasan] An LLVM flag to disable stack tag randomization.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 12 17:32:15 PST 2018


Author: eugenis
Date: Fri Jan 12 17:32:15 2018
New Revision: 322429

URL: http://llvm.org/viewvc/llvm-project?rev=322429&view=rev
Log:
[hwasan] An LLVM flag to disable stack tag randomization.

Summary: Necessary to achieve consistent test results.

Reviewers: kcc, alekseyshl

Subscribers: kubamracek, llvm-commits, hiraditya

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

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
    llvm/trunk/test/Instrumentation/HWAddressSanitizer/alloca.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp?rev=322429&r1=322428&r2=322429&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Fri Jan 12 17:32:15 2018
@@ -91,6 +91,11 @@ static cl::opt<bool> ClInstrumentStack("
                                        cl::desc("instrument stack (allocas)"),
                                        cl::Hidden, cl::init(true));
 
+static cl::opt<bool> ClGenerateTagsWithCalls(
+    "hwasan-generate-tags-with-calls",
+    cl::desc("generate new tags with runtime library calls"), cl::Hidden,
+    cl::init(false));
+
 namespace {
 
 /// \brief An instrumentation pass implementing detection of addressability bugs
@@ -121,6 +126,11 @@ public:
   bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag);
   bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas,
                        SmallVectorImpl<Instruction *> &RetVec);
+  Value *getNextTagWithCall(IRBuilder<> &IRB);
+  Value *getStackBaseTag(IRBuilder<> &IRB);
+  Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI,
+                     unsigned AllocaNo);
+  Value *getUARTag(IRBuilder<> &IRB, Value *StackTag);
 
 private:
   LLVMContext *C;
@@ -135,6 +145,7 @@ private:
   Function *HwasanMemoryAccessCallbackSized[2];
 
   Function *HwasanTagMemoryFunc;
+  Function *HwasanGenerateTagFunc;
 };
 
 } // end anonymous namespace
@@ -198,6 +209,8 @@ void HWAddressSanitizer::initializeCallb
 
   HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
       "__hwasan_tag_memory", IRB.getVoidTy(), IntptrTy, Int8Ty, IntptrTy));
+  HwasanGenerateTagFunc = checkSanitizerInterfaceFunction(
+      M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty));
 }
 
 Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I,
@@ -373,18 +386,20 @@ static unsigned RetagMask(unsigned Alloc
   return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))];
 }
 
-bool HWAddressSanitizer::instrumentStack(
-    SmallVectorImpl<AllocaInst *> &Allocas,
-    SmallVectorImpl<Instruction *> &RetVec) {
-  Function *F = Allocas[0]->getParent()->getParent();
-  Module *M = F->getParent();
-  Instruction *InsertPt = &*F->getEntryBlock().begin();
-  IRBuilder<> IRB(InsertPt);
+Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
+  return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
+}
 
+Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
+  if (ClGenerateTagsWithCalls)
+    return nullptr;
   // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
   // first).
-  auto GetStackPointerFn = Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
-  Value *StackPointer = IRB.CreateCall(GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
+  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+  auto GetStackPointerFn =
+      Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
+  Value *StackPointer = IRB.CreateCall(
+      GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
 
   // Extract some entropy from the stack pointer for the tags.
   // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
@@ -393,6 +408,31 @@ bool HWAddressSanitizer::instrumentStack
   Value *StackTag =
       IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20),
                     "hwasan.stack.base.tag");
+  return StackTag;
+}
+
+Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
+                                        AllocaInst *AI, unsigned AllocaNo) {
+  if (ClGenerateTagsWithCalls)
+    return getNextTagWithCall(IRB);
+  return IRB.CreateXor(StackTag,
+                       ConstantInt::get(IntptrTy, RetagMask(AllocaNo)));
+}
+
+Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
+  if (ClGenerateTagsWithCalls)
+    return getNextTagWithCall(IRB);
+  return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
+}
+
+bool HWAddressSanitizer::instrumentStack(
+    SmallVectorImpl<AllocaInst *> &Allocas,
+    SmallVectorImpl<Instruction *> &RetVec) {
+  Function *F = Allocas[0]->getParent()->getParent();
+  Instruction *InsertPt = &*F->getEntryBlock().begin();
+  IRBuilder<> IRB(InsertPt);
+
+  Value *StackTag = getStackBaseTag(IRB);
 
   // Ideally, we want to calculate tagged stack base pointer, and rewrite all
   // alloca addresses using that. Unfortunately, offsets are not known yet
@@ -404,17 +444,15 @@ bool HWAddressSanitizer::instrumentStack
     IRB.SetInsertPoint(AI->getNextNode());
 
     // Replace uses of the alloca with tagged address.
+    Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
+    Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
     std::string Name =
         AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
-    Value *Tag =
-        IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, RetagMask(N)));
-    Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
     Value *Replacement = IRB.CreateIntToPtr(
         IRB.CreateOr(AILong, IRB.CreateShl(Tag, kPointerTagShift)),
         AI->getType(), Name + ".hwasan");
 
-    for (auto UI = AI->use_begin(), UE = AI->use_end();
-         UI != UE;) {
+    for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
       Use &U = *UI++;
       if (U.getUser() != AILong)
         U.set(Replacement);
@@ -426,7 +464,7 @@ bool HWAddressSanitizer::instrumentStack
       IRB.SetInsertPoint(RI);
 
       // Re-tag alloca memory with the special UAR tag.
-      Value *Tag = IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
+      Value *Tag = getUARTag(IRB, StackTag);
       tagAlloca(IRB, AI, Tag);
     }
   }

Modified: llvm/trunk/test/Instrumentation/HWAddressSanitizer/alloca.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/HWAddressSanitizer/alloca.ll?rev=322429&r1=322428&r2=322429&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/HWAddressSanitizer/alloca.ll (original)
+++ llvm/trunk/test/Instrumentation/HWAddressSanitizer/alloca.ll Fri Jan 12 17:32:15 2018
@@ -1,6 +1,7 @@
 ; Test basic address sanitizer instrumentation.
 ;
 ; RUN: opt < %s -hwasan -S | FileCheck %s
+; RUN: opt < %s -hwasan -hwasan-generate-tags-with-calls -S | FileCheck %s --check-prefix=WITH-CALLS
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64--linux-android"
@@ -43,3 +44,9 @@ entry:
   ret void
 }
 
+; WITH-CALLS-LABEL: @test_alloca(
+; WITH-CALLS: %[[T1:[^ ]*]] = call i8 @__hwasan_generate_tag()
+; WITH-CALLS: %[[A:[^ ]*]] = zext i8 %[[T1]] to i64
+; WITH-CALLS: %[[B:[^ ]*]] = ptrtoint i32* %x to i64
+; WITH-CALLS: %[[C:[^ ]*]] = shl i64 %[[A]], 56
+; WITH-CALLS: or i64 %[[B]], %[[C]]




More information about the llvm-commits mailing list