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