From 80ccda2d4bd3d5aed4a7c49d3d4d4adbb20318f3 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 9 Feb 2018 00:59:10 +0000 Subject: [PATCH] [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 llvm-svn: 324691 --- .../Instrumentation/HWAddressSanitizer.cpp | 24 +++++++++++++++--- .../HWAddressSanitizer/kernel-alloca.ll | 29 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index df2fe37..cc8abb8 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -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 &Allocas, SmallVectorImpl &RetVec); Value *getNextTagWithCall(IRBuilder<> &IRB); @@ -442,6 +443,24 @@ Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) { 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 &Allocas, SmallVectorImpl &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++; diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll b/llvm/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll new file mode 100644 index 0000000..6e56919 --- /dev/null +++ b/llvm/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll @@ -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 +} -- 2.7.4