StackProtector.h 4.8 KB

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