118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//===-- StackProtector.h - Stack Protector Insertion ----------------------===//
218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//
318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//                     The LLVM Compiler Infrastructure
418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//
518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// This file is distributed under the University of Illinois Open Source
618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// License. See LICENSE.TXT for details.
718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//
818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//===----------------------------------------------------------------------===//
918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//
1018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// This pass inserts stack protectors into functions which need them. A variable
1118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// with a random value in it is stored onto the stack before the local variables
1218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// are allocated. Upon exiting the block, the stored value is checked. If it's
1318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee// changed, then there was some sort of violation and the program aborts.
1418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//
1518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee//===----------------------------------------------------------------------===//
1618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
1718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#ifndef LLVM_CODEGEN_STACKPROTECTOR_H
1818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#define LLVM_CODEGEN_STACKPROTECTOR_H
1918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
2018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#include "llvm/ADT/SmallPtrSet.h"
2118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#include "llvm/ADT/Triple.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Dominators.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueMap.h"
2418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#include "llvm/Pass.h"
2518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#include "llvm/Target/TargetLowering.h"
2618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
2718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageenamespace llvm {
2818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageeclass Function;
2918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageeclass Module;
3018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageeclass PHINode;
3118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
3218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageeclass StackProtector : public FunctionPass {
334598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Mageepublic:
34ec4b5398c93a855da292589242d7369adc0a54a4NAKAMURA Takumi  /// SSPLayoutKind.  Stack Smashing Protection (SSP) rules require that
354598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// vulnerable stack allocations are located close the stack protector.
364598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  enum SSPLayoutKind {
379794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi    SSPLK_None,       ///< Did not trigger a stack protector.  No effect on data
389794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi                      ///< layout.
399794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi    SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size.  Closest
409794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi                      ///< to the stack protector.
419794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi    SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest
429794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi                      ///< to the stack protector.
439794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi    SSPLK_AddrOf      ///< The address of this allocation is exposed and
449794186889189efaee69a127123fffd26c834fa4NAKAMURA Takumi                      ///< triggered protection.  3rd closest to the protector.
454598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  };
464598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee
474598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// A mapping of AllocaInsts to their required SSP layout.
4862406fdc6f199e4e7df60830be45de4da97b34c7Josh Magee  typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap;
494598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee
504598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Mageeprivate:
5118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  const TargetMachine *TM;
5218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
5318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// TLI - Keep a pointer of a TargetLowering to consult for determining
5418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// target type sizes.
5518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  const TargetLoweringBase *TLI;
5618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  const Triple Trip;
5718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
5818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  Function *F;
5918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  Module *M;
6018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
6118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  DominatorTree *DT;
6218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
634598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// Layout - Mapping of allocations to the required SSPLayoutKind.
644598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// StackProtector analysis will update this map when determining if an
654598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// AllocaInst triggers a stack protector.
664598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  SSPLayoutMap Layout;
674598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee
6818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// \brief The minimum size of buffers that will receive stack smashing
6918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// protection when -fstack-protection is used.
7018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  unsigned SSPBufferSize;
7118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
7218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// VisitedPHIs - The set of PHI nodes visited when determining
7318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// if a variable's reference has been taken.  This set
7418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// is maintained to ensure we don't visit the same PHI node multiple
7518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// times.
7662406fdc6f199e4e7df60830be45de4da97b34c7Josh Magee  SmallPtrSet<const PHINode *, 16> VisitedPHIs;
7718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
7818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// InsertStackProtectors - Insert code into the prologue and epilogue of
7918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// the function.
8018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  ///
8118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  ///  - The prologue code loads and stores the stack guard onto the stack.
8218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  ///  - The epilogue checks the value stored in the prologue against the
8318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  ///    original value. It calls __stack_chk_fail if they differ.
8418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  bool InsertStackProtectors();
8518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
8618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// CreateFailBB - Create a basic block to jump to when the stack protector
8718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// check fails.
8818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  BasicBlock *CreateFailBB();
8918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
9018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// ContainsProtectableArray - Check whether the type either is an array or
9118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// contains an array of sufficient size so that we need stack protectors
9218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// for it.
934598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// \param [out] IsLarge is set to true if a protectable array is found and
944598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// it is "large" ( >= ssp-buffer-size).  In the case of a structure with
954598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  /// multiple arrays, this gets set if any of them is large.
964598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
9718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee                                bool InStruct = false) const;
9818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
9918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// \brief Check whether a stack allocation has its address taken.
10018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  bool HasAddressTaken(const Instruction *AI);
10118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
10218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// RequiresStackProtector - Check whether or not this function needs a
10318ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  /// stack protector based upon the stack protector level.
10418ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  bool RequiresStackProtector();
10562406fdc6f199e4e7df60830be45de4da97b34c7Josh Magee
10618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Mageepublic:
10762406fdc6f199e4e7df60830be45de4da97b34c7Josh Magee  static char ID; // Pass identification, replacement for typeid.
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StackProtector()
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) {
11018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee    initializeStackProtectorPass(*PassRegistry::getPassRegistry());
11118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  }
11218ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  StackProtector(const TargetMachine *TM)
113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()),
11462406fdc6f199e4e7df60830be45de4da97b34c7Josh Magee        SSPBufferSize(8) {
11518ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee    initializeStackProtectorPass(*PassRegistry::getPassRegistry());
11618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  }
11718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void getAnalysisUsage(AnalysisUsage &AU) const override {
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AU.addPreserved<DominatorTreeWrapperPass>();
12018ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee  }
12118ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
1224598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee  SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
1244598b40ce62dceb5ff96bbb7caeebd1ca57ae3feJosh Magee
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool runOnFunction(Function &Fn) override;
12618ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee};
12718ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee} // end namespace llvm
12818ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee
12918ebd48960afe9a4e694dac3ba0ee1002044d297Josh Magee#endif // LLVM_CODEGEN_STACKPROTECTOR_H
130