AddressSanitizer.cpp revision 3574eca1b02600bac4e625297f4ecf745f4c4f32
1//===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===// 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// This file is a part of AddressSanitizer, an address sanity checker. 11// Details of the algorithm: 12// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 13// 14//===----------------------------------------------------------------------===// 15 16#define DEBUG_TYPE "asan" 17 18#include "BlackList.h" 19#include "llvm/Function.h" 20#include "llvm/IRBuilder.h" 21#include "llvm/InlineAsm.h" 22#include "llvm/IntrinsicInst.h" 23#include "llvm/LLVMContext.h" 24#include "llvm/Module.h" 25#include "llvm/Type.h" 26#include "llvm/ADT/ArrayRef.h" 27#include "llvm/ADT/OwningPtr.h" 28#include "llvm/ADT/SmallSet.h" 29#include "llvm/ADT/SmallString.h" 30#include "llvm/ADT/SmallVector.h" 31#include "llvm/ADT/StringExtras.h" 32#include "llvm/ADT/Triple.h" 33#include "llvm/Support/CommandLine.h" 34#include "llvm/Support/DataTypes.h" 35#include "llvm/Support/Debug.h" 36#include "llvm/Support/raw_ostream.h" 37#include "llvm/Support/system_error.h" 38#include "llvm/DataLayout.h" 39#include "llvm/Target/TargetMachine.h" 40#include "llvm/Transforms/Instrumentation.h" 41#include "llvm/Transforms/Utils/BasicBlockUtils.h" 42#include "llvm/Transforms/Utils/ModuleUtils.h" 43 44#include <string> 45#include <algorithm> 46 47using namespace llvm; 48 49static const uint64_t kDefaultShadowScale = 3; 50static const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 51static const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 52static const uint64_t kDefaultShadowOffsetAndroid = 0; 53 54static const size_t kMaxStackMallocSize = 1 << 16; // 64K 55static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 56static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 57 58static const char *kAsanModuleCtorName = "asan.module_ctor"; 59static const char *kAsanModuleDtorName = "asan.module_dtor"; 60static const int kAsanCtorAndCtorPriority = 1; 61static const char *kAsanReportErrorTemplate = "__asan_report_"; 62static const char *kAsanRegisterGlobalsName = "__asan_register_globals"; 63static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals"; 64static const char *kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 65static const char *kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 66static const char *kAsanInitName = "__asan_init"; 67static const char *kAsanHandleNoReturnName = "__asan_handle_no_return"; 68static const char *kAsanMappingOffsetName = "__asan_mapping_offset"; 69static const char *kAsanMappingScaleName = "__asan_mapping_scale"; 70static const char *kAsanStackMallocName = "__asan_stack_malloc"; 71static const char *kAsanStackFreeName = "__asan_stack_free"; 72 73static const int kAsanStackLeftRedzoneMagic = 0xf1; 74static const int kAsanStackMidRedzoneMagic = 0xf2; 75static const int kAsanStackRightRedzoneMagic = 0xf3; 76static const int kAsanStackPartialRedzoneMagic = 0xf4; 77 78// Accesses sizes are powers of two: 1, 2, 4, 8, 16. 79static const size_t kNumberOfAccessSizes = 5; 80 81// Command-line flags. 82 83// This flag may need to be replaced with -f[no-]asan-reads. 84static cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 85 cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); 86static cl::opt<bool> ClInstrumentWrites("asan-instrument-writes", 87 cl::desc("instrument write instructions"), cl::Hidden, cl::init(true)); 88static cl::opt<bool> ClInstrumentAtomics("asan-instrument-atomics", 89 cl::desc("instrument atomic instructions (rmw, cmpxchg)"), 90 cl::Hidden, cl::init(true)); 91static cl::opt<bool> ClAlwaysSlowPath("asan-always-slow-path", 92 cl::desc("use instrumentation with slow path for all accesses"), 93 cl::Hidden, cl::init(false)); 94// This flag limits the number of instructions to be instrumented 95// in any given BB. Normally, this should be set to unlimited (INT_MAX), 96// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 97// set it to 10000. 98static cl::opt<int> ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", 99 cl::init(10000), 100 cl::desc("maximal number of instructions to instrument in any given BB"), 101 cl::Hidden); 102// This flag may need to be replaced with -f[no]asan-stack. 103static cl::opt<bool> ClStack("asan-stack", 104 cl::desc("Handle stack memory"), cl::Hidden, cl::init(true)); 105// This flag may need to be replaced with -f[no]asan-use-after-return. 106static cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 107 cl::desc("Check return-after-free"), cl::Hidden, cl::init(false)); 108// This flag may need to be replaced with -f[no]asan-globals. 109static cl::opt<bool> ClGlobals("asan-globals", 110 cl::desc("Handle global objects"), cl::Hidden, cl::init(true)); 111static cl::opt<bool> ClInitializers("asan-initialization-order", 112 cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false)); 113static cl::opt<bool> ClMemIntrin("asan-memintrin", 114 cl::desc("Handle memset/memcpy/memmove"), cl::Hidden, cl::init(true)); 115// This flag may need to be replaced with -fasan-blacklist. 116static cl::opt<std::string> ClBlackListFile("asan-blacklist", 117 cl::desc("File containing the list of functions to ignore " 118 "during instrumentation"), cl::Hidden); 119 120// These flags allow to change the shadow mapping. 121// The shadow mapping looks like 122// Shadow = (Mem >> scale) + (1 << offset_log) 123static cl::opt<int> ClMappingScale("asan-mapping-scale", 124 cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); 125static cl::opt<int> ClMappingOffsetLog("asan-mapping-offset-log", 126 cl::desc("offset of asan shadow mapping"), cl::Hidden, cl::init(-1)); 127 128// Optimization flags. Not user visible, used mostly for testing 129// and benchmarking the tool. 130static cl::opt<bool> ClOpt("asan-opt", 131 cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); 132static cl::opt<bool> ClOptSameTemp("asan-opt-same-temp", 133 cl::desc("Instrument the same temp just once"), cl::Hidden, 134 cl::init(true)); 135static cl::opt<bool> ClOptGlobals("asan-opt-globals", 136 cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); 137 138// Debug flags. 139static cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 140 cl::init(0)); 141static cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 142 cl::Hidden, cl::init(0)); 143static cl::opt<std::string> ClDebugFunc("asan-debug-func", 144 cl::Hidden, cl::desc("Debug func")); 145static cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 146 cl::Hidden, cl::init(-1)); 147static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 148 cl::Hidden, cl::init(-1)); 149 150namespace { 151 152/// An object of this type is created while instrumenting every function. 153struct AsanFunctionContext { 154 AsanFunctionContext(Function &Function) : F(Function) { } 155 156 Function &F; 157}; 158 159/// AddressSanitizer: instrument the code in module to find memory bugs. 160struct AddressSanitizer : public ModulePass { 161 AddressSanitizer(); 162 virtual const char *getPassName() const; 163 void instrumentMop(AsanFunctionContext &AFC, Instruction *I); 164 void instrumentAddress(AsanFunctionContext &AFC, 165 Instruction *OrigIns, IRBuilder<> &IRB, 166 Value *Addr, uint32_t TypeSize, bool IsWrite); 167 Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 168 Value *ShadowValue, uint32_t TypeSize); 169 Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 170 bool IsWrite, size_t AccessSizeIndex); 171 bool instrumentMemIntrinsic(AsanFunctionContext &AFC, MemIntrinsic *MI); 172 void instrumentMemIntrinsicParam(AsanFunctionContext &AFC, 173 Instruction *OrigIns, Value *Addr, 174 Value *Size, 175 Instruction *InsertBefore, bool IsWrite); 176 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 177 bool handleFunction(Module &M, Function &F); 178 void createInitializerPoisonCalls(Module &M, 179 Value *FirstAddr, Value *LastAddr); 180 bool maybeInsertAsanInitAtFunctionEntry(Function &F); 181 bool poisonStackInFunction(Module &M, Function &F); 182 virtual bool runOnModule(Module &M); 183 bool insertGlobalRedzones(Module &M); 184 static char ID; // Pass identification, replacement for typeid 185 186 private: 187 uint64_t getAllocaSizeInBytes(AllocaInst *AI) { 188 Type *Ty = AI->getAllocatedType(); 189 uint64_t SizeInBytes = TD->getTypeAllocSize(Ty); 190 return SizeInBytes; 191 } 192 uint64_t getAlignedSize(uint64_t SizeInBytes) { 193 return ((SizeInBytes + RedzoneSize - 1) 194 / RedzoneSize) * RedzoneSize; 195 } 196 uint64_t getAlignedAllocaSize(AllocaInst *AI) { 197 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 198 return getAlignedSize(SizeInBytes); 199 } 200 201 Function *checkInterfaceFunction(Constant *FuncOrBitcast); 202 bool ShouldInstrumentGlobal(GlobalVariable *G); 203 void PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> IRB, 204 Value *ShadowBase, bool DoPoison); 205 bool LooksLikeCodeInBug11395(Instruction *I); 206 void FindDynamicInitializers(Module &M); 207 bool HasDynamicInitializer(GlobalVariable *G); 208 209 LLVMContext *C; 210 DataLayout *TD; 211 uint64_t MappingOffset; 212 int MappingScale; 213 size_t RedzoneSize; 214 int LongSize; 215 Type *IntptrTy; 216 Type *IntptrPtrTy; 217 Function *AsanCtorFunction; 218 Function *AsanInitFunction; 219 Instruction *CtorInsertBefore; 220 OwningPtr<BlackList> BL; 221 // This array is indexed by AccessIsWrite and log2(AccessSize). 222 Function *AsanErrorCallback[2][kNumberOfAccessSizes]; 223 InlineAsm *EmptyAsm; 224 SmallSet<GlobalValue*, 32> DynamicallyInitializedGlobals; 225}; 226 227} // namespace 228 229char AddressSanitizer::ID = 0; 230INITIALIZE_PASS(AddressSanitizer, "asan", 231 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 232 false, false) 233AddressSanitizer::AddressSanitizer() : ModulePass(ID) { } 234ModulePass *llvm::createAddressSanitizerPass() { 235 return new AddressSanitizer(); 236} 237 238const char *AddressSanitizer::getPassName() const { 239 return "AddressSanitizer"; 240} 241 242static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 243 size_t Res = CountTrailingZeros_32(TypeSize / 8); 244 assert(Res < kNumberOfAccessSizes); 245 return Res; 246} 247 248// Create a constant for Str so that we can pass it to the run-time lib. 249static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) { 250 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 251 return new GlobalVariable(M, StrConst->getType(), true, 252 GlobalValue::PrivateLinkage, StrConst, ""); 253} 254 255// Split the basic block and insert an if-then code. 256// Before: 257// Head 258// Cmp 259// Tail 260// After: 261// Head 262// if (Cmp) 263// ThenBlock 264// Tail 265// 266// ThenBlock block is created and its terminator is returned. 267// If Unreachable, ThenBlock is terminated with UnreachableInst, otherwise 268// it is terminated with BranchInst to Tail. 269static TerminatorInst *splitBlockAndInsertIfThen(Value *Cmp, bool Unreachable) { 270 Instruction *SplitBefore = cast<Instruction>(Cmp)->getNextNode(); 271 BasicBlock *Head = SplitBefore->getParent(); 272 BasicBlock *Tail = Head->splitBasicBlock(SplitBefore); 273 TerminatorInst *HeadOldTerm = Head->getTerminator(); 274 LLVMContext &C = Head->getParent()->getParent()->getContext(); 275 BasicBlock *ThenBlock = BasicBlock::Create(C, "", Head->getParent(), Tail); 276 TerminatorInst *CheckTerm; 277 if (Unreachable) 278 CheckTerm = new UnreachableInst(C, ThenBlock); 279 else 280 CheckTerm = BranchInst::Create(Tail, ThenBlock); 281 BranchInst *HeadNewTerm = 282 BranchInst::Create(/*ifTrue*/ThenBlock, /*ifFalse*/Tail, Cmp); 283 ReplaceInstWithInst(HeadOldTerm, HeadNewTerm); 284 return CheckTerm; 285} 286 287Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 288 // Shadow >> scale 289 Shadow = IRB.CreateLShr(Shadow, MappingScale); 290 if (MappingOffset == 0) 291 return Shadow; 292 // (Shadow >> scale) | offset 293 return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, 294 MappingOffset)); 295} 296 297void AddressSanitizer::instrumentMemIntrinsicParam( 298 AsanFunctionContext &AFC, Instruction *OrigIns, 299 Value *Addr, Value *Size, Instruction *InsertBefore, bool IsWrite) { 300 // Check the first byte. 301 { 302 IRBuilder<> IRB(InsertBefore); 303 instrumentAddress(AFC, OrigIns, IRB, Addr, 8, IsWrite); 304 } 305 // Check the last byte. 306 { 307 IRBuilder<> IRB(InsertBefore); 308 Value *SizeMinusOne = IRB.CreateSub( 309 Size, ConstantInt::get(Size->getType(), 1)); 310 SizeMinusOne = IRB.CreateIntCast(SizeMinusOne, IntptrTy, false); 311 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 312 Value *AddrPlusSizeMinisOne = IRB.CreateAdd(AddrLong, SizeMinusOne); 313 instrumentAddress(AFC, OrigIns, IRB, AddrPlusSizeMinisOne, 8, IsWrite); 314 } 315} 316 317// Instrument memset/memmove/memcpy 318bool AddressSanitizer::instrumentMemIntrinsic(AsanFunctionContext &AFC, 319 MemIntrinsic *MI) { 320 Value *Dst = MI->getDest(); 321 MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI); 322 Value *Src = MemTran ? MemTran->getSource() : 0; 323 Value *Length = MI->getLength(); 324 325 Constant *ConstLength = dyn_cast<Constant>(Length); 326 Instruction *InsertBefore = MI; 327 if (ConstLength) { 328 if (ConstLength->isNullValue()) return false; 329 } else { 330 // The size is not a constant so it could be zero -- check at run-time. 331 IRBuilder<> IRB(InsertBefore); 332 333 Value *Cmp = IRB.CreateICmpNE(Length, 334 Constant::getNullValue(Length->getType())); 335 InsertBefore = splitBlockAndInsertIfThen(Cmp, false); 336 } 337 338 instrumentMemIntrinsicParam(AFC, MI, Dst, Length, InsertBefore, true); 339 if (Src) 340 instrumentMemIntrinsicParam(AFC, MI, Src, Length, InsertBefore, false); 341 return true; 342} 343 344// If I is an interesting memory access, return the PointerOperand 345// and set IsWrite. Otherwise return NULL. 346static Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite) { 347 if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 348 if (!ClInstrumentReads) return NULL; 349 *IsWrite = false; 350 return LI->getPointerOperand(); 351 } 352 if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 353 if (!ClInstrumentWrites) return NULL; 354 *IsWrite = true; 355 return SI->getPointerOperand(); 356 } 357 if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 358 if (!ClInstrumentAtomics) return NULL; 359 *IsWrite = true; 360 return RMW->getPointerOperand(); 361 } 362 if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 363 if (!ClInstrumentAtomics) return NULL; 364 *IsWrite = true; 365 return XCHG->getPointerOperand(); 366 } 367 return NULL; 368} 369 370void AddressSanitizer::FindDynamicInitializers(Module& M) { 371 // Clang generates metadata identifying all dynamically initialized globals. 372 NamedMDNode *DynamicGlobals = 373 M.getNamedMetadata("llvm.asan.dynamically_initialized_globals"); 374 if (!DynamicGlobals) 375 return; 376 for (int i = 0, n = DynamicGlobals->getNumOperands(); i < n; ++i) { 377 MDNode *MDN = DynamicGlobals->getOperand(i); 378 assert(MDN->getNumOperands() == 1); 379 Value *VG = MDN->getOperand(0); 380 // The optimizer may optimize away a global entirely, in which case we 381 // cannot instrument access to it. 382 if (!VG) 383 continue; 384 385 GlobalVariable *G = cast<GlobalVariable>(VG); 386 DynamicallyInitializedGlobals.insert(G); 387 } 388} 389// Returns true if a global variable is initialized dynamically in this TU. 390bool AddressSanitizer::HasDynamicInitializer(GlobalVariable *G) { 391 return DynamicallyInitializedGlobals.count(G); 392} 393 394void AddressSanitizer::instrumentMop(AsanFunctionContext &AFC, Instruction *I) { 395 bool IsWrite = false; 396 Value *Addr = isInterestingMemoryAccess(I, &IsWrite); 397 assert(Addr); 398 if (ClOpt && ClOptGlobals) { 399 if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) { 400 // If initialization order checking is disabled, a simple access to a 401 // dynamically initialized global is always valid. 402 if (!ClInitializers) 403 return; 404 // If a global variable does not have dynamic initialization we don't 405 // have to instrument it. However, if a global has external linkage, we 406 // assume it has dynamic initialization, as it may have an initializer 407 // in a different TU. 408 if (G->getLinkage() != GlobalVariable::ExternalLinkage && 409 !HasDynamicInitializer(G)) 410 return; 411 } 412 } 413 414 Type *OrigPtrTy = Addr->getType(); 415 Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); 416 417 assert(OrigTy->isSized()); 418 uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy); 419 420 if (TypeSize != 8 && TypeSize != 16 && 421 TypeSize != 32 && TypeSize != 64 && TypeSize != 128) { 422 // Ignore all unusual sizes. 423 return; 424 } 425 426 IRBuilder<> IRB(I); 427 instrumentAddress(AFC, I, IRB, Addr, TypeSize, IsWrite); 428} 429 430// Validate the result of Module::getOrInsertFunction called for an interface 431// function of AddressSanitizer. If the instrumented module defines a function 432// with the same name, their prototypes must match, otherwise 433// getOrInsertFunction returns a bitcast. 434Function *AddressSanitizer::checkInterfaceFunction(Constant *FuncOrBitcast) { 435 if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); 436 FuncOrBitcast->dump(); 437 report_fatal_error("trying to redefine an AddressSanitizer " 438 "interface function"); 439} 440 441Instruction *AddressSanitizer::generateCrashCode( 442 Instruction *InsertBefore, Value *Addr, 443 bool IsWrite, size_t AccessSizeIndex) { 444 IRBuilder<> IRB(InsertBefore); 445 CallInst *Call = IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex], 446 Addr); 447 // We don't do Call->setDoesNotReturn() because the BB already has 448 // UnreachableInst at the end. 449 // This EmptyAsm is required to avoid callback merge. 450 IRB.CreateCall(EmptyAsm); 451 return Call; 452} 453 454Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 455 Value *ShadowValue, 456 uint32_t TypeSize) { 457 size_t Granularity = 1 << MappingScale; 458 // Addr & (Granularity - 1) 459 Value *LastAccessedByte = IRB.CreateAnd( 460 AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 461 // (Addr & (Granularity - 1)) + size - 1 462 if (TypeSize / 8 > 1) 463 LastAccessedByte = IRB.CreateAdd( 464 LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 465 // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 466 LastAccessedByte = IRB.CreateIntCast( 467 LastAccessedByte, ShadowValue->getType(), false); 468 // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 469 return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 470} 471 472void AddressSanitizer::instrumentAddress(AsanFunctionContext &AFC, 473 Instruction *OrigIns, 474 IRBuilder<> &IRB, Value *Addr, 475 uint32_t TypeSize, bool IsWrite) { 476 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 477 478 Type *ShadowTy = IntegerType::get( 479 *C, std::max(8U, TypeSize >> MappingScale)); 480 Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 481 Value *ShadowPtr = memToShadow(AddrLong, IRB); 482 Value *CmpVal = Constant::getNullValue(ShadowTy); 483 Value *ShadowValue = IRB.CreateLoad( 484 IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 485 486 Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 487 size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 488 size_t Granularity = 1 << MappingScale; 489 TerminatorInst *CrashTerm = 0; 490 491 if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 492 TerminatorInst *CheckTerm = splitBlockAndInsertIfThen(Cmp, false); 493 assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional()); 494 BasicBlock *NextBB = CheckTerm->getSuccessor(0); 495 IRB.SetInsertPoint(CheckTerm); 496 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 497 BasicBlock *CrashBlock = BasicBlock::Create(*C, "", &AFC.F, NextBB); 498 CrashTerm = new UnreachableInst(*C, CrashBlock); 499 BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 500 ReplaceInstWithInst(CheckTerm, NewTerm); 501 } else { 502 CrashTerm = splitBlockAndInsertIfThen(Cmp, true); 503 } 504 505 Instruction *Crash = 506 generateCrashCode(CrashTerm, AddrLong, IsWrite, AccessSizeIndex); 507 Crash->setDebugLoc(OrigIns->getDebugLoc()); 508} 509 510void AddressSanitizer::createInitializerPoisonCalls(Module &M, 511 Value *FirstAddr, 512 Value *LastAddr) { 513 // We do all of our poisoning and unpoisoning within _GLOBAL__I_a. 514 Function *GlobalInit = M.getFunction("_GLOBAL__I_a"); 515 // If that function is not present, this TU contains no globals, or they have 516 // all been optimized away 517 if (!GlobalInit) 518 return; 519 520 // Set up the arguments to our poison/unpoison functions. 521 IRBuilder<> IRB(GlobalInit->begin()->getFirstInsertionPt()); 522 523 // Declare our poisoning and unpoisoning functions. 524 Function *AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 525 kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 526 AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 527 Function *AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 528 kAsanUnpoisonGlobalsName, IRB.getVoidTy(), NULL)); 529 AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 530 531 // Add a call to poison all external globals before the given function starts. 532 IRB.CreateCall2(AsanPoisonGlobals, FirstAddr, LastAddr); 533 534 // Add calls to unpoison all globals before each return instruction. 535 for (Function::iterator I = GlobalInit->begin(), E = GlobalInit->end(); 536 I != E; ++I) { 537 if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator())) { 538 CallInst::Create(AsanUnpoisonGlobals, "", RI); 539 } 540 } 541} 542 543bool AddressSanitizer::ShouldInstrumentGlobal(GlobalVariable *G) { 544 Type *Ty = cast<PointerType>(G->getType())->getElementType(); 545 DEBUG(dbgs() << "GLOBAL: " << *G); 546 547 if (BL->isIn(*G)) return false; 548 if (!Ty->isSized()) return false; 549 if (!G->hasInitializer()) return false; 550 // Touch only those globals that will not be defined in other modules. 551 // Don't handle ODR type linkages since other modules may be built w/o asan. 552 if (G->getLinkage() != GlobalVariable::ExternalLinkage && 553 G->getLinkage() != GlobalVariable::PrivateLinkage && 554 G->getLinkage() != GlobalVariable::InternalLinkage) 555 return false; 556 // Two problems with thread-locals: 557 // - The address of the main thread's copy can't be computed at link-time. 558 // - Need to poison all copies, not just the main thread's one. 559 if (G->isThreadLocal()) 560 return false; 561 // For now, just ignore this Alloca if the alignment is large. 562 if (G->getAlignment() > RedzoneSize) return false; 563 564 // Ignore all the globals with the names starting with "\01L_OBJC_". 565 // Many of those are put into the .cstring section. The linker compresses 566 // that section by removing the spare \0s after the string terminator, so 567 // our redzones get broken. 568 if ((G->getName().find("\01L_OBJC_") == 0) || 569 (G->getName().find("\01l_OBJC_") == 0)) { 570 DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G); 571 return false; 572 } 573 574 if (G->hasSection()) { 575 StringRef Section(G->getSection()); 576 // Ignore the globals from the __OBJC section. The ObjC runtime assumes 577 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 578 // them. 579 if ((Section.find("__OBJC,") == 0) || 580 (Section.find("__DATA, __objc_") == 0)) { 581 DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G); 582 return false; 583 } 584 // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 585 // Constant CFString instances are compiled in the following way: 586 // -- the string buffer is emitted into 587 // __TEXT,__cstring,cstring_literals 588 // -- the constant NSConstantString structure referencing that buffer 589 // is placed into __DATA,__cfstring 590 // Therefore there's no point in placing redzones into __DATA,__cfstring. 591 // Moreover, it causes the linker to crash on OS X 10.7 592 if (Section.find("__DATA,__cfstring") == 0) { 593 DEBUG(dbgs() << "Ignoring CFString: " << *G); 594 return false; 595 } 596 } 597 598 return true; 599} 600 601// This function replaces all global variables with new variables that have 602// trailing redzones. It also creates a function that poisons 603// redzones and inserts this function into llvm.global_ctors. 604bool AddressSanitizer::insertGlobalRedzones(Module &M) { 605 SmallVector<GlobalVariable *, 16> GlobalsToChange; 606 607 for (Module::GlobalListType::iterator G = M.global_begin(), 608 E = M.global_end(); G != E; ++G) { 609 if (ShouldInstrumentGlobal(G)) 610 GlobalsToChange.push_back(G); 611 } 612 613 size_t n = GlobalsToChange.size(); 614 if (n == 0) return false; 615 616 // A global is described by a structure 617 // size_t beg; 618 // size_t size; 619 // size_t size_with_redzone; 620 // const char *name; 621 // size_t has_dynamic_init; 622 // We initialize an array of such structures and pass it to a run-time call. 623 StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy, 624 IntptrTy, IntptrTy, 625 IntptrTy, NULL); 626 SmallVector<Constant *, 16> Initializers(n), DynamicInit; 627 628 IRBuilder<> IRB(CtorInsertBefore); 629 630 if (ClInitializers) 631 FindDynamicInitializers(M); 632 633 // The addresses of the first and last dynamically initialized globals in 634 // this TU. Used in initialization order checking. 635 Value *FirstDynamic = 0, *LastDynamic = 0; 636 637 for (size_t i = 0; i < n; i++) { 638 GlobalVariable *G = GlobalsToChange[i]; 639 PointerType *PtrTy = cast<PointerType>(G->getType()); 640 Type *Ty = PtrTy->getElementType(); 641 uint64_t SizeInBytes = TD->getTypeAllocSize(Ty); 642 uint64_t RightRedzoneSize = RedzoneSize + 643 (RedzoneSize - (SizeInBytes % RedzoneSize)); 644 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 645 // Determine whether this global should be poisoned in initialization. 646 bool GlobalHasDynamicInitializer = HasDynamicInitializer(G); 647 // Don't check initialization order if this global is blacklisted. 648 GlobalHasDynamicInitializer &= !BL->isInInit(*G); 649 650 StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL); 651 Constant *NewInitializer = ConstantStruct::get( 652 NewTy, G->getInitializer(), 653 Constant::getNullValue(RightRedZoneTy), NULL); 654 655 SmallString<2048> DescriptionOfGlobal = G->getName(); 656 DescriptionOfGlobal += " ("; 657 DescriptionOfGlobal += M.getModuleIdentifier(); 658 DescriptionOfGlobal += ")"; 659 GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal); 660 661 // Create a new global variable with enough space for a redzone. 662 GlobalVariable *NewGlobal = new GlobalVariable( 663 M, NewTy, G->isConstant(), G->getLinkage(), 664 NewInitializer, "", G, G->getThreadLocalMode()); 665 NewGlobal->copyAttributesFrom(G); 666 NewGlobal->setAlignment(RedzoneSize); 667 668 Value *Indices2[2]; 669 Indices2[0] = IRB.getInt32(0); 670 Indices2[1] = IRB.getInt32(0); 671 672 G->replaceAllUsesWith( 673 ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); 674 NewGlobal->takeName(G); 675 G->eraseFromParent(); 676 677 Initializers[i] = ConstantStruct::get( 678 GlobalStructTy, 679 ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 680 ConstantInt::get(IntptrTy, SizeInBytes), 681 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 682 ConstantExpr::getPointerCast(Name, IntptrTy), 683 ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer), 684 NULL); 685 686 // Populate the first and last globals declared in this TU. 687 if (ClInitializers && GlobalHasDynamicInitializer) { 688 LastDynamic = ConstantExpr::getPointerCast(NewGlobal, IntptrTy); 689 if (FirstDynamic == 0) 690 FirstDynamic = LastDynamic; 691 } 692 693 DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal); 694 } 695 696 ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 697 GlobalVariable *AllGlobals = new GlobalVariable( 698 M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage, 699 ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 700 701 // Create calls for poisoning before initializers run and unpoisoning after. 702 if (ClInitializers && FirstDynamic && LastDynamic) 703 createInitializerPoisonCalls(M, FirstDynamic, LastDynamic); 704 705 Function *AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 706 kAsanRegisterGlobalsName, IRB.getVoidTy(), 707 IntptrTy, IntptrTy, NULL)); 708 AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 709 710 IRB.CreateCall2(AsanRegisterGlobals, 711 IRB.CreatePointerCast(AllGlobals, IntptrTy), 712 ConstantInt::get(IntptrTy, n)); 713 714 // We also need to unregister globals at the end, e.g. when a shared library 715 // gets closed. 716 Function *AsanDtorFunction = Function::Create( 717 FunctionType::get(Type::getVoidTy(*C), false), 718 GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 719 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 720 IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 721 Function *AsanUnregisterGlobals = 722 checkInterfaceFunction(M.getOrInsertFunction( 723 kAsanUnregisterGlobalsName, 724 IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 725 AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 726 727 IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 728 IRB.CreatePointerCast(AllGlobals, IntptrTy), 729 ConstantInt::get(IntptrTy, n)); 730 appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority); 731 732 DEBUG(dbgs() << M); 733 return true; 734} 735 736// virtual 737bool AddressSanitizer::runOnModule(Module &M) { 738 // Initialize the private fields. No one has accessed them before. 739 TD = getAnalysisIfAvailable<DataLayout>(); 740 if (!TD) 741 return false; 742 BL.reset(new BlackList(ClBlackListFile)); 743 744 C = &(M.getContext()); 745 LongSize = TD->getPointerSizeInBits(); 746 IntptrTy = Type::getIntNTy(*C, LongSize); 747 IntptrPtrTy = PointerType::get(IntptrTy, 0); 748 749 AsanCtorFunction = Function::Create( 750 FunctionType::get(Type::getVoidTy(*C), false), 751 GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 752 BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 753 CtorInsertBefore = ReturnInst::Create(*C, AsanCtorBB); 754 755 // call __asan_init in the module ctor. 756 IRBuilder<> IRB(CtorInsertBefore); 757 AsanInitFunction = checkInterfaceFunction( 758 M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), NULL)); 759 AsanInitFunction->setLinkage(Function::ExternalLinkage); 760 IRB.CreateCall(AsanInitFunction); 761 762 // Create __asan_report* callbacks. 763 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 764 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 765 AccessSizeIndex++) { 766 // IsWrite and TypeSize are encoded in the function name. 767 std::string FunctionName = std::string(kAsanReportErrorTemplate) + 768 (AccessIsWrite ? "store" : "load") + itostr(1 << AccessSizeIndex); 769 // If we are merging crash callbacks, they have two parameters. 770 AsanErrorCallback[AccessIsWrite][AccessSizeIndex] = cast<Function>( 771 M.getOrInsertFunction(FunctionName, IRB.getVoidTy(), IntptrTy, NULL)); 772 } 773 } 774 // We insert an empty inline asm after __asan_report* to avoid callback merge. 775 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 776 StringRef(""), StringRef(""), 777 /*hasSideEffects=*/true); 778 779 llvm::Triple targetTriple(M.getTargetTriple()); 780 bool isAndroid = targetTriple.getEnvironment() == llvm::Triple::Android; 781 782 MappingOffset = isAndroid ? kDefaultShadowOffsetAndroid : 783 (LongSize == 32 ? kDefaultShadowOffset32 : kDefaultShadowOffset64); 784 if (ClMappingOffsetLog >= 0) { 785 if (ClMappingOffsetLog == 0) { 786 // special case 787 MappingOffset = 0; 788 } else { 789 MappingOffset = 1ULL << ClMappingOffsetLog; 790 } 791 } 792 MappingScale = kDefaultShadowScale; 793 if (ClMappingScale) { 794 MappingScale = ClMappingScale; 795 } 796 // Redzone used for stack and globals is at least 32 bytes. 797 // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 798 RedzoneSize = std::max(32, (int)(1 << MappingScale)); 799 800 bool Res = false; 801 802 if (ClGlobals) 803 Res |= insertGlobalRedzones(M); 804 805 if (ClMappingOffsetLog >= 0) { 806 // Tell the run-time the current values of mapping offset and scale. 807 GlobalValue *asan_mapping_offset = 808 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 809 ConstantInt::get(IntptrTy, MappingOffset), 810 kAsanMappingOffsetName); 811 // Read the global, otherwise it may be optimized away. 812 IRB.CreateLoad(asan_mapping_offset, true); 813 } 814 if (ClMappingScale) { 815 GlobalValue *asan_mapping_scale = 816 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 817 ConstantInt::get(IntptrTy, MappingScale), 818 kAsanMappingScaleName); 819 // Read the global, otherwise it may be optimized away. 820 IRB.CreateLoad(asan_mapping_scale, true); 821 } 822 823 824 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 825 if (F->isDeclaration()) continue; 826 Res |= handleFunction(M, *F); 827 } 828 829 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndCtorPriority); 830 831 return Res; 832} 833 834bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 835 // For each NSObject descendant having a +load method, this method is invoked 836 // by the ObjC runtime before any of the static constructors is called. 837 // Therefore we need to instrument such methods with a call to __asan_init 838 // at the beginning in order to initialize our runtime before any access to 839 // the shadow memory. 840 // We cannot just ignore these methods, because they may call other 841 // instrumented functions. 842 if (F.getName().find(" load]") != std::string::npos) { 843 IRBuilder<> IRB(F.begin()->begin()); 844 IRB.CreateCall(AsanInitFunction); 845 return true; 846 } 847 return false; 848} 849 850bool AddressSanitizer::handleFunction(Module &M, Function &F) { 851 if (BL->isIn(F)) return false; 852 if (&F == AsanCtorFunction) return false; 853 854 // If needed, insert __asan_init before checking for AddressSafety attr. 855 maybeInsertAsanInitAtFunctionEntry(F); 856 857 if (!F.getFnAttributes().hasAddressSafetyAttr()) return false; 858 859 if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) 860 return false; 861 // We want to instrument every address only once per basic block 862 // (unless there are calls between uses). 863 SmallSet<Value*, 16> TempsToInstrument; 864 SmallVector<Instruction*, 16> ToInstrument; 865 SmallVector<Instruction*, 8> NoReturnCalls; 866 bool IsWrite; 867 868 // Fill the set of memory operations to instrument. 869 for (Function::iterator FI = F.begin(), FE = F.end(); 870 FI != FE; ++FI) { 871 TempsToInstrument.clear(); 872 int NumInsnsPerBB = 0; 873 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 874 BI != BE; ++BI) { 875 if (LooksLikeCodeInBug11395(BI)) return false; 876 if (Value *Addr = isInterestingMemoryAccess(BI, &IsWrite)) { 877 if (ClOpt && ClOptSameTemp) { 878 if (!TempsToInstrument.insert(Addr)) 879 continue; // We've seen this temp in the current BB. 880 } 881 } else if (isa<MemIntrinsic>(BI) && ClMemIntrin) { 882 // ok, take it. 883 } else { 884 if (CallInst *CI = dyn_cast<CallInst>(BI)) { 885 // A call inside BB. 886 TempsToInstrument.clear(); 887 if (CI->doesNotReturn()) { 888 NoReturnCalls.push_back(CI); 889 } 890 } 891 continue; 892 } 893 ToInstrument.push_back(BI); 894 NumInsnsPerBB++; 895 if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) 896 break; 897 } 898 } 899 900 AsanFunctionContext AFC(F); 901 902 // Instrument. 903 int NumInstrumented = 0; 904 for (size_t i = 0, n = ToInstrument.size(); i != n; i++) { 905 Instruction *Inst = ToInstrument[i]; 906 if (ClDebugMin < 0 || ClDebugMax < 0 || 907 (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 908 if (isInterestingMemoryAccess(Inst, &IsWrite)) 909 instrumentMop(AFC, Inst); 910 else 911 instrumentMemIntrinsic(AFC, cast<MemIntrinsic>(Inst)); 912 } 913 NumInstrumented++; 914 } 915 916 DEBUG(dbgs() << F); 917 918 bool ChangedStack = poisonStackInFunction(M, F); 919 920 // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 921 // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 922 for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) { 923 Instruction *CI = NoReturnCalls[i]; 924 IRBuilder<> IRB(CI); 925 IRB.CreateCall(M.getOrInsertFunction(kAsanHandleNoReturnName, 926 IRB.getVoidTy(), NULL)); 927 } 928 929 return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 930} 931 932static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) { 933 if (ShadowRedzoneSize == 1) return PoisonByte; 934 if (ShadowRedzoneSize == 2) return (PoisonByte << 8) + PoisonByte; 935 if (ShadowRedzoneSize == 4) 936 return (PoisonByte << 24) + (PoisonByte << 16) + 937 (PoisonByte << 8) + (PoisonByte); 938 llvm_unreachable("ShadowRedzoneSize is either 1, 2 or 4"); 939} 940 941static void PoisonShadowPartialRightRedzone(uint8_t *Shadow, 942 size_t Size, 943 size_t RedzoneSize, 944 size_t ShadowGranularity, 945 uint8_t Magic) { 946 for (size_t i = 0; i < RedzoneSize; 947 i+= ShadowGranularity, Shadow++) { 948 if (i + ShadowGranularity <= Size) { 949 *Shadow = 0; // fully addressable 950 } else if (i >= Size) { 951 *Shadow = Magic; // unaddressable 952 } else { 953 *Shadow = Size - i; // first Size-i bytes are addressable 954 } 955 } 956} 957 958void AddressSanitizer::PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec, 959 IRBuilder<> IRB, 960 Value *ShadowBase, bool DoPoison) { 961 size_t ShadowRZSize = RedzoneSize >> MappingScale; 962 assert(ShadowRZSize >= 1 && ShadowRZSize <= 4); 963 Type *RZTy = Type::getIntNTy(*C, ShadowRZSize * 8); 964 Type *RZPtrTy = PointerType::get(RZTy, 0); 965 966 Value *PoisonLeft = ConstantInt::get(RZTy, 967 ValueForPoison(DoPoison ? kAsanStackLeftRedzoneMagic : 0LL, ShadowRZSize)); 968 Value *PoisonMid = ConstantInt::get(RZTy, 969 ValueForPoison(DoPoison ? kAsanStackMidRedzoneMagic : 0LL, ShadowRZSize)); 970 Value *PoisonRight = ConstantInt::get(RZTy, 971 ValueForPoison(DoPoison ? kAsanStackRightRedzoneMagic : 0LL, ShadowRZSize)); 972 973 // poison the first red zone. 974 IRB.CreateStore(PoisonLeft, IRB.CreateIntToPtr(ShadowBase, RZPtrTy)); 975 976 // poison all other red zones. 977 uint64_t Pos = RedzoneSize; 978 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 979 AllocaInst *AI = AllocaVec[i]; 980 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 981 uint64_t AlignedSize = getAlignedAllocaSize(AI); 982 assert(AlignedSize - SizeInBytes < RedzoneSize); 983 Value *Ptr = NULL; 984 985 Pos += AlignedSize; 986 987 assert(ShadowBase->getType() == IntptrTy); 988 if (SizeInBytes < AlignedSize) { 989 // Poison the partial redzone at right 990 Ptr = IRB.CreateAdd( 991 ShadowBase, ConstantInt::get(IntptrTy, 992 (Pos >> MappingScale) - ShadowRZSize)); 993 size_t AddressableBytes = RedzoneSize - (AlignedSize - SizeInBytes); 994 uint32_t Poison = 0; 995 if (DoPoison) { 996 PoisonShadowPartialRightRedzone((uint8_t*)&Poison, AddressableBytes, 997 RedzoneSize, 998 1ULL << MappingScale, 999 kAsanStackPartialRedzoneMagic); 1000 } 1001 Value *PartialPoison = ConstantInt::get(RZTy, Poison); 1002 IRB.CreateStore(PartialPoison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 1003 } 1004 1005 // Poison the full redzone at right. 1006 Ptr = IRB.CreateAdd(ShadowBase, 1007 ConstantInt::get(IntptrTy, Pos >> MappingScale)); 1008 Value *Poison = i == AllocaVec.size() - 1 ? PoisonRight : PoisonMid; 1009 IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 1010 1011 Pos += RedzoneSize; 1012 } 1013} 1014 1015// Workaround for bug 11395: we don't want to instrument stack in functions 1016// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 1017// FIXME: remove once the bug 11395 is fixed. 1018bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 1019 if (LongSize != 32) return false; 1020 CallInst *CI = dyn_cast<CallInst>(I); 1021 if (!CI || !CI->isInlineAsm()) return false; 1022 if (CI->getNumArgOperands() <= 5) return false; 1023 // We have inline assembly with quite a few arguments. 1024 return true; 1025} 1026 1027// Find all static Alloca instructions and put 1028// poisoned red zones around all of them. 1029// Then unpoison everything back before the function returns. 1030// 1031// Stack poisoning does not play well with exception handling. 1032// When an exception is thrown, we essentially bypass the code 1033// that unpoisones the stack. This is why the run-time library has 1034// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 1035// stack in the interceptor. This however does not work inside the 1036// actual function which catches the exception. Most likely because the 1037// compiler hoists the load of the shadow value somewhere too high. 1038// This causes asan to report a non-existing bug on 453.povray. 1039// It sounds like an LLVM bug. 1040bool AddressSanitizer::poisonStackInFunction(Module &M, Function &F) { 1041 if (!ClStack) return false; 1042 SmallVector<AllocaInst*, 16> AllocaVec; 1043 SmallVector<Instruction*, 8> RetVec; 1044 uint64_t TotalSize = 0; 1045 1046 // Filter out Alloca instructions we want (and can) handle. 1047 // Collect Ret instructions. 1048 for (Function::iterator FI = F.begin(), FE = F.end(); 1049 FI != FE; ++FI) { 1050 BasicBlock &BB = *FI; 1051 for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); 1052 BI != BE; ++BI) { 1053 if (isa<ReturnInst>(BI)) { 1054 RetVec.push_back(BI); 1055 continue; 1056 } 1057 1058 AllocaInst *AI = dyn_cast<AllocaInst>(BI); 1059 if (!AI) continue; 1060 if (AI->isArrayAllocation()) continue; 1061 if (!AI->isStaticAlloca()) continue; 1062 if (!AI->getAllocatedType()->isSized()) continue; 1063 if (AI->getAlignment() > RedzoneSize) continue; 1064 AllocaVec.push_back(AI); 1065 uint64_t AlignedSize = getAlignedAllocaSize(AI); 1066 TotalSize += AlignedSize; 1067 } 1068 } 1069 1070 if (AllocaVec.empty()) return false; 1071 1072 uint64_t LocalStackSize = TotalSize + (AllocaVec.size() + 1) * RedzoneSize; 1073 1074 bool DoStackMalloc = ClUseAfterReturn 1075 && LocalStackSize <= kMaxStackMallocSize; 1076 1077 Instruction *InsBefore = AllocaVec[0]; 1078 IRBuilder<> IRB(InsBefore); 1079 1080 1081 Type *ByteArrayTy = ArrayType::get(IRB.getInt8Ty(), LocalStackSize); 1082 AllocaInst *MyAlloca = 1083 new AllocaInst(ByteArrayTy, "MyAlloca", InsBefore); 1084 MyAlloca->setAlignment(RedzoneSize); 1085 assert(MyAlloca->isStaticAlloca()); 1086 Value *OrigStackBase = IRB.CreatePointerCast(MyAlloca, IntptrTy); 1087 Value *LocalStackBase = OrigStackBase; 1088 1089 if (DoStackMalloc) { 1090 Value *AsanStackMallocFunc = M.getOrInsertFunction( 1091 kAsanStackMallocName, IntptrTy, IntptrTy, IntptrTy, NULL); 1092 LocalStackBase = IRB.CreateCall2(AsanStackMallocFunc, 1093 ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase); 1094 } 1095 1096 // This string will be parsed by the run-time (DescribeStackAddress). 1097 SmallString<2048> StackDescriptionStorage; 1098 raw_svector_ostream StackDescription(StackDescriptionStorage); 1099 StackDescription << F.getName() << " " << AllocaVec.size() << " "; 1100 1101 uint64_t Pos = RedzoneSize; 1102 // Replace Alloca instructions with base+offset. 1103 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 1104 AllocaInst *AI = AllocaVec[i]; 1105 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 1106 StringRef Name = AI->getName(); 1107 StackDescription << Pos << " " << SizeInBytes << " " 1108 << Name.size() << " " << Name << " "; 1109 uint64_t AlignedSize = getAlignedAllocaSize(AI); 1110 assert((AlignedSize % RedzoneSize) == 0); 1111 AI->replaceAllUsesWith( 1112 IRB.CreateIntToPtr( 1113 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Pos)), 1114 AI->getType())); 1115 Pos += AlignedSize + RedzoneSize; 1116 } 1117 assert(Pos == LocalStackSize); 1118 1119 // Write the Magic value and the frame description constant to the redzone. 1120 Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 1121 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 1122 BasePlus0); 1123 Value *BasePlus1 = IRB.CreateAdd(LocalStackBase, 1124 ConstantInt::get(IntptrTy, LongSize/8)); 1125 BasePlus1 = IRB.CreateIntToPtr(BasePlus1, IntptrPtrTy); 1126 Value *Description = IRB.CreatePointerCast( 1127 createPrivateGlobalForString(M, StackDescription.str()), 1128 IntptrTy); 1129 IRB.CreateStore(Description, BasePlus1); 1130 1131 // Poison the stack redzones at the entry. 1132 Value *ShadowBase = memToShadow(LocalStackBase, IRB); 1133 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRB, ShadowBase, true); 1134 1135 Value *AsanStackFreeFunc = NULL; 1136 if (DoStackMalloc) { 1137 AsanStackFreeFunc = M.getOrInsertFunction( 1138 kAsanStackFreeName, IRB.getVoidTy(), 1139 IntptrTy, IntptrTy, IntptrTy, NULL); 1140 } 1141 1142 // Unpoison the stack before all ret instructions. 1143 for (size_t i = 0, n = RetVec.size(); i < n; i++) { 1144 Instruction *Ret = RetVec[i]; 1145 IRBuilder<> IRBRet(Ret); 1146 1147 // Mark the current frame as retired. 1148 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 1149 BasePlus0); 1150 // Unpoison the stack. 1151 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRBRet, ShadowBase, false); 1152 1153 if (DoStackMalloc) { 1154 IRBRet.CreateCall3(AsanStackFreeFunc, LocalStackBase, 1155 ConstantInt::get(IntptrTy, LocalStackSize), 1156 OrigStackBase); 1157 } 1158 } 1159 1160 if (ClDebugStack) { 1161 DEBUG(dbgs() << F); 1162 } 1163 1164 return true; 1165} 1166