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 // A prologue is generated. 79 bool HasPrologue = false; 80 81 // IR checking code is generated. 82 bool HasIRCheck = false; 83 84 /// InsertStackProtectors - Insert code into the prologue and epilogue of 85 /// the function. 86 /// 87 /// - The prologue code loads and stores the stack guard onto the stack. 88 /// - The epilogue checks the value stored in the prologue against the 89 /// original value. It calls __stack_chk_fail if they differ. 90 bool InsertStackProtectors(); 91 92 /// CreateFailBB - Create a basic block to jump to when the stack protector 93 /// check fails. 94 BasicBlock *CreateFailBB(); 95 96 /// ContainsProtectableArray - Check whether the type either is an array or 97 /// contains an array of sufficient size so that we need stack protectors 98 /// for it. 99 /// \param [out] IsLarge is set to true if a protectable array is found and 100 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 101 /// multiple arrays, this gets set if any of them is large. 102 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 103 bool InStruct = false) const; 104 105 /// \brief Check whether a stack allocation has its address taken. 106 bool HasAddressTaken(const Instruction *AI); 107 108 /// RequiresStackProtector - Check whether or not this function needs a 109 /// stack protector based upon the stack protector level. 110 bool RequiresStackProtector(); 111 112 public: 113 static char ID; // Pass identification, replacement for typeid. StackProtector()114 StackProtector() 115 : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) { 116 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 117 } StackProtector(const TargetMachine * TM)118 StackProtector(const TargetMachine *TM) 119 : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()), 120 SSPBufferSize(8) { 121 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 122 } 123 getAnalysisUsage(AnalysisUsage & AU)124 void getAnalysisUsage(AnalysisUsage &AU) const override { 125 AU.addPreserved<DominatorTreeWrapperPass>(); 126 } 127 128 SSPLayoutKind getSSPLayout(const AllocaInst *AI) const; 129 130 // Return true if StackProtector is supposed to be handled by SelectionDAG. 131 bool shouldEmitSDCheck(const BasicBlock &BB) const; 132 133 void adjustForColoring(const AllocaInst *From, const AllocaInst *To); 134 135 bool runOnFunction(Function &Fn) override; 136 }; 137 } // end namespace llvm 138 139 #endif // LLVM_CODEGEN_STACKPROTECTOR_H 140