LLVM API Documentation
00001 //===-- StackProtector.cpp - Stack Protector Insertion --------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass inserts stack protectors into functions which need them. A variable 00011 // with a random value in it is stored onto the stack before the local variables 00012 // are allocated. Upon exiting the block, the stored value is checked. If it's 00013 // changed, then there was some sort of violation and the program aborts. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #define DEBUG_TYPE "stack-protector" 00018 #include "llvm/CodeGen/Passes.h" 00019 #include "llvm/Attributes.h" 00020 #include "llvm/Constants.h" 00021 #include "llvm/DerivedTypes.h" 00022 #include "llvm/Function.h" 00023 #include "llvm/Instructions.h" 00024 #include "llvm/Intrinsics.h" 00025 #include "llvm/Module.h" 00026 #include "llvm/Pass.h" 00027 #include "llvm/Support/CommandLine.h" 00028 #include "llvm/Target/TargetData.h" 00029 #include "llvm/Target/TargetLowering.h" 00030 using namespace llvm; 00031 00032 // SSPBufferSize - The lower bound for a buffer to be considered for stack 00033 // smashing protection. 00034 static cl::opt<unsigned> 00035 SSPBufferSize("stack-protector-buffer-size", cl::init(8), 00036 cl::desc("Lower bound for a buffer to be considered for " 00037 "stack protection")); 00038 00039 namespace { 00040 class VISIBILITY_HIDDEN StackProtector : public FunctionPass { 00041 /// TLI - Keep a pointer of a TargetLowering to consult for determining 00042 /// target type sizes. 00043 const TargetLowering *TLI; 00044 00045 Function *F; 00046 Module *M; 00047 00048 /// InsertStackProtectors - Insert code into the prologue and epilogue of 00049 /// the function. 00050 /// 00051 /// - The prologue code loads and stores the stack guard onto the stack. 00052 /// - The epilogue checks the value stored in the prologue against the 00053 /// original value. It calls __stack_chk_fail if they differ. 00054 bool InsertStackProtectors(); 00055 00056 /// CreateFailBB - Create a basic block to jump to when the stack protector 00057 /// check fails. 00058 BasicBlock *CreateFailBB(); 00059 00060 /// RequiresStackProtector - Check whether or not this function needs a 00061 /// stack protector based upon the stack protector level. 00062 bool RequiresStackProtector() const; 00063 public: 00064 static char ID; // Pass identification, replacement for typeid. 00065 StackProtector() : FunctionPass(&ID), TLI(0) {} 00066 StackProtector(const TargetLowering *tli) 00067 : FunctionPass(&ID), TLI(tli) {} 00068 00069 virtual bool runOnFunction(Function &Fn); 00070 }; 00071 } // end anonymous namespace 00072 00073 char StackProtector::ID = 0; 00074 static RegisterPass<StackProtector> 00075 X("stack-protector", "Insert stack protectors"); 00076 00077 FunctionPass *llvm::createStackProtectorPass(const TargetLowering *tli) { 00078 return new StackProtector(tli); 00079 } 00080 00081 bool StackProtector::runOnFunction(Function &Fn) { 00082 F = &Fn; 00083 M = F->getParent(); 00084 00085 if (!RequiresStackProtector()) return false; 00086 00087 return InsertStackProtectors(); 00088 } 00089 00090 /// RequiresStackProtector - Check whether or not this function needs a stack 00091 /// protector based upon the stack protector level. The heuristic we use is to 00092 /// add a guard variable to functions that call alloca, and functions with 00093 /// buffers larger than SSPBufferSize bytes. 00094 bool StackProtector::RequiresStackProtector() const { 00095 if (F->hasFnAttr(Attribute::StackProtectReq)) 00096 return true; 00097 00098 if (!F->hasFnAttr(Attribute::StackProtect)) 00099 return false; 00100 00101 const TargetData *TD = TLI->getTargetData(); 00102 00103 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { 00104 BasicBlock *BB = I; 00105 00106 for (BasicBlock::iterator 00107 II = BB->begin(), IE = BB->end(); II != IE; ++II) 00108 if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 00109 if (AI->isArrayAllocation()) 00110 // This is a call to alloca with a variable size. Emit stack 00111 // protectors. 00112 return true; 00113 00114 if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) 00115 // If an array has more than SSPBufferSize bytes of allocated space, 00116 // then we emit stack protectors. 00117 if (SSPBufferSize <= TD->getTypePaddedSize(AT)) 00118 return true; 00119 } 00120 } 00121 00122 return false; 00123 } 00124 00125 /// InsertStackProtectors - Insert code into the prologue and epilogue of the 00126 /// function. 00127 /// 00128 /// - The prologue code loads and stores the stack guard onto the stack. 00129 /// - The epilogue checks the value stored in the prologue against the original 00130 /// value. It calls __stack_chk_fail if they differ. 00131 bool StackProtector::InsertStackProtectors() { 00132 BasicBlock *FailBB = 0; // The basic block to jump to if check fails. 00133 AllocaInst *AI = 0; // Place on stack that stores the stack guard. 00134 Constant *StackGuardVar = 0; // The stack guard variable. 00135 00136 for (Function::iterator I = F->begin(), E = F->end(); I != E; ) { 00137 BasicBlock *BB = I++; 00138 00139 ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()); 00140 if (!RI) continue; 00141 00142 if (!FailBB) { 00143 // Insert code into the entry block that stores the __stack_chk_guard 00144 // variable onto the stack: 00145 // 00146 // entry: 00147 // StackGuardSlot = alloca i8* 00148 // StackGuard = load __stack_chk_guard 00149 // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) 00150 // 00151 PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty); 00152 StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy); 00153 00154 BasicBlock &Entry = F->getEntryBlock(); 00155 Instruction *InsPt = &Entry.front(); 00156 00157 AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt); 00158 LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt); 00159 00160 Value *Args[] = { LI, AI }; 00161 CallInst:: 00162 Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), 00163 &Args[0], array_endof(Args), "", InsPt); 00164 00165 // Create the basic block to jump to when the guard check fails. 00166 FailBB = CreateFailBB(); 00167 } 00168 00169 // For each block with a return instruction, convert this: 00170 // 00171 // return: 00172 // ... 00173 // ret ... 00174 // 00175 // into this: 00176 // 00177 // return: 00178 // ... 00179 // %1 = load __stack_chk_guard 00180 // %2 = load StackGuardSlot 00181 // %3 = cmp i1 %1, %2 00182 // br i1 %3, label %SP_return, label %CallStackCheckFailBlk 00183 // 00184 // SP_return: 00185 // ret ... 00186 // 00187 // CallStackCheckFailBlk: 00188 // call void @__stack_chk_fail() 00189 // unreachable 00190 00191 // Split the basic block before the return instruction. 00192 BasicBlock *NewBB = BB->splitBasicBlock(RI, "SP_return"); 00193 00194 // Move the newly created basic block to the point right after the old basic 00195 // block so that it's in the "fall through" position. 00196 NewBB->moveAfter(BB); 00197 00198 // Generate the stack protector instructions in the old basic block. 00199 LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB); 00200 LoadInst *LI2 = new LoadInst(AI, "", true, BB); 00201 ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB); 00202 BranchInst::Create(NewBB, FailBB, Cmp, BB); 00203 } 00204 00205 // Return if we didn't modify any basic blocks. I.e., there are no return 00206 // statements in the function. 00207 if (!FailBB) return false; 00208 00209 return true; 00210 } 00211 00212 /// CreateFailBB - Create a basic block to jump to when the stack protector 00213 /// check fails. 00214 BasicBlock *StackProtector::CreateFailBB() { 00215 BasicBlock *FailBB = BasicBlock::Create("CallStackCheckFailBlk", F); 00216 Constant *StackChkFail = 00217 M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL); 00218 CallInst::Create(StackChkFail, "", FailBB); 00219 new UnreachableInst(FailBB); 00220 return FailBB; 00221 }