diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2018-02-09 00:59:10 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2018-02-09 00:59:10 +0000 |
commit | 80ccda2d4bd3d5aed4a7c49d3d4d4adbb20318f3 (patch) | |
tree | e00896184b4f4185b3a95408854f77a6db752615 /llvm/lib/Transforms | |
parent | 7d3dde3c6b31b513a9c3e6b8d9cf8acc530dbab0 (diff) | |
download | bcm5719-llvm-80ccda2d4bd3d5aed4a7c49d3d4d4adbb20318f3.tar.gz bcm5719-llvm-80ccda2d4bd3d5aed4a7c49d3d4d4adbb20318f3.zip |
[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
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index df2fe37a6d4..cc8abb8a60a 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<AllocaInst *> &Allocas, SmallVectorImpl<Instruction *> &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<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++; |