LLVM API Documentation
00001 //===-- StackProtector.h - 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 #ifndef LLVM_CODEGEN_STACKPROTECTOR_H 00018 #define LLVM_CODEGEN_STACKPROTECTOR_H 00019 00020 #include "llvm/ADT/SmallPtrSet.h" 00021 #include "llvm/ADT/Triple.h" 00022 #include "llvm/IR/Dominators.h" 00023 #include "llvm/IR/ValueMap.h" 00024 #include "llvm/Pass.h" 00025 #include "llvm/Target/TargetLowering.h" 00026 00027 namespace llvm { 00028 class Function; 00029 class Module; 00030 class PHINode; 00031 00032 class StackProtector : public FunctionPass { 00033 public: 00034 /// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that 00035 /// vulnerable stack allocations are located close the stack protector. 00036 enum SSPLayoutKind { 00037 SSPLK_None, ///< Did not trigger a stack protector. No effect on data 00038 ///< layout. 00039 SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest 00040 ///< to the stack protector. 00041 SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest 00042 ///< to the stack protector. 00043 SSPLK_AddrOf ///< The address of this allocation is exposed and 00044 ///< triggered protection. 3rd closest to the protector. 00045 }; 00046 00047 /// A mapping of AllocaInsts to their required SSP layout. 00048 typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap; 00049 00050 private: 00051 const TargetMachine *TM; 00052 00053 /// TLI - Keep a pointer of a TargetLowering to consult for determining 00054 /// target type sizes. 00055 const TargetLoweringBase *TLI; 00056 const Triple Trip; 00057 00058 Function *F; 00059 Module *M; 00060 00061 DominatorTree *DT; 00062 00063 /// Layout - Mapping of allocations to the required SSPLayoutKind. 00064 /// StackProtector analysis will update this map when determining if an 00065 /// AllocaInst triggers a stack protector. 00066 SSPLayoutMap Layout; 00067 00068 /// \brief The minimum size of buffers that will receive stack smashing 00069 /// protection when -fstack-protection is used. 00070 unsigned SSPBufferSize; 00071 00072 /// VisitedPHIs - The set of PHI nodes visited when determining 00073 /// if a variable's reference has been taken. This set 00074 /// is maintained to ensure we don't visit the same PHI node multiple 00075 /// times. 00076 SmallPtrSet<const PHINode *, 16> VisitedPHIs; 00077 00078 /// InsertStackProtectors - Insert code into the prologue and epilogue of 00079 /// the function. 00080 /// 00081 /// - The prologue code loads and stores the stack guard onto the stack. 00082 /// - The epilogue checks the value stored in the prologue against the 00083 /// original value. It calls __stack_chk_fail if they differ. 00084 bool InsertStackProtectors(); 00085 00086 /// CreateFailBB - Create a basic block to jump to when the stack protector 00087 /// check fails. 00088 BasicBlock *CreateFailBB(); 00089 00090 /// ContainsProtectableArray - Check whether the type either is an array or 00091 /// contains an array of sufficient size so that we need stack protectors 00092 /// for it. 00093 /// \param [out] IsLarge is set to true if a protectable array is found and 00094 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 00095 /// multiple arrays, this gets set if any of them is large. 00096 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 00097 bool InStruct = false) const; 00098 00099 /// \brief Check whether a stack allocation has its address taken. 00100 bool HasAddressTaken(const Instruction *AI); 00101 00102 /// RequiresStackProtector - Check whether or not this function needs a 00103 /// stack protector based upon the stack protector level. 00104 bool RequiresStackProtector(); 00105 00106 public: 00107 static char ID; // Pass identification, replacement for typeid. 00108 StackProtector() 00109 : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) { 00110 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 00111 } 00112 StackProtector(const TargetMachine *TM) 00113 : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()), 00114 SSPBufferSize(8) { 00115 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 00116 } 00117 00118 void getAnalysisUsage(AnalysisUsage &AU) const override { 00119 AU.addPreserved<DominatorTreeWrapperPass>(); 00120 } 00121 00122 SSPLayoutKind getSSPLayout(const AllocaInst *AI) const; 00123 void adjustForColoring(const AllocaInst *From, const AllocaInst *To); 00124 00125 bool runOnFunction(Function &Fn) override; 00126 }; 00127 } // end namespace llvm 00128 00129 #endif // LLVM_CODEGEN_STACKPROTECTOR_H