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