Files
llvm-6502/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
Tom Roeder 63dea2c952 Add Forward Control-Flow Integrity.
This commit adds a new pass that can inject checks before indirect calls to
make sure that these calls target known locations. It supports three types of
checks and, at compile time, it can take the name of a custom function to call
when an indirect call check fails. The default failure function ignores the
error and continues.

This pass incidentally moves the function JumpInstrTables::transformType from
private to public and makes it static (with a new argument that specifies the
table type to use); this is so that the CFI code can transform function types
at call sites to determine which jump-instruction table to use for the check at
that site.

Also, this removes support for jumptables in ARM, pending further performance
analysis and discussion.

Review: http://reviews.llvm.org/D4167



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221708 91177308-0d34-0410-b5e6-96231b3b80d8
2014-11-11 21:08:02 +00:00

124 lines
4.2 KiB
C++

//===-- 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 <string>
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);
virtual ~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<Instruction *, 64> 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<FunctionType *, CFIConstants> 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