//===-- ForwardControlFlowIntegrity.h: Forward-Edge CFI ---------*- C++ -*-===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This pass instruments indirect calls with checks to ensure that these calls // pass through the appropriate jump-instruction table generated by // JumpInstrTables. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H #define LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Pass.h" #include "llvm/Target/TargetOptions.h" #include namespace llvm { class AnalysisUsage; class BasicBlock; class Constant; class Function; class Instruction; class Module; class Value; /// ForwardControlFlowIntegrity uses the information from JumpInstrTableInfo to /// prepend checks to indirect calls to make sure that these calls target valid /// locations. class ForwardControlFlowIntegrity : public ModulePass { public: static char ID; ForwardControlFlowIntegrity(); ForwardControlFlowIntegrity(JumpTable::JumpTableType JTT, CFIntegrity CFIType, bool CFIEnforcing, std::string CFIFuncName); ~ForwardControlFlowIntegrity() override; /// Runs the CFI pass on a given module. This works best if the module in /// question is the result of link-time optimization (see lib/LTO). bool runOnModule(Module &M) override; const char *getPassName() const override { return "Forward Control-Flow Integrity"; } void getAnalysisUsage(AnalysisUsage &AU) const override; private: typedef SmallVector CallSet; /// A structure that is used to keep track of constant table information. struct CFIConstants { Constant *StartValue; Constant *MaskValue; Constant *Size; }; /// A map from function type to the base of the table for this type and a mask /// for the table typedef DenseMap CFITables; CallSet IndirectCalls; /// The type of jumptable implementation. JumpTable::JumpTableType JTType; /// The type of CFI check to add before each indirect call. CFIntegrity CFIType; /// A value that controls whether or not CFI violations cause a halt. bool CFIEnforcing; /// The name of the function to call in case of a CFI violation when /// CFIEnforcing is false. There is a default function that ignores /// violations. std::string CFIFuncName; /// The alignment of each entry in the table, from JumpInstrTableInfo. The /// JumpInstrTableInfo class always makes this a power of two. uint64_t ByteAlignment; /// The base-2 logarithm of ByteAlignment, needed for some of the transforms /// (like CFIntegrity::Ror) unsigned LogByteAlignment; /// Adds checks to each indirect call site to make sure that it is calling a /// function in our jump table. void updateIndirectCalls(Module &M, CFITables &CFIT); /// Walks the instructions to find all the indirect calls. void getIndirectCalls(Module &M); /// Adds a function that handles violations in non-enforcing mode /// (!CFIEnforcing). The default warning function simply returns, since the /// exact details of how to handle CFI violations depend on the application. void addWarningFunction(Module &M); /// Rewrites a function pointer in a call/invoke instruction to force it into /// a table. void rewriteFunctionPointer(Module &M, Instruction *I, Value *FunPtr, Constant *JumpTableStart, Constant *JumpTableMask, Constant *JumpTableSize); /// Inserts a check and a call to a warning function at a given instruction /// that must be an indirect call. void insertWarning(Module &M, BasicBlock *Block, Instruction *I, Value *FunPtr); }; ModulePass * createForwardControlFlowIntegrityPass(JumpTable::JumpTableType JTT, CFIntegrity CFIType, bool CFIEnforcing, StringRef CFIFuncName); } #endif // LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H