[llvm] r324691 - [hwasan] Fix kernel instrumentation of stack.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 16:59:10 PST 2018


Author: eugenis
Date: Thu Feb  8 16:59:10 2018
New Revision: 324691

URL: http://llvm.org/viewvc/llvm-project?rev=324691&view=rev
Log:
[hwasan] Fix kernel instrumentation of stack.

Summary:
Kernel addresses have 0xFF in the most significant byte.
A tag can not be pushed there with OR (tag << 56);
use AND ((tag << 56) | 0x00FF..FF) instead.

Reviewers: kcc, andreyknvl

Subscribers: srhines, llvm-commits, hiraditya

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

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

Modified: llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp?rev=324691&r1=324690&r2=324691&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp Thu Feb  8 16:59:10 2018
@@ -133,6 +133,7 @@ public:
 
   bool isInterestingAlloca(const AllocaInst &AI);
   bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag);
+  Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
   bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas,
                        SmallVectorImpl<Instruction *> &RetVec);
   Value *getNextTagWithCall(IRBuilder<> &IRB);
@@ -442,6 +443,24 @@ Value *HWAddressSanitizer::getUARTag(IRB
   return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
 }
 
+// Add a tag to an address.
+Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong,
+                                      Value *Tag) {
+  Value *TaggedPtrLong;
+  if (ClEnableKhwasan) {
+    // Kernel addresses have 0xFF in the most significant byte.
+    Value *ShiftedTag = IRB.CreateOr(
+        IRB.CreateShl(Tag, kPointerTagShift),
+        ConstantInt::get(IntptrTy, (1ULL << kPointerTagShift) - 1));
+    TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
+  } else {
+    // Userspace can simply do OR (tag << 56);
+    Value *ShiftedTag = IRB.CreateShl(Tag, kPointerTagShift);
+    TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
+  }
+  return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
+}
+
 bool HWAddressSanitizer::instrumentStack(
     SmallVectorImpl<AllocaInst *> &Allocas,
     SmallVectorImpl<Instruction *> &RetVec) {
@@ -463,11 +482,10 @@ bool HWAddressSanitizer::instrumentStack
     // Replace uses of the alloca with tagged address.
     Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
     Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
+    Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag);
     std::string Name =
         AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
-    Value *Replacement = IRB.CreateIntToPtr(
-        IRB.CreateOr(AILong, IRB.CreateShl(Tag, kPointerTagShift)),
-        AI->getType(), Name + ".hwasan");
+    Replacement->setName(Name + ".hwasan");
 
     for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
       Use &U = *UI++;

Added: llvm/trunk/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll?rev=324691&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll (added)
+++ llvm/trunk/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll Thu Feb  8 16:59:10 2018
@@ -0,0 +1,29 @@
+; Test basic address sanitizer instrumentation.
+;
+; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-android"
+
+declare void @use32(i32*)
+
+define void @test_alloca() sanitize_hwaddress {
+; CHECK-LABEL: @test_alloca(
+; CHECK: %[[FP:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
+; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %[[FP]] to i64
+; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 20
+; CHECK: %[[BASE_TAG:[^ ]*]] = xor i64 %[[A]], %[[B]]
+
+; CHECK: %[[X:[^ ]*]] = alloca i32, align 16
+; CHECK: %[[X_TAG:[^ ]*]] = xor i64 %[[BASE_TAG]], 0
+; CHECK: %[[X1:[^ ]*]] = ptrtoint i32* %[[X]] to i64
+; CHECK: %[[C:[^ ]*]] = shl i64 %[[X_TAG]], 56
+; CHECK: %[[D:[^ ]*]] = or i64 %[[C]], 72057594037927935
+; CHECK: %[[E:[^ ]*]] = and i64 %[[X1]], %[[D]]
+; CHECK: %[[X_HWASAN:[^ ]*]] = inttoptr i64 %[[E]] to i32*
+
+entry:
+  %x = alloca i32, align 4
+  call void @use32(i32* nonnull %x)
+  ret void
+}




More information about the llvm-commits mailing list