Home | History | Annotate | Download | only in CodeGen
      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