1 //===-- StackProtector.h - 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 #ifndef LLVM_CODEGEN_STACKPROTECTOR_H 18 #define LLVM_CODEGEN_STACKPROTECTOR_H 19 20 #include "llvm/ADT/SmallPtrSet.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/IR/Dominators.h" 23 #include "llvm/IR/ValueMap.h" 24 #include "llvm/Pass.h" 25 #include "llvm/Target/TargetLowering.h" 26 27 namespace llvm { 28 class Function; 29 class Module; 30 class PHINode; 31 32 class StackProtector : public FunctionPass { 33 public: 34 /// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that 35 /// vulnerable stack allocations are located close the stack protector. 36 enum SSPLayoutKind { 37 SSPLK_None, ///< Did not trigger a stack protector. No effect on data 38 ///< layout. 39 SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest 40 ///< to the stack protector. 41 SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest 42 ///< to the stack protector. 43 SSPLK_AddrOf ///< The address of this allocation is exposed and 44 ///< triggered protection. 3rd closest to the protector. 45 }; 46 47 /// A mapping of AllocaInsts to their required SSP layout. 48 typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap; 49 50 private: 51 const TargetMachine *TM; 52 53 /// TLI - Keep a pointer of a TargetLowering to consult for determining 54 /// target type sizes. 55 const TargetLoweringBase *TLI; 56 const Triple Trip; 57 58 Function *F; 59 Module *M; 60 61 DominatorTree *DT; 62 63 /// Layout - Mapping of allocations to the required SSPLayoutKind. 64 /// StackProtector analysis will update this map when determining if an 65 /// AllocaInst triggers a stack protector. 66 SSPLayoutMap Layout; 67 68 /// \brief The minimum size of buffers that will receive stack smashing 69 /// protection when -fstack-protection is used. 70 unsigned SSPBufferSize; 71 72 /// VisitedPHIs - The set of PHI nodes visited when determining 73 /// if a variable's reference has been taken. This set 74 /// is maintained to ensure we don't visit the same PHI node multiple 75 /// times. 76 SmallPtrSet<const PHINode *, 16> VisitedPHIs; 77 78 /// InsertStackProtectors - Insert code into the prologue and epilogue of 79 /// the function. 80 /// 81 /// - The prologue code loads and stores the stack guard onto the stack. 82 /// - The epilogue checks the value stored in the prologue against the 83 /// original value. It calls __stack_chk_fail if they differ. 84 bool InsertStackProtectors(); 85 86 /// CreateFailBB - Create a basic block to jump to when the stack protector 87 /// check fails. 88 BasicBlock *CreateFailBB(); 89 90 /// ContainsProtectableArray - Check whether the type either is an array or 91 /// contains an array of sufficient size so that we need stack protectors 92 /// for it. 93 /// \param [out] IsLarge is set to true if a protectable array is found and 94 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 95 /// multiple arrays, this gets set if any of them is large. 96 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 97 bool InStruct = false) const; 98 99 /// \brief Check whether a stack allocation has its address taken. 100 bool HasAddressTaken(const Instruction *AI); 101 102 /// RequiresStackProtector - Check whether or not this function needs a 103 /// stack protector based upon the stack protector level. 104 bool RequiresStackProtector(); 105 106 public: 107 static char ID; // Pass identification, replacement for typeid. StackProtector()108 StackProtector() 109 : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) { 110 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 111 } StackProtector(const TargetMachine * TM)112 StackProtector(const TargetMachine *TM) 113 : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()), 114 SSPBufferSize(8) { 115 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 116 } 117 getAnalysisUsage(AnalysisUsage & AU)118 void getAnalysisUsage(AnalysisUsage &AU) const override { 119 AU.addPreserved<DominatorTreeWrapperPass>(); 120 } 121 122 SSPLayoutKind getSSPLayout(const AllocaInst *AI) const; 123 void adjustForColoring(const AllocaInst *From, const AllocaInst *To); 124 125 bool runOnFunction(Function &Fn) override; 126 }; 127 } // end namespace llvm 128 129 #endif // LLVM_CODEGEN_STACKPROTECTOR_H 130