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" 19f22ef01cSRoman Divacky #include "llvm/Attributes.h" 20f22ef01cSRoman Divacky #include "llvm/Constants.h" 21f22ef01cSRoman Divacky #include "llvm/DerivedTypes.h" 22f22ef01cSRoman Divacky #include "llvm/Function.h" 23f22ef01cSRoman Divacky #include "llvm/Instructions.h" 24f22ef01cSRoman Divacky #include "llvm/Intrinsics.h" 25f22ef01cSRoman Divacky #include "llvm/Module.h" 26f22ef01cSRoman Divacky #include "llvm/Pass.h" 27f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h" 28f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h" 29f22ef01cSRoman Divacky #include "llvm/Target/TargetLowering.h" 30f22ef01cSRoman Divacky using namespace llvm; 31f22ef01cSRoman Divacky 32f22ef01cSRoman Divacky // SSPBufferSize - The lower bound for a buffer to be considered for stack 33f22ef01cSRoman Divacky // smashing protection. 34f22ef01cSRoman Divacky static cl::opt<unsigned> 35f22ef01cSRoman Divacky SSPBufferSize("stack-protector-buffer-size", cl::init(8), 36f22ef01cSRoman Divacky cl::desc("Lower bound for a buffer to be considered for " 37f22ef01cSRoman Divacky "stack protection")); 38f22ef01cSRoman Divacky 39f22ef01cSRoman Divacky namespace { 40f22ef01cSRoman Divacky class StackProtector : public FunctionPass { 41f22ef01cSRoman Divacky /// TLI - Keep a pointer of a TargetLowering to consult for determining 42f22ef01cSRoman Divacky /// target type sizes. 43f22ef01cSRoman Divacky const TargetLowering *TLI; 44f22ef01cSRoman Divacky 45f22ef01cSRoman Divacky Function *F; 46f22ef01cSRoman Divacky Module *M; 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky /// InsertStackProtectors - Insert code into the prologue and epilogue of 49f22ef01cSRoman Divacky /// the function. 50f22ef01cSRoman Divacky /// 51f22ef01cSRoman Divacky /// - The prologue code loads and stores the stack guard onto the stack. 52f22ef01cSRoman Divacky /// - The epilogue checks the value stored in the prologue against the 53f22ef01cSRoman Divacky /// original value. It calls __stack_chk_fail if they differ. 54f22ef01cSRoman Divacky bool InsertStackProtectors(); 55f22ef01cSRoman Divacky 56f22ef01cSRoman Divacky /// CreateFailBB - Create a basic block to jump to when the stack protector 57f22ef01cSRoman Divacky /// check fails. 58f22ef01cSRoman Divacky BasicBlock *CreateFailBB(); 59f22ef01cSRoman Divacky 60f22ef01cSRoman Divacky /// RequiresStackProtector - Check whether or not this function needs a 61f22ef01cSRoman Divacky /// stack protector based upon the stack protector level. 62f22ef01cSRoman Divacky bool RequiresStackProtector() const; 63f22ef01cSRoman Divacky public: 64f22ef01cSRoman Divacky static char ID; // Pass identification, replacement for typeid. 65f22ef01cSRoman Divacky StackProtector() : FunctionPass(&ID), TLI(0) {} 66f22ef01cSRoman Divacky StackProtector(const TargetLowering *tli) 67f22ef01cSRoman Divacky : FunctionPass(&ID), TLI(tli) {} 68f22ef01cSRoman Divacky 69f22ef01cSRoman Divacky virtual bool runOnFunction(Function &Fn); 70f22ef01cSRoman Divacky }; 71f22ef01cSRoman Divacky } // end anonymous namespace 72f22ef01cSRoman Divacky 73f22ef01cSRoman Divacky char StackProtector::ID = 0; 74f22ef01cSRoman Divacky static RegisterPass<StackProtector> 75f22ef01cSRoman Divacky X("stack-protector", "Insert stack protectors"); 76f22ef01cSRoman Divacky 77f22ef01cSRoman Divacky FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) { 78f22ef01cSRoman Divacky return new StackProtector(tli); 79f22ef01cSRoman Divacky } 80f22ef01cSRoman Divacky 81f22ef01cSRoman Divacky bool StackProtector::runOnFunction(Function &Fn) { 82f22ef01cSRoman Divacky F = &Fn; 83f22ef01cSRoman Divacky M = F->getParent(); 84f22ef01cSRoman Divacky 85f22ef01cSRoman Divacky if (!RequiresStackProtector()) return false; 86f22ef01cSRoman Divacky 87f22ef01cSRoman Divacky return InsertStackProtectors(); 88f22ef01cSRoman Divacky } 89f22ef01cSRoman Divacky 90f22ef01cSRoman Divacky /// RequiresStackProtector - Check whether or not this function needs a stack 91f22ef01cSRoman Divacky /// protector based upon the stack protector level. The heuristic we use is to 92f22ef01cSRoman Divacky /// add a guard variable to functions that call alloca, and functions with 93f22ef01cSRoman Divacky /// buffers larger than SSPBufferSize bytes. 94f22ef01cSRoman Divacky bool StackProtector::RequiresStackProtector() const { 95f22ef01cSRoman Divacky if (F->hasFnAttr(Attribute::StackProtectReq)) 96f22ef01cSRoman Divacky return true; 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky if (!F->hasFnAttr(Attribute::StackProtect)) 99f22ef01cSRoman Divacky return false; 100f22ef01cSRoman Divacky 101f22ef01cSRoman Divacky const TargetData *TD = TLI->getTargetData(); 102f22ef01cSRoman Divacky 103f22ef01cSRoman Divacky for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { 104f22ef01cSRoman Divacky BasicBlock *BB = I; 105f22ef01cSRoman Divacky 106f22ef01cSRoman Divacky for (BasicBlock::iterator 107f22ef01cSRoman Divacky II = BB->begin(), IE = BB->end(); II != IE; ++II) 108f22ef01cSRoman Divacky if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 109f22ef01cSRoman Divacky if (AI->isArrayAllocation()) 110f22ef01cSRoman Divacky // This is a call to alloca with a variable size. Emit stack 111f22ef01cSRoman Divacky // protectors. 112f22ef01cSRoman Divacky return true; 113f22ef01cSRoman Divacky 114f22ef01cSRoman Divacky if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) { 115f22ef01cSRoman Divacky // We apparently only care about character arrays. 116f22ef01cSRoman Divacky if (!AT->getElementType()->isIntegerTy(8)) 117f22ef01cSRoman Divacky continue; 118f22ef01cSRoman Divacky 119f22ef01cSRoman Divacky // If an array has more than SSPBufferSize bytes of allocated space, 120f22ef01cSRoman Divacky // then we emit stack protectors. 121f22ef01cSRoman Divacky if (SSPBufferSize <= TD->getTypeAllocSize(AT)) 122f22ef01cSRoman Divacky return true; 123f22ef01cSRoman Divacky } 124f22ef01cSRoman Divacky } 125f22ef01cSRoman Divacky } 126f22ef01cSRoman Divacky 127f22ef01cSRoman Divacky return false; 128f22ef01cSRoman Divacky } 129f22ef01cSRoman Divacky 130f22ef01cSRoman Divacky /// InsertStackProtectors - Insert code into the prologue and epilogue of the 131f22ef01cSRoman Divacky /// function. 132f22ef01cSRoman Divacky /// 133f22ef01cSRoman Divacky /// - The prologue code loads and stores the stack guard onto the stack. 134f22ef01cSRoman Divacky /// - The epilogue checks the value stored in the prologue against the original 135f22ef01cSRoman Divacky /// value. It calls __stack_chk_fail if they differ. 136f22ef01cSRoman Divacky bool StackProtector::InsertStackProtectors() { 137f22ef01cSRoman Divacky BasicBlock *FailBB = 0; // The basic block to jump to if check fails. 138f22ef01cSRoman Divacky AllocaInst *AI = 0; // Place on stack that stores the stack guard. 139ffd1746dSEd Schouten Value *StackGuardVar = 0; // The stack guard variable. 140f22ef01cSRoman Divacky 141f22ef01cSRoman Divacky for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { 142f22ef01cSRoman Divacky BasicBlock *BB = I++; 143f22ef01cSRoman Divacky 144f22ef01cSRoman Divacky ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()); 145f22ef01cSRoman Divacky if (!RI) continue; 146f22ef01cSRoman Divacky 147f22ef01cSRoman Divacky if (!FailBB) { 148f22ef01cSRoman Divacky // Insert code into the entry block that stores the __stack_chk_guard 149f22ef01cSRoman Divacky // variable onto the stack: 150f22ef01cSRoman Divacky // 151f22ef01cSRoman Divacky // entry: 152f22ef01cSRoman Divacky // StackGuardSlot = alloca i8* 153f22ef01cSRoman Divacky // StackGuard = load __stack_chk_guard 154f22ef01cSRoman Divacky // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) 155f22ef01cSRoman Divacky // 156ffd1746dSEd Schouten const PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); 157ffd1746dSEd Schouten unsigned AddressSpace, Offset; 158ffd1746dSEd Schouten if (TLI->getStackCookieLocation(AddressSpace, Offset)) { 159ffd1746dSEd Schouten Constant *OffsetVal = 160ffd1746dSEd Schouten ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset); 161ffd1746dSEd Schouten 162ffd1746dSEd Schouten StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal, 163ffd1746dSEd Schouten PointerType::get(PtrTy, AddressSpace)); 164ffd1746dSEd Schouten } else { 165f22ef01cSRoman Divacky StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 166ffd1746dSEd Schouten } 167f22ef01cSRoman Divacky 168f22ef01cSRoman Divacky BasicBlock &Entry = F->getEntryBlock(); 169f22ef01cSRoman Divacky Instruction *InsPt = &Entry.front(); 170f22ef01cSRoman Divacky 171f22ef01cSRoman Divacky AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); 172f22ef01cSRoman Divacky LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky Value *Args[] = { LI, AI }; 175f22ef01cSRoman Divacky CallInst:: 176f22ef01cSRoman Divacky Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), 177f22ef01cSRoman Divacky &Args[0], array_endof(Args), "", InsPt); 178f22ef01cSRoman Divacky 179f22ef01cSRoman Divacky // Create the basic block to jump to when the guard check fails. 180f22ef01cSRoman Divacky FailBB = CreateFailBB(); 181f22ef01cSRoman Divacky } 182f22ef01cSRoman Divacky 183f22ef01cSRoman Divacky // For each block with a return instruction, convert this: 184f22ef01cSRoman Divacky // 185f22ef01cSRoman Divacky // return: 186f22ef01cSRoman Divacky // ... 187f22ef01cSRoman Divacky // ret ... 188f22ef01cSRoman Divacky // 189f22ef01cSRoman Divacky // into this: 190f22ef01cSRoman Divacky // 191f22ef01cSRoman Divacky // return: 192f22ef01cSRoman Divacky // ... 193f22ef01cSRoman Divacky // %1 = load __stack_chk_guard 194f22ef01cSRoman Divacky // %2 = load StackGuardSlot 195f22ef01cSRoman Divacky // %3 = cmp i1 %1, %2 196f22ef01cSRoman Divacky // br i1 %3, label %SP_return, label %CallStackCheckFailBlk 197f22ef01cSRoman Divacky // 198f22ef01cSRoman Divacky // SP_return: 199f22ef01cSRoman Divacky // ret ... 200f22ef01cSRoman Divacky // 201f22ef01cSRoman Divacky // CallStackCheckFailBlk: 202f22ef01cSRoman Divacky // call void @__stack_chk_fail() 203f22ef01cSRoman Divacky // unreachable 204f22ef01cSRoman Divacky 205f22ef01cSRoman Divacky // Split the basic block before the return instruction. 206f22ef01cSRoman Divacky BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); 207f22ef01cSRoman Divacky 208f22ef01cSRoman Divacky // Remove default branch instruction to the new BB. 209f22ef01cSRoman Divacky BB->getTerminator()->eraseFromParent(); 210f22ef01cSRoman Divacky 211f22ef01cSRoman Divacky // Move the newly created basic block to the point right after the old basic 212f22ef01cSRoman Divacky // block so that it's in the "fall through" position. 213f22ef01cSRoman Divacky NewBB->moveAfter(BB); 214f22ef01cSRoman Divacky 215f22ef01cSRoman Divacky // Generate the stack protector instructions in the old basic block. 216f22ef01cSRoman Divacky LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); 217f22ef01cSRoman Divacky LoadInst *LI2 = new LoadInst(AI, "", true, BB); 218f22ef01cSRoman Divacky ICmpInst *Cmp = new ICmpInst(*BB, CmpInst::ICMP_EQ, LI1, LI2, ""); 219f22ef01cSRoman Divacky BranchInst::Create(NewBB, FailBB, Cmp, BB); 220f22ef01cSRoman Divacky } 221f22ef01cSRoman Divacky 222f22ef01cSRoman Divacky // Return if we didn't modify any basic blocks. I.e., there are no return 223f22ef01cSRoman Divacky // statements in the function. 224f22ef01cSRoman Divacky if (!FailBB) return false; 225f22ef01cSRoman Divacky 226f22ef01cSRoman Divacky return true; 227f22ef01cSRoman Divacky } 228f22ef01cSRoman Divacky 229f22ef01cSRoman Divacky /// CreateFailBB - Create a basic block to jump to when the stack protector 230f22ef01cSRoman Divacky /// check fails. 231f22ef01cSRoman Divacky BasicBlock *StackProtector::CreateFailBB() { 232f22ef01cSRoman Divacky BasicBlock *FailBB = BasicBlock::Create(F->getContext(), 233f22ef01cSRoman Divacky "CallStackCheckFailBlk", F); 234f22ef01cSRoman Divacky Constant *StackChkFail = 235f22ef01cSRoman Divacky M->getOrInsertFunction("__stack_chk_fail", 236f22ef01cSRoman Divacky Type::getVoidTy(F->getContext()), NULL); 237f22ef01cSRoman Divacky CallInst::Create(StackChkFail, "", FailBB); 238f22ef01cSRoman Divacky new UnreachableInst(F->getContext(), FailBB); 239f22ef01cSRoman Divacky return FailBB; 240f22ef01cSRoman Divacky } 241