LLVM API Documentation

StackProtector.h
Go to the documentation of this file.
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