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