1 //===- HWAddressSanitizer.cpp - detector of uninitialized reads -------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// This file is a part of HWAddressSanitizer, an address sanity checker 12 /// based on tagged addressing. 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/IR/Attributes.h" 20 #include "llvm/IR/BasicBlock.h" 21 #include "llvm/IR/Constant.h" 22 #include "llvm/IR/Constants.h" 23 #include "llvm/IR/DataLayout.h" 24 #include "llvm/IR/DerivedTypes.h" 25 #include "llvm/IR/Function.h" 26 #include "llvm/IR/IRBuilder.h" 27 #include "llvm/IR/InlineAsm.h" 28 #include "llvm/IR/InstVisitor.h" 29 #include "llvm/IR/Instruction.h" 30 #include "llvm/IR/Instructions.h" 31 #include "llvm/IR/IntrinsicInst.h" 32 #include "llvm/IR/Intrinsics.h" 33 #include "llvm/IR/LLVMContext.h" 34 #include "llvm/IR/MDBuilder.h" 35 #include "llvm/IR/Module.h" 36 #include "llvm/IR/Type.h" 37 #include "llvm/IR/Value.h" 38 #include "llvm/Pass.h" 39 #include "llvm/Support/Casting.h" 40 #include "llvm/Support/CommandLine.h" 41 #include "llvm/Support/Debug.h" 42 #include "llvm/Support/raw_ostream.h" 43 #include "llvm/Transforms/Instrumentation.h" 44 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 45 #include "llvm/Transforms/Utils/ModuleUtils.h" 46 #include "llvm/Transforms/Utils/PromoteMemToReg.h" 47 #include <sstream> 48 49 using namespace llvm; 50 51 #define DEBUG_TYPE "hwasan" 52 53 static const char *const kHwasanModuleCtorName = "hwasan.module_ctor"; 54 static const char *const kHwasanInitName = "__hwasan_init"; 55 56 static const char *const kHwasanShadowMemoryDynamicAddress = 57 "__hwasan_shadow_memory_dynamic_address"; 58 59 // Accesses sizes are powers of two: 1, 2, 4, 8, 16. 60 static const size_t kNumberOfAccessSizes = 5; 61 62 static const size_t kDefaultShadowScale = 4; 63 static const uint64_t kDynamicShadowSentinel = 64 std::numeric_limits<uint64_t>::max(); 65 static const unsigned kPointerTagShift = 56; 66 67 static const unsigned kShadowBaseAlignment = 32; 68 69 static cl::opt<std::string> ClMemoryAccessCallbackPrefix( 70 "hwasan-memory-access-callback-prefix", 71 cl::desc("Prefix for memory access callbacks"), cl::Hidden, 72 cl::init("__hwasan_")); 73 74 static cl::opt<bool> 75 ClInstrumentWithCalls("hwasan-instrument-with-calls", 76 cl::desc("instrument reads and writes with callbacks"), 77 cl::Hidden, cl::init(false)); 78 79 static cl::opt<bool> ClInstrumentReads("hwasan-instrument-reads", 80 cl::desc("instrument read instructions"), 81 cl::Hidden, cl::init(true)); 82 83 static cl::opt<bool> ClInstrumentWrites( 84 "hwasan-instrument-writes", cl::desc("instrument write instructions"), 85 cl::Hidden, cl::init(true)); 86 87 static cl::opt<bool> ClInstrumentAtomics( 88 "hwasan-instrument-atomics", 89 cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, 90 cl::init(true)); 91 92 static cl::opt<bool> ClRecover( 93 "hwasan-recover", 94 cl::desc("Enable recovery mode (continue-after-error)."), 95 cl::Hidden, cl::init(false)); 96 97 static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack", 98 cl::desc("instrument stack (allocas)"), 99 cl::Hidden, cl::init(true)); 100 101 static cl::opt<bool> ClUARRetagToZero( 102 "hwasan-uar-retag-to-zero", 103 cl::desc("Clear alloca tags before returning from the function to allow " 104 "non-instrumented and instrumented function calls mix. When set " 105 "to false, allocas are retagged before returning from the " 106 "function to detect use after return."), 107 cl::Hidden, cl::init(true)); 108 109 static cl::opt<bool> ClGenerateTagsWithCalls( 110 "hwasan-generate-tags-with-calls", 111 cl::desc("generate new tags with runtime library calls"), cl::Hidden, 112 cl::init(false)); 113 114 static cl::opt<int> ClMatchAllTag( 115 "hwasan-match-all-tag", 116 cl::desc("don't report bad accesses via pointers with this tag"), 117 cl::Hidden, cl::init(-1)); 118 119 static cl::opt<bool> ClEnableKhwasan( 120 "hwasan-kernel", 121 cl::desc("Enable KernelHWAddressSanitizer instrumentation"), 122 cl::Hidden, cl::init(false)); 123 124 // These flags allow to change the shadow mapping and control how shadow memory 125 // is accessed. The shadow mapping looks like: 126 // Shadow = (Mem >> scale) + offset 127 128 static cl::opt<unsigned long long> ClMappingOffset( 129 "hwasan-mapping-offset", 130 cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, 131 cl::init(0)); 132 133 static cl::opt<bool> 134 ClWithIfunc("hwasan-with-ifunc", 135 cl::desc("Access dynamic shadow through an ifunc global on " 136 "platforms that support this"), 137 cl::Hidden, cl::init(false)); 138 139 static cl::opt<bool> ClWithTls( 140 "hwasan-with-tls", 141 cl::desc("Access dynamic shadow through an thread-local pointer on " 142 "platforms that support this"), 143 cl::Hidden, cl::init(true)); 144 145 static cl::opt<bool> 146 ClRecordStackHistory("hwasan-record-stack-history", 147 cl::desc("Record stack frames with tagged allocations " 148 "in a thread-local ring buffer"), 149 cl::Hidden, cl::init(true)); 150 static cl::opt<bool> 151 ClCreateFrameDescriptions("hwasan-create-frame-descriptions", 152 cl::desc("create static frame descriptions"), 153 cl::Hidden, cl::init(true)); 154 155 namespace { 156 157 /// An instrumentation pass implementing detection of addressability bugs 158 /// using tagged pointers. 159 class HWAddressSanitizer : public FunctionPass { 160 public: 161 // Pass identification, replacement for typeid. 162 static char ID; 163 164 explicit HWAddressSanitizer(bool CompileKernel = false, bool Recover = false) 165 : FunctionPass(ID) { 166 this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover; 167 this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0 ? 168 ClEnableKhwasan : CompileKernel; 169 } 170 171 StringRef getPassName() const override { return "HWAddressSanitizer"; } 172 173 bool runOnFunction(Function &F) override; 174 bool doInitialization(Module &M) override; 175 176 void initializeCallbacks(Module &M); 177 178 Value *getDynamicShadowNonTls(IRBuilder<> &IRB); 179 180 void untagPointerOperand(Instruction *I, Value *Addr); 181 Value *memToShadow(Value *Shadow, Type *Ty, IRBuilder<> &IRB); 182 void instrumentMemAccessInline(Value *PtrLong, bool IsWrite, 183 unsigned AccessSizeIndex, 184 Instruction *InsertBefore); 185 bool instrumentMemAccess(Instruction *I); 186 Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, 187 uint64_t *TypeSize, unsigned *Alignment, 188 Value **MaybeMask); 189 190 bool isInterestingAlloca(const AllocaInst &AI); 191 bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag); 192 Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag); 193 Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong); 194 bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas, 195 SmallVectorImpl<Instruction *> &RetVec, Value *StackTag); 196 Value *getNextTagWithCall(IRBuilder<> &IRB); 197 Value *getStackBaseTag(IRBuilder<> &IRB); 198 Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI, 199 unsigned AllocaNo); 200 Value *getUARTag(IRBuilder<> &IRB, Value *StackTag); 201 202 Value *getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty); 203 Value *emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord); 204 205 private: 206 LLVMContext *C; 207 std::string CurModuleUniqueId; 208 Triple TargetTriple; 209 210 // Frame description is a way to pass names/sizes of local variables 211 // to the run-time w/o adding extra executable code in every function. 212 // We do this by creating a separate section with {PC,Descr} pairs and passing 213 // the section beg/end to __hwasan_init_frames() at module init time. 214 std::string createFrameString(ArrayRef<AllocaInst*> Allocas); 215 void createFrameGlobal(Function &F, const std::string &FrameString); 216 // Get the section name for frame descriptions. Currently ELF-only. 217 const char *getFrameSection() { return "__hwasan_frames"; } 218 const char *getFrameSectionBeg() { return "__start___hwasan_frames"; } 219 const char *getFrameSectionEnd() { return "__stop___hwasan_frames"; } 220 GlobalVariable *createFrameSectionBound(Module &M, Type *Ty, 221 const char *Name) { 222 auto GV = new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, 223 nullptr, Name); 224 GV->setVisibility(GlobalValue::HiddenVisibility); 225 return GV; 226 } 227 228 /// This struct defines the shadow mapping using the rule: 229 /// shadow = (mem >> Scale) + Offset. 230 /// If InGlobal is true, then 231 /// extern char __hwasan_shadow[]; 232 /// shadow = (mem >> Scale) + &__hwasan_shadow 233 /// If InTls is true, then 234 /// extern char *__hwasan_tls; 235 /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment) 236 struct ShadowMapping { 237 int Scale; 238 uint64_t Offset; 239 bool InGlobal; 240 bool InTls; 241 242 void init(Triple &TargetTriple); 243 unsigned getAllocaAlignment() const { return 1U << Scale; } 244 }; 245 ShadowMapping Mapping; 246 247 Type *IntptrTy; 248 Type *Int8PtrTy; 249 Type *Int8Ty; 250 251 bool CompileKernel; 252 bool Recover; 253 254 Function *HwasanCtorFunction; 255 256 Function *HwasanMemoryAccessCallback[2][kNumberOfAccessSizes]; 257 Function *HwasanMemoryAccessCallbackSized[2]; 258 259 Function *HwasanTagMemoryFunc; 260 Function *HwasanGenerateTagFunc; 261 262 Constant *ShadowGlobal; 263 264 Value *LocalDynamicShadow = nullptr; 265 GlobalValue *ThreadPtrGlobal = nullptr; 266 }; 267 268 } // end anonymous namespace 269 270 char HWAddressSanitizer::ID = 0; 271 272 INITIALIZE_PASS_BEGIN( 273 HWAddressSanitizer, "hwasan", 274 "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, 275 false) 276 INITIALIZE_PASS_END( 277 HWAddressSanitizer, "hwasan", 278 "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, 279 false) 280 281 FunctionPass *llvm::createHWAddressSanitizerPass(bool CompileKernel, 282 bool Recover) { 283 assert(!CompileKernel || Recover); 284 return new HWAddressSanitizer(CompileKernel, Recover); 285 } 286 287 /// Module-level initialization. 288 /// 289 /// inserts a call to __hwasan_init to the module's constructor list. 290 bool HWAddressSanitizer::doInitialization(Module &M) { 291 LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n"); 292 auto &DL = M.getDataLayout(); 293 294 TargetTriple = Triple(M.getTargetTriple()); 295 296 Mapping.init(TargetTriple); 297 298 C = &(M.getContext()); 299 CurModuleUniqueId = getUniqueModuleId(&M); 300 IRBuilder<> IRB(*C); 301 IntptrTy = IRB.getIntPtrTy(DL); 302 Int8PtrTy = IRB.getInt8PtrTy(); 303 Int8Ty = IRB.getInt8Ty(); 304 305 HwasanCtorFunction = nullptr; 306 if (!CompileKernel) { 307 std::tie(HwasanCtorFunction, std::ignore) = 308 createSanitizerCtorAndInitFunctions(M, kHwasanModuleCtorName, 309 kHwasanInitName, 310 /*InitArgTypes=*/{}, 311 /*InitArgs=*/{}); 312 Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName); 313 HwasanCtorFunction->setComdat(CtorComdat); 314 appendToGlobalCtors(M, HwasanCtorFunction, 0, HwasanCtorFunction); 315 316 // Create a zero-length global in __hwasan_frame so that the linker will 317 // always create start and stop symbols. 318 // 319 // N.B. If we ever start creating associated metadata in this pass this 320 // global will need to be associated with the ctor. 321 Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0); 322 auto GV = 323 new GlobalVariable(M, Int8Arr0Ty, /*isConstantGlobal*/ true, 324 GlobalVariable::PrivateLinkage, 325 Constant::getNullValue(Int8Arr0Ty), "__hwasan"); 326 GV->setSection(getFrameSection()); 327 GV->setComdat(CtorComdat); 328 appendToCompilerUsed(M, GV); 329 330 IRBuilder<> IRBCtor(HwasanCtorFunction->getEntryBlock().getTerminator()); 331 IRBCtor.CreateCall( 332 declareSanitizerInitFunction(M, "__hwasan_init_frames", 333 {Int8PtrTy, Int8PtrTy}), 334 {createFrameSectionBound(M, Int8Ty, getFrameSectionBeg()), 335 createFrameSectionBound(M, Int8Ty, getFrameSectionEnd())}); 336 } 337 338 if (!TargetTriple.isAndroid()) 339 appendToCompilerUsed( 340 M, ThreadPtrGlobal = new GlobalVariable( 341 M, IntptrTy, false, GlobalVariable::ExternalLinkage, nullptr, 342 "__hwasan_tls", nullptr, GlobalVariable::InitialExecTLSModel)); 343 344 return true; 345 } 346 347 void HWAddressSanitizer::initializeCallbacks(Module &M) { 348 IRBuilder<> IRB(*C); 349 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 350 const std::string TypeStr = AccessIsWrite ? "store" : "load"; 351 const std::string EndingStr = Recover ? "_noabort" : ""; 352 353 HwasanMemoryAccessCallbackSized[AccessIsWrite] = 354 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 355 ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr, 356 FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false))); 357 358 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 359 AccessSizeIndex++) { 360 HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] = 361 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 362 ClMemoryAccessCallbackPrefix + TypeStr + 363 itostr(1ULL << AccessSizeIndex) + EndingStr, 364 FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false))); 365 } 366 } 367 368 HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 369 "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy)); 370 HwasanGenerateTagFunc = checkSanitizerInterfaceFunction( 371 M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty)); 372 373 if (Mapping.InGlobal) 374 ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow", 375 ArrayType::get(IRB.getInt8Ty(), 0)); 376 } 377 378 Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) { 379 // Generate code only when dynamic addressing is needed. 380 if (Mapping.Offset != kDynamicShadowSentinel) 381 return nullptr; 382 383 if (Mapping.InGlobal) { 384 // An empty inline asm with input reg == output reg. 385 // An opaque pointer-to-int cast, basically. 386 InlineAsm *Asm = InlineAsm::get( 387 FunctionType::get(IntptrTy, {ShadowGlobal->getType()}, false), 388 StringRef(""), StringRef("=r,0"), 389 /*hasSideEffects=*/false); 390 return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow"); 391 } else { 392 Value *GlobalDynamicAddress = 393 IRB.GetInsertBlock()->getParent()->getParent()->getOrInsertGlobal( 394 kHwasanShadowMemoryDynamicAddress, IntptrTy); 395 return IRB.CreateLoad(GlobalDynamicAddress); 396 } 397 } 398 399 Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I, 400 bool *IsWrite, 401 uint64_t *TypeSize, 402 unsigned *Alignment, 403 Value **MaybeMask) { 404 // Skip memory accesses inserted by another instrumentation. 405 if (I->getMetadata("nosanitize")) return nullptr; 406 407 // Do not instrument the load fetching the dynamic shadow address. 408 if (LocalDynamicShadow == I) 409 return nullptr; 410 411 Value *PtrOperand = nullptr; 412 const DataLayout &DL = I->getModule()->getDataLayout(); 413 if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 414 if (!ClInstrumentReads) return nullptr; 415 *IsWrite = false; 416 *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); 417 *Alignment = LI->getAlignment(); 418 PtrOperand = LI->getPointerOperand(); 419 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 420 if (!ClInstrumentWrites) return nullptr; 421 *IsWrite = true; 422 *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); 423 *Alignment = SI->getAlignment(); 424 PtrOperand = SI->getPointerOperand(); 425 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 426 if (!ClInstrumentAtomics) return nullptr; 427 *IsWrite = true; 428 *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); 429 *Alignment = 0; 430 PtrOperand = RMW->getPointerOperand(); 431 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 432 if (!ClInstrumentAtomics) return nullptr; 433 *IsWrite = true; 434 *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); 435 *Alignment = 0; 436 PtrOperand = XCHG->getPointerOperand(); 437 } 438 439 if (PtrOperand) { 440 // Do not instrument accesses from different address spaces; we cannot deal 441 // with them. 442 Type *PtrTy = cast<PointerType>(PtrOperand->getType()->getScalarType()); 443 if (PtrTy->getPointerAddressSpace() != 0) 444 return nullptr; 445 446 // Ignore swifterror addresses. 447 // swifterror memory addresses are mem2reg promoted by instruction 448 // selection. As such they cannot have regular uses like an instrumentation 449 // function and it makes no sense to track them as memory. 450 if (PtrOperand->isSwiftError()) 451 return nullptr; 452 } 453 454 return PtrOperand; 455 } 456 457 static unsigned getPointerOperandIndex(Instruction *I) { 458 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 459 return LI->getPointerOperandIndex(); 460 if (StoreInst *SI = dyn_cast<StoreInst>(I)) 461 return SI->getPointerOperandIndex(); 462 if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) 463 return RMW->getPointerOperandIndex(); 464 if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) 465 return XCHG->getPointerOperandIndex(); 466 report_fatal_error("Unexpected instruction"); 467 return -1; 468 } 469 470 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 471 size_t Res = countTrailingZeros(TypeSize / 8); 472 assert(Res < kNumberOfAccessSizes); 473 return Res; 474 } 475 476 void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) { 477 if (TargetTriple.isAArch64()) 478 return; 479 480 IRBuilder<> IRB(I); 481 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 482 Value *UntaggedPtr = 483 IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType()); 484 I->setOperand(getPointerOperandIndex(I), UntaggedPtr); 485 } 486 487 Value *HWAddressSanitizer::memToShadow(Value *Mem, Type *Ty, IRBuilder<> &IRB) { 488 // Mem >> Scale 489 Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale); 490 if (Mapping.Offset == 0) 491 return Shadow; 492 // (Mem >> Scale) + Offset 493 Value *ShadowBase; 494 if (LocalDynamicShadow) 495 ShadowBase = LocalDynamicShadow; 496 else 497 ShadowBase = ConstantInt::get(Ty, Mapping.Offset); 498 return IRB.CreateAdd(Shadow, ShadowBase); 499 } 500 501 void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite, 502 unsigned AccessSizeIndex, 503 Instruction *InsertBefore) { 504 IRBuilder<> IRB(InsertBefore); 505 Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift), 506 IRB.getInt8Ty()); 507 Value *AddrLong = untagPointer(IRB, PtrLong); 508 Value *ShadowLong = memToShadow(AddrLong, PtrLong->getType(), IRB); 509 Value *MemTag = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, Int8PtrTy)); 510 Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag); 511 512 int matchAllTag = ClMatchAllTag.getNumOccurrences() > 0 ? 513 ClMatchAllTag : (CompileKernel ? 0xFF : -1); 514 if (matchAllTag != -1) { 515 Value *TagNotIgnored = IRB.CreateICmpNE(PtrTag, 516 ConstantInt::get(PtrTag->getType(), matchAllTag)); 517 TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored); 518 } 519 520 Instruction *CheckTerm = 521 SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, !Recover, 522 MDBuilder(*C).createBranchWeights(1, 100000)); 523 524 IRB.SetInsertPoint(CheckTerm); 525 const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex; 526 InlineAsm *Asm; 527 switch (TargetTriple.getArch()) { 528 case Triple::x86_64: 529 // The signal handler will find the data address in rdi. 530 Asm = InlineAsm::get( 531 FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false), 532 "int3\nnopl " + itostr(0x40 + AccessInfo) + "(%rax)", 533 "{rdi}", 534 /*hasSideEffects=*/true); 535 break; 536 case Triple::aarch64: 537 case Triple::aarch64_be: 538 // The signal handler will find the data address in x0. 539 Asm = InlineAsm::get( 540 FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false), 541 "brk #" + itostr(0x900 + AccessInfo), 542 "{x0}", 543 /*hasSideEffects=*/true); 544 break; 545 default: 546 report_fatal_error("unsupported architecture"); 547 } 548 IRB.CreateCall(Asm, PtrLong); 549 } 550 551 bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) { 552 LLVM_DEBUG(dbgs() << "Instrumenting: " << *I << "\n"); 553 bool IsWrite = false; 554 unsigned Alignment = 0; 555 uint64_t TypeSize = 0; 556 Value *MaybeMask = nullptr; 557 Value *Addr = 558 isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask); 559 560 if (!Addr) 561 return false; 562 563 if (MaybeMask) 564 return false; //FIXME 565 566 IRBuilder<> IRB(I); 567 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 568 if (isPowerOf2_64(TypeSize) && 569 (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) && 570 (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 || 571 Alignment >= TypeSize / 8)) { 572 size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 573 if (ClInstrumentWithCalls) { 574 IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex], 575 AddrLong); 576 } else { 577 instrumentMemAccessInline(AddrLong, IsWrite, AccessSizeIndex, I); 578 } 579 } else { 580 IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite], 581 {AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8)}); 582 } 583 untagPointerOperand(I, Addr); 584 585 return true; 586 } 587 588 static uint64_t getAllocaSizeInBytes(const AllocaInst &AI) { 589 uint64_t ArraySize = 1; 590 if (AI.isArrayAllocation()) { 591 const ConstantInt *CI = dyn_cast<ConstantInt>(AI.getArraySize()); 592 assert(CI && "non-constant array size"); 593 ArraySize = CI->getZExtValue(); 594 } 595 Type *Ty = AI.getAllocatedType(); 596 uint64_t SizeInBytes = AI.getModule()->getDataLayout().getTypeAllocSize(Ty); 597 return SizeInBytes * ArraySize; 598 } 599 600 bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, 601 Value *Tag) { 602 size_t Size = (getAllocaSizeInBytes(*AI) + Mapping.getAllocaAlignment() - 1) & 603 ~(Mapping.getAllocaAlignment() - 1); 604 605 Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty()); 606 if (ClInstrumentWithCalls) { 607 IRB.CreateCall(HwasanTagMemoryFunc, 608 {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag, 609 ConstantInt::get(IntptrTy, Size)}); 610 } else { 611 size_t ShadowSize = Size >> Mapping.Scale; 612 Value *ShadowPtr = IRB.CreateIntToPtr( 613 memToShadow(IRB.CreatePointerCast(AI, IntptrTy), AI->getType(), IRB), 614 Int8PtrTy); 615 // If this memset is not inlined, it will be intercepted in the hwasan 616 // runtime library. That's OK, because the interceptor skips the checks if 617 // the address is in the shadow region. 618 // FIXME: the interceptor is not as fast as real memset. Consider lowering 619 // llvm.memset right here into either a sequence of stores, or a call to 620 // hwasan_tag_memory. 621 IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, /*Align=*/1); 622 } 623 return true; 624 } 625 626 static unsigned RetagMask(unsigned AllocaNo) { 627 // A list of 8-bit numbers that have at most one run of non-zero bits. 628 // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these 629 // masks. 630 // The list does not include the value 255, which is used for UAR. 631 static unsigned FastMasks[] = { 632 0, 1, 2, 3, 4, 6, 7, 8, 12, 14, 15, 16, 24, 633 28, 30, 31, 32, 48, 56, 60, 62, 63, 64, 96, 112, 120, 634 124, 126, 127, 128, 192, 224, 240, 248, 252, 254}; 635 return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))]; 636 } 637 638 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) { 639 return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy); 640 } 641 642 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) { 643 if (ClGenerateTagsWithCalls) 644 return getNextTagWithCall(IRB); 645 // FIXME: use addressofreturnaddress (but implement it in aarch64 backend 646 // first). 647 Module *M = IRB.GetInsertBlock()->getParent()->getParent(); 648 auto GetStackPointerFn = 649 Intrinsic::getDeclaration(M, Intrinsic::frameaddress); 650 Value *StackPointer = IRB.CreateCall( 651 GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())}); 652 653 // Extract some entropy from the stack pointer for the tags. 654 // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ 655 // between functions). 656 Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy); 657 Value *StackTag = 658 IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20), 659 "hwasan.stack.base.tag"); 660 return StackTag; 661 } 662 663 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag, 664 AllocaInst *AI, unsigned AllocaNo) { 665 if (ClGenerateTagsWithCalls) 666 return getNextTagWithCall(IRB); 667 return IRB.CreateXor(StackTag, 668 ConstantInt::get(IntptrTy, RetagMask(AllocaNo))); 669 } 670 671 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) { 672 if (ClUARRetagToZero) 673 return ConstantInt::get(IntptrTy, 0); 674 if (ClGenerateTagsWithCalls) 675 return getNextTagWithCall(IRB); 676 return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU)); 677 } 678 679 // Add a tag to an address. 680 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty, 681 Value *PtrLong, Value *Tag) { 682 Value *TaggedPtrLong; 683 if (CompileKernel) { 684 // Kernel addresses have 0xFF in the most significant byte. 685 Value *ShiftedTag = IRB.CreateOr( 686 IRB.CreateShl(Tag, kPointerTagShift), 687 ConstantInt::get(IntptrTy, (1ULL << kPointerTagShift) - 1)); 688 TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag); 689 } else { 690 // Userspace can simply do OR (tag << 56); 691 Value *ShiftedTag = IRB.CreateShl(Tag, kPointerTagShift); 692 TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag); 693 } 694 return IRB.CreateIntToPtr(TaggedPtrLong, Ty); 695 } 696 697 // Remove tag from an address. 698 Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) { 699 Value *UntaggedPtrLong; 700 if (CompileKernel) { 701 // Kernel addresses have 0xFF in the most significant byte. 702 UntaggedPtrLong = IRB.CreateOr(PtrLong, 703 ConstantInt::get(PtrLong->getType(), 0xFFULL << kPointerTagShift)); 704 } else { 705 // Userspace addresses have 0x00. 706 UntaggedPtrLong = IRB.CreateAnd(PtrLong, 707 ConstantInt::get(PtrLong->getType(), ~(0xFFULL << kPointerTagShift))); 708 } 709 return UntaggedPtrLong; 710 } 711 712 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) { 713 Module *M = IRB.GetInsertBlock()->getParent()->getParent(); 714 if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) { 715 Function *ThreadPointerFunc = 716 Intrinsic::getDeclaration(M, Intrinsic::thread_pointer); 717 Value *SlotPtr = IRB.CreatePointerCast( 718 IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), 0x40), 719 Ty->getPointerTo(0)); 720 return SlotPtr; 721 } 722 if (ThreadPtrGlobal) 723 return ThreadPtrGlobal; 724 725 726 return nullptr; 727 } 728 729 // Creates a string with a description of the stack frame (set of Allocas). 730 // The string is intended to be human readable. 731 // The current form is: Size1 Name1; Size2 Name2; ... 732 std::string 733 HWAddressSanitizer::createFrameString(ArrayRef<AllocaInst *> Allocas) { 734 std::ostringstream Descr; 735 for (auto AI : Allocas) 736 Descr << getAllocaSizeInBytes(*AI) << " " << AI->getName().str() << "; "; 737 return Descr.str(); 738 } 739 740 // Creates a global in the frame section which consists of two pointers: 741 // the function PC and the frame string constant. 742 void HWAddressSanitizer::createFrameGlobal(Function &F, 743 const std::string &FrameString) { 744 Module &M = *F.getParent(); 745 auto DescrGV = createPrivateGlobalForString(M, FrameString, true); 746 auto PtrPairTy = StructType::get(F.getType(), DescrGV->getType()); 747 auto GV = new GlobalVariable( 748 M, PtrPairTy, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage, 749 ConstantStruct::get(PtrPairTy, (Constant *)&F, (Constant *)DescrGV), 750 "__hwasan"); 751 GV->setSection(getFrameSection()); 752 appendToCompilerUsed(M, GV); 753 // Put GV into the F's Comadat so that if F is deleted GV can be deleted too. 754 if (auto Comdat = 755 GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId)) 756 GV->setComdat(Comdat); 757 } 758 759 Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, 760 bool WithFrameRecord) { 761 if (!Mapping.InTls) 762 return getDynamicShadowNonTls(IRB); 763 764 Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy); 765 assert(SlotPtr); 766 767 Value *ThreadLong = IRB.CreateLoad(SlotPtr); 768 // Extract the address field from ThreadLong. Unnecessary on AArch64 with TBI. 769 Value *ThreadLongMaybeUntagged = 770 TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong); 771 772 if (WithFrameRecord) { 773 // Prepare ring buffer data. 774 Function *F = IRB.GetInsertBlock()->getParent(); 775 auto PC = IRB.CreatePtrToInt(F, IntptrTy); 776 auto GetStackPointerFn = 777 Intrinsic::getDeclaration(F->getParent(), Intrinsic::frameaddress); 778 Value *SP = IRB.CreatePtrToInt( 779 IRB.CreateCall(GetStackPointerFn, 780 {Constant::getNullValue(IRB.getInt32Ty())}), 781 IntptrTy); 782 // Mix SP and PC. TODO: also add the tag to the mix. 783 // Assumptions: 784 // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero) 785 // SP is 0xsssssssssssSSSS0 (4 lower bits are zero) 786 // We only really need ~20 lower non-zero bits (SSSS), so we mix like this: 787 // 0xSSSSPPPPPPPPPPPP 788 SP = IRB.CreateShl(SP, 44); 789 790 // Store data to ring buffer. 791 Value *RecordPtr = 792 IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IntptrTy->getPointerTo(0)); 793 IRB.CreateStore(IRB.CreateOr(PC, SP), RecordPtr); 794 795 // Update the ring buffer. Top byte of ThreadLong defines the size of the 796 // buffer in pages, it must be a power of two, and the start of the buffer 797 // must be aligned by twice that much. Therefore wrap around of the ring 798 // buffer is simply Addr &= ~((ThreadLong >> 56) << 12). 799 // The use of AShr instead of LShr is due to 800 // https://bugs.llvm.org/show_bug.cgi?id=39030 801 // Runtime library makes sure not to use the highest bit. 802 Value *WrapMask = IRB.CreateXor( 803 IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true), 804 ConstantInt::get(IntptrTy, (uint64_t)-1)); 805 Value *ThreadLongNew = IRB.CreateAnd( 806 IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask); 807 IRB.CreateStore(ThreadLongNew, SlotPtr); 808 } 809 810 // Get shadow base address by aligning RecordPtr up. 811 // Note: this is not correct if the pointer is already aligned. 812 // Runtime library will make sure this never happens. 813 Value *ShadowBase = IRB.CreateAdd( 814 IRB.CreateOr( 815 ThreadLongMaybeUntagged, 816 ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)), 817 ConstantInt::get(IntptrTy, 1), "hwasan.shadow"); 818 return ShadowBase; 819 } 820 821 bool HWAddressSanitizer::instrumentStack( 822 SmallVectorImpl<AllocaInst *> &Allocas, 823 SmallVectorImpl<Instruction *> &RetVec, Value *StackTag) { 824 // Ideally, we want to calculate tagged stack base pointer, and rewrite all 825 // alloca addresses using that. Unfortunately, offsets are not known yet 826 // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a 827 // temp, shift-OR it into each alloca address and xor with the retag mask. 828 // This generates one extra instruction per alloca use. 829 for (unsigned N = 0; N < Allocas.size(); ++N) { 830 auto *AI = Allocas[N]; 831 IRBuilder<> IRB(AI->getNextNode()); 832 833 // Replace uses of the alloca with tagged address. 834 Value *Tag = getAllocaTag(IRB, StackTag, AI, N); 835 Value *AILong = IRB.CreatePointerCast(AI, IntptrTy); 836 Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag); 837 std::string Name = 838 AI->hasName() ? AI->getName().str() : "alloca." + itostr(N); 839 Replacement->setName(Name + ".hwasan"); 840 841 for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) { 842 Use &U = *UI++; 843 if (U.getUser() != AILong) 844 U.set(Replacement); 845 } 846 847 tagAlloca(IRB, AI, Tag); 848 849 for (auto RI : RetVec) { 850 IRB.SetInsertPoint(RI); 851 852 // Re-tag alloca memory with the special UAR tag. 853 Value *Tag = getUARTag(IRB, StackTag); 854 tagAlloca(IRB, AI, Tag); 855 } 856 } 857 858 return true; 859 } 860 861 bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) { 862 return (AI.getAllocatedType()->isSized() && 863 // FIXME: instrument dynamic allocas, too 864 AI.isStaticAlloca() && 865 // alloca() may be called with 0 size, ignore it. 866 getAllocaSizeInBytes(AI) > 0 && 867 // We are only interested in allocas not promotable to registers. 868 // Promotable allocas are common under -O0. 869 !isAllocaPromotable(&AI) && 870 // inalloca allocas are not treated as static, and we don't want 871 // dynamic alloca instrumentation for them as well. 872 !AI.isUsedWithInAlloca() && 873 // swifterror allocas are register promoted by ISel 874 !AI.isSwiftError()); 875 } 876 877 bool HWAddressSanitizer::runOnFunction(Function &F) { 878 if (&F == HwasanCtorFunction) 879 return false; 880 881 if (!F.hasFnAttribute(Attribute::SanitizeHWAddress)) 882 return false; 883 884 LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); 885 886 SmallVector<Instruction*, 16> ToInstrument; 887 SmallVector<AllocaInst*, 8> AllocasToInstrument; 888 SmallVector<Instruction*, 8> RetVec; 889 for (auto &BB : F) { 890 for (auto &Inst : BB) { 891 if (ClInstrumentStack) 892 if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) { 893 // Realign all allocas. We don't want small uninteresting allocas to 894 // hide in instrumented alloca's padding. 895 if (AI->getAlignment() < Mapping.getAllocaAlignment()) 896 AI->setAlignment(Mapping.getAllocaAlignment()); 897 // Instrument some of them. 898 if (isInterestingAlloca(*AI)) 899 AllocasToInstrument.push_back(AI); 900 continue; 901 } 902 903 if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst) || 904 isa<CleanupReturnInst>(Inst)) 905 RetVec.push_back(&Inst); 906 907 Value *MaybeMask = nullptr; 908 bool IsWrite; 909 unsigned Alignment; 910 uint64_t TypeSize; 911 Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, 912 &Alignment, &MaybeMask); 913 if (Addr || isa<MemIntrinsic>(Inst)) 914 ToInstrument.push_back(&Inst); 915 } 916 } 917 918 if (AllocasToInstrument.empty() && ToInstrument.empty()) 919 return false; 920 921 if (ClCreateFrameDescriptions && !AllocasToInstrument.empty()) 922 createFrameGlobal(F, createFrameString(AllocasToInstrument)); 923 924 initializeCallbacks(*F.getParent()); 925 926 assert(!LocalDynamicShadow); 927 928 Instruction *InsertPt = &*F.getEntryBlock().begin(); 929 IRBuilder<> EntryIRB(InsertPt); 930 LocalDynamicShadow = emitPrologue(EntryIRB, 931 /*WithFrameRecord*/ ClRecordStackHistory && 932 !AllocasToInstrument.empty()); 933 934 bool Changed = false; 935 if (!AllocasToInstrument.empty()) { 936 Value *StackTag = 937 ClGenerateTagsWithCalls ? nullptr : getStackBaseTag(EntryIRB); 938 Changed |= instrumentStack(AllocasToInstrument, RetVec, StackTag); 939 } 940 941 for (auto Inst : ToInstrument) 942 Changed |= instrumentMemAccess(Inst); 943 944 LocalDynamicShadow = nullptr; 945 946 return Changed; 947 } 948 949 void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) { 950 Scale = kDefaultShadowScale; 951 if (ClMappingOffset.getNumOccurrences() > 0) { 952 InGlobal = false; 953 InTls = false; 954 Offset = ClMappingOffset; 955 } else if (ClEnableKhwasan || ClInstrumentWithCalls) { 956 InGlobal = false; 957 InTls = false; 958 Offset = 0; 959 } else if (ClWithIfunc) { 960 InGlobal = true; 961 InTls = false; 962 Offset = kDynamicShadowSentinel; 963 } else if (ClWithTls) { 964 InGlobal = false; 965 InTls = true; 966 Offset = kDynamicShadowSentinel; 967 } else { 968 InGlobal = false; 969 InTls = false; 970 Offset = kDynamicShadowSentinel; 971 } 972 } 973