1f22ef01cSRoman Divacky //===-- StackProtector.cpp - Stack Protector Insertion --------------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This pass inserts stack protectors into functions which need them. A variable 11f22ef01cSRoman Divacky // with a random value in it is stored onto the stack before the local variables 12f22ef01cSRoman Divacky // are allocated. Upon exiting the block, the stored value is checked. If it's 13f22ef01cSRoman Divacky // changed, then there was some sort of violation and the program aborts. 14f22ef01cSRoman Divacky // 15f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 16f22ef01cSRoman Divacky 17f22ef01cSRoman Divacky #define DEBUG_TYPE "stack-protector" 18f22ef01cSRoman Divacky #include "llvm/CodeGen/Passes.h" 192754fe60SDimitry Andric #include "llvm/Analysis/Dominators.h" 20f22ef01cSRoman Divacky #include "llvm/Attributes.h" 21f22ef01cSRoman Divacky #include "llvm/Constants.h" 22f22ef01cSRoman Divacky #include "llvm/DerivedTypes.h" 23f22ef01cSRoman Divacky #include "llvm/Function.h" 24f22ef01cSRoman Divacky #include "llvm/Instructions.h" 25f22ef01cSRoman Divacky #include "llvm/Intrinsics.h" 26f22ef01cSRoman Divacky #include "llvm/Module.h" 27f22ef01cSRoman Divacky #include "llvm/Pass.h" 28f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h" 29f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h" 30f22ef01cSRoman Divacky #include "llvm/Target/TargetLowering.h" 317ae0e2c9SDimitry Andric #include "llvm/ADT/Triple.h" 32f22ef01cSRoman Divacky using namespace llvm; 33f22ef01cSRoman Divacky 34f22ef01cSRoman Divacky // SSPBufferSize - The lower bound for a buffer to be considered for stack 35f22ef01cSRoman Divacky // smashing protection. 36f22ef01cSRoman Divacky static cl::opt<unsigned> 37f22ef01cSRoman Divacky SSPBufferSize("stack-protector-buffer-size", cl::init(8), 38f22ef01cSRoman Divacky cl::desc("Lower bound for a buffer to be considered for " 39f22ef01cSRoman Divacky "stack protection")); 40f22ef01cSRoman Divacky 41f22ef01cSRoman Divacky namespace { 42f22ef01cSRoman Divacky class StackProtector : public FunctionPass { 43f22ef01cSRoman Divacky /// TLI - Keep a pointer of a TargetLowering to consult for determining 44f22ef01cSRoman Divacky /// target type sizes. 45f22ef01cSRoman Divacky const TargetLowering *TLI; 46f22ef01cSRoman Divacky 47f22ef01cSRoman Divacky Function *F; 48f22ef01cSRoman Divacky Module *M; 49f22ef01cSRoman Divacky 502754fe60SDimitry Andric DominatorTree *DT; 512754fe60SDimitry Andric 52f22ef01cSRoman Divacky /// InsertStackProtectors - Insert code into the prologue and epilogue of 53f22ef01cSRoman Divacky /// the function. 54f22ef01cSRoman Divacky /// 55f22ef01cSRoman Divacky /// - The prologue code loads and stores the stack guard onto the stack. 56f22ef01cSRoman Divacky /// - The epilogue checks the value stored in the prologue against the 57f22ef01cSRoman Divacky /// original value. It calls __stack_chk_fail if they differ. 58f22ef01cSRoman Divacky bool InsertStackProtectors(); 59f22ef01cSRoman Divacky 60f22ef01cSRoman Divacky /// CreateFailBB - Create a basic block to jump to when the stack protector 61f22ef01cSRoman Divacky /// check fails. 62f22ef01cSRoman Divacky BasicBlock *CreateFailBB(); 63f22ef01cSRoman Divacky 64f22ef01cSRoman Divacky /// RequiresStackProtector - Check whether or not this function needs a 65f22ef01cSRoman Divacky /// stack protector based upon the stack protector level. 66f22ef01cSRoman Divacky bool RequiresStackProtector() const; 67f22ef01cSRoman Divacky public: 68f22ef01cSRoman Divacky static char ID; // Pass identification, replacement for typeid. 692754fe60SDimitry Andric StackProtector() : FunctionPass(ID), TLI(0) { 702754fe60SDimitry Andric initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 712754fe60SDimitry Andric } 72f22ef01cSRoman Divacky StackProtector(const TargetLowering *tli) 732754fe60SDimitry Andric : FunctionPass(ID), TLI(tli) { 742754fe60SDimitry Andric initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 752754fe60SDimitry Andric } 762754fe60SDimitry Andric 772754fe60SDimitry Andric virtual void getAnalysisUsage(AnalysisUsage &AU) const { 782754fe60SDimitry Andric AU.addPreserved<DominatorTree>(); 792754fe60SDimitry Andric } 80f22ef01cSRoman Divacky 81f22ef01cSRoman Divacky virtual bool runOnFunction(Function &Fn); 82f22ef01cSRoman Divacky }; 83f22ef01cSRoman Divacky } // end anonymous namespace 84f22ef01cSRoman Divacky 85f22ef01cSRoman Divacky char StackProtector::ID = 0; 86e580952dSDimitry Andric INITIALIZE_PASS(StackProtector, "stack-protector", 872754fe60SDimitry Andric "Insert stack protectors", false, false) 88f22ef01cSRoman Divacky 89f22ef01cSRoman Divacky FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) { 90f22ef01cSRoman Divacky return new StackProtector(tli); 91f22ef01cSRoman Divacky } 92f22ef01cSRoman Divacky 93f22ef01cSRoman Divacky bool StackProtector::runOnFunction(Function &Fn) { 94f22ef01cSRoman Divacky F = &Fn; 95f22ef01cSRoman Divacky M = F->getParent(); 962754fe60SDimitry Andric DT = getAnalysisIfAvailable<DominatorTree>(); 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky if (!RequiresStackProtector()) return false; 99f22ef01cSRoman Divacky 100f22ef01cSRoman Divacky return InsertStackProtectors(); 101f22ef01cSRoman Divacky } 102f22ef01cSRoman Divacky 103f22ef01cSRoman Divacky /// RequiresStackProtector - Check whether or not this function needs a stack 104f22ef01cSRoman Divacky /// protector based upon the stack protector level. The heuristic we use is to 105f22ef01cSRoman Divacky /// add a guard variable to functions that call alloca, and functions with 106f22ef01cSRoman Divacky /// buffers larger than SSPBufferSize bytes. 107f22ef01cSRoman Divacky bool StackProtector::RequiresStackProtector() const { 108f22ef01cSRoman Divacky if (F->hasFnAttr(Attribute::StackProtectReq)) 109f22ef01cSRoman Divacky return true; 110f22ef01cSRoman Divacky 111f22ef01cSRoman Divacky if (!F->hasFnAttr(Attribute::StackProtect)) 112f22ef01cSRoman Divacky return false; 113f22ef01cSRoman Divacky 114f22ef01cSRoman Divacky const TargetData *TD = TLI->getTargetData(); 1157ae0e2c9SDimitry Andric const TargetMachine &TM = TLI->getTargetMachine(); 1167ae0e2c9SDimitry Andric Triple Trip(TM.getTargetTriple()); 117f22ef01cSRoman Divacky 118f22ef01cSRoman Divacky for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { 119f22ef01cSRoman Divacky BasicBlock *BB = I; 120f22ef01cSRoman Divacky 121f22ef01cSRoman Divacky for (BasicBlock::iterator 122f22ef01cSRoman Divacky II = BB->begin(), IE = BB->end(); II != IE; ++II) 123f22ef01cSRoman Divacky if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 124f22ef01cSRoman Divacky if (AI->isArrayAllocation()) 125f22ef01cSRoman Divacky // This is a call to alloca with a variable size. Emit stack 126f22ef01cSRoman Divacky // protectors. 127f22ef01cSRoman Divacky return true; 128f22ef01cSRoman Divacky 1297ae0e2c9SDimitry Andric if (ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) { 1307ae0e2c9SDimitry Andric // If we're on a non-Darwin platform, don't add stack protectors 1317ae0e2c9SDimitry Andric // unless the array is a character array. 1327ae0e2c9SDimitry Andric if (!Trip.isOSDarwin() && !AT->getElementType()->isIntegerTy(8)) 1337ae0e2c9SDimitry Andric continue; 1347ae0e2c9SDimitry Andric 135f22ef01cSRoman Divacky // If an array has more than SSPBufferSize bytes of allocated space, 136f22ef01cSRoman Divacky // then we emit stack protectors. 137f22ef01cSRoman Divacky if (SSPBufferSize <= TD->getTypeAllocSize(AT)) 138f22ef01cSRoman Divacky return true; 139f22ef01cSRoman Divacky } 140f22ef01cSRoman Divacky } 1417ae0e2c9SDimitry Andric } 142f22ef01cSRoman Divacky 143f22ef01cSRoman Divacky return false; 144f22ef01cSRoman Divacky } 145f22ef01cSRoman Divacky 146f22ef01cSRoman Divacky /// InsertStackProtectors - Insert code into the prologue and epilogue of the 147f22ef01cSRoman Divacky /// function. 148f22ef01cSRoman Divacky /// 149f22ef01cSRoman Divacky /// - The prologue code loads and stores the stack guard onto the stack. 150f22ef01cSRoman Divacky /// - The epilogue checks the value stored in the prologue against the original 151f22ef01cSRoman Divacky /// value. It calls __stack_chk_fail if they differ. 152f22ef01cSRoman Divacky bool StackProtector::InsertStackProtectors() { 153f22ef01cSRoman Divacky BasicBlock *FailBB = 0; // The basic block to jump to if check fails. 1542754fe60SDimitry Andric BasicBlock *FailBBDom = 0; // FailBB's dominator. 155f22ef01cSRoman Divacky AllocaInst *AI = 0; // Place on stack that stores the stack guard. 156ffd1746dSEd Schouten Value *StackGuardVar = 0; // The stack guard variable. 157f22ef01cSRoman Divacky 158f22ef01cSRoman Divacky for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { 159f22ef01cSRoman Divacky BasicBlock *BB = I++; 160f22ef01cSRoman Divacky ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()); 161f22ef01cSRoman Divacky if (!RI) continue; 162f22ef01cSRoman Divacky 163f22ef01cSRoman Divacky if (!FailBB) { 164f22ef01cSRoman Divacky // Insert code into the entry block that stores the __stack_chk_guard 165f22ef01cSRoman Divacky // variable onto the stack: 166f22ef01cSRoman Divacky // 167f22ef01cSRoman Divacky // entry: 168f22ef01cSRoman Divacky // StackGuardSlot = alloca i8* 169f22ef01cSRoman Divacky // StackGuard = load __stack_chk_guard 170f22ef01cSRoman Divacky // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) 171f22ef01cSRoman Divacky // 1726122f3e6SDimitry Andric PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); 173ffd1746dSEd Schouten unsigned AddressSpace, Offset; 174ffd1746dSEd Schouten if (TLI->getStackCookieLocation(AddressSpace, Offset)) { 175ffd1746dSEd Schouten Constant *OffsetVal = 176ffd1746dSEd Schouten ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); 177ffd1746dSEd Schouten 178ffd1746dSEd Schouten StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, 179ffd1746dSEd Schouten PointerType::get(PtrTy, AddressSpace)); 180ffd1746dSEd Schouten } else { 181f22ef01cSRoman Divacky StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 182ffd1746dSEd Schouten } 183f22ef01cSRoman Divacky 184f22ef01cSRoman Divacky BasicBlock &Entry = F->getEntryBlock(); 185f22ef01cSRoman Divacky Instruction *InsPt = &Entry.front(); 186f22ef01cSRoman Divacky 187f22ef01cSRoman Divacky AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); 188f22ef01cSRoman Divacky LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); 189f22ef01cSRoman Divacky 190f22ef01cSRoman Divacky Value *Args[] = { LI, AI }; 191f22ef01cSRoman Divacky CallInst:: 192f22ef01cSRoman Divacky Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), 19317a519f9SDimitry Andric Args, "", InsPt); 194f22ef01cSRoman Divacky 195f22ef01cSRoman Divacky // Create the basic block to jump to when the guard check fails. 196f22ef01cSRoman Divacky FailBB = CreateFailBB(); 197f22ef01cSRoman Divacky } 198f22ef01cSRoman Divacky 199f22ef01cSRoman Divacky // For each block with a return instruction, convert this: 200f22ef01cSRoman Divacky // 201f22ef01cSRoman Divacky // return: 202f22ef01cSRoman Divacky // ... 203f22ef01cSRoman Divacky // ret ... 204f22ef01cSRoman Divacky // 205f22ef01cSRoman Divacky // into this: 206f22ef01cSRoman Divacky // 207f22ef01cSRoman Divacky // return: 208f22ef01cSRoman Divacky // ... 209f22ef01cSRoman Divacky // %1 = load __stack_chk_guard 210f22ef01cSRoman Divacky // %2 = load StackGuardSlot 211f22ef01cSRoman Divacky // %3 = cmp i1 %1, %2 212f22ef01cSRoman Divacky // br i1 %3, label %SP_return, label %CallStackCheckFailBlk 213f22ef01cSRoman Divacky // 214f22ef01cSRoman Divacky // SP_return: 215f22ef01cSRoman Divacky // ret ... 216f22ef01cSRoman Divacky // 217f22ef01cSRoman Divacky // CallStackCheckFailBlk: 218f22ef01cSRoman Divacky // call void @__stack_chk_fail() 219f22ef01cSRoman Divacky // unreachable 220f22ef01cSRoman Divacky 221f22ef01cSRoman Divacky // Split the basic block before the return instruction. 222f22ef01cSRoman Divacky BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); 2233b0f4066SDimitry Andric 2243b0f4066SDimitry Andric if (DT && DT->isReachableFromEntry(BB)) { 2253b0f4066SDimitry Andric DT->addNewBlock(NewBB, BB); 2263b0f4066SDimitry Andric FailBBDom = FailBBDom ? DT->findNearestCommonDominator(FailBBDom, BB) :BB; 2272754fe60SDimitry Andric } 228f22ef01cSRoman Divacky 229f22ef01cSRoman Divacky // Remove default branch instruction to the new BB. 230f22ef01cSRoman Divacky BB->getTerminator()->eraseFromParent(); 231f22ef01cSRoman Divacky 232f22ef01cSRoman Divacky // Move the newly created basic block to the point right after the old basic 233f22ef01cSRoman Divacky // block so that it's in the "fall through" position. 234f22ef01cSRoman Divacky NewBB->moveAfter(BB); 235f22ef01cSRoman Divacky 236f22ef01cSRoman Divacky // Generate the stack protector instructions in the old basic block. 237f22ef01cSRoman Divacky LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); 238f22ef01cSRoman Divacky LoadInst *LI2 = new LoadInst(AI, "", true, BB); 239f22ef01cSRoman Divacky ICmpInst *Cmp = new ICmpInst(*BB, CmpInst::ICMP_EQ, LI1, LI2, ""); 240f22ef01cSRoman Divacky BranchInst::Create(NewBB, FailBB, Cmp, BB); 241f22ef01cSRoman Divacky } 242f22ef01cSRoman Divacky 243f22ef01cSRoman Divacky // Return if we didn't modify any basic blocks. I.e., there are no return 244f22ef01cSRoman Divacky // statements in the function. 245f22ef01cSRoman Divacky if (!FailBB) return false; 246f22ef01cSRoman Divacky 2473b0f4066SDimitry Andric if (DT && FailBBDom) 2482754fe60SDimitry Andric DT->addNewBlock(FailBB, FailBBDom); 2492754fe60SDimitry Andric 250f22ef01cSRoman Divacky return true; 251f22ef01cSRoman Divacky } 252f22ef01cSRoman Divacky 253f22ef01cSRoman Divacky /// CreateFailBB - Create a basic block to jump to when the stack protector 254f22ef01cSRoman Divacky /// check fails. 255f22ef01cSRoman Divacky BasicBlock *StackProtector::CreateFailBB() { 256f22ef01cSRoman Divacky BasicBlock *FailBB = BasicBlock::Create(F->getContext(), 257f22ef01cSRoman Divacky "CallStackCheckFailBlk", F); 258f22ef01cSRoman Divacky Constant *StackChkFail = 259f22ef01cSRoman Divacky M->getOrInsertFunction("__stack_chk_fail", 260f22ef01cSRoman Divacky Type::getVoidTy(F->getContext()), NULL); 261f22ef01cSRoman Divacky CallInst::Create(StackChkFail, "", FailBB); 262f22ef01cSRoman Divacky new UnreachableInst(F->getContext(), FailBB); 263f22ef01cSRoman Divacky return FailBB; 264f22ef01cSRoman Divacky } 265