Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -133,6 +133,7 @@ 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 @@ 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 @@ // 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++; Index: llvm/test/Instrumentation/HWAddressSanitizer/kernel-alloca.ll =================================================================== --- /dev/null +++ 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 +}