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