Provide a pass which mitigates speculative execution attacks which operate by speculating incorrectly past some predicate (a type check, bounds check, or other condition) to reach a load with invalid inputs and leak the data accessed by that load using a side channel out of the speculative domain.
More...
|
| STATISTIC (NumCondBranchesTraced, "Number of conditional branches traced") |
|
| STATISTIC (NumBranchesUntraced, "Number of branches unable to trace") |
|
| STATISTIC (NumAddrRegsHardened, "Number of address mode used registers hardaned") |
|
| STATISTIC (NumPostLoadRegsHardened, "Number of post-load register values hardened") |
|
| STATISTIC (NumCallsOrJumpsHardened, "Number of calls or jumps requiring extra hardening") |
|
| STATISTIC (NumInstsInserted, "Number of instructions inserted") |
|
| STATISTIC (NumLFENCEsInserted, "Number of lfence instructions inserted") |
|
static MachineBasicBlock & | splitEdge (MachineBasicBlock &MBB, MachineBasicBlock &Succ, int SuccCount, MachineInstr *Br, MachineInstr *&UncondBr, const X86InstrInfo &TII) |
|
static void | canonicalizePHIOperands (MachineFunction &MF) |
| Removing duplicate PHI operands to leave the PHI in a canonical and predictable form.
|
|
static bool | hasVulnerableLoad (MachineFunction &MF) |
| Helper to scan a function for loads vulnerable to misspeculation that we want to harden.
|
|
static const TargetRegisterClass * | getRegClassForUnfoldedLoad (MachineFunction &MF, const X86InstrInfo &TII, unsigned Opcode) |
| Compute the register class for the unfolded load.
|
|
static bool | isEFLAGSDefLive (const MachineInstr &MI) |
|
static bool | isEFLAGSLive (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const TargetRegisterInfo &TRI) |
|
| INITIALIZE_PASS_BEGIN (X86SpeculativeLoadHardeningPass, PASS_KEY, "X86 speculative load hardener", false, false) INITIALIZE_PASS_END(X86SpeculativeLoadHardeningPass |
|
|
static cl::opt< bool > | EnableSpeculativeLoadHardening ("x86-speculative-load-hardening", cl::desc("Force enable speculative load hardening"), cl::init(false), cl::Hidden) |
|
static cl::opt< bool > | HardenEdgesWithLFENCE (PASS_KEY "-lfence", cl::desc("Use LFENCE along each conditional edge to harden against speculative " "loads rather than conditional movs and poisoned pointers."), cl::init(false), cl::Hidden) |
|
static cl::opt< bool > | EnablePostLoadHardening (PASS_KEY "-post-load", cl::desc("Harden the value loaded *after* it is loaded by " "flushing the loaded bits to 1. This is hard to do " "in general but can be done easily for GPRs."), cl::init(true), cl::Hidden) |
|
static cl::opt< bool > | FenceCallAndRet (PASS_KEY "-fence-call-and-ret", cl::desc("Use a full speculation fence to harden both call and ret edges " "rather than a lighter weight mitigation."), cl::init(false), cl::Hidden) |
|
static cl::opt< bool > | HardenInterprocedurally (PASS_KEY "-ip", cl::desc("Harden interprocedurally by passing our state in and out of " "functions in the high bits of the stack pointer."), cl::init(true), cl::Hidden) |
|
static cl::opt< bool > | HardenLoads (PASS_KEY "-loads", cl::desc("Sanitize loads from memory. When disable, no " "significant security is provided."), cl::init(true), cl::Hidden) |
|
static cl::opt< bool > | HardenIndirectCallsAndJumps (PASS_KEY "-indirect", cl::desc("Harden indirect calls and jumps against using speculatively " "stored attacker controlled addresses. This is designed to " "mitigate Spectre v1.2 style attacks."), cl::init(true), cl::Hidden) |
|
| PASS_KEY |
|
X86 speculative load | hardener |
|
X86 speculative load | false |
|
Provide a pass which mitigates speculative execution attacks which operate by speculating incorrectly past some predicate (a type check, bounds check, or other condition) to reach a load with invalid inputs and leak the data accessed by that load using a side channel out of the speculative domain.
For details on the attacks, see the first variant in both the Project Zero writeup and the Spectre paper: https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html https://spectreattack.com/spectre.pdf
Definition in file X86SpeculativeLoadHardening.cpp.
Removing duplicate PHI operands to leave the PHI in a canonical and predictable form.
FIXME: It's really frustrating that we have to do this, but SSA-form in MIR isn't what you might expect. We may have multiple entries in PHI nodes for a single predecessor. This makes CFG-updating extremely complex, so here we simplify all PHI nodes to a model even simpler than the IR's model: exactly one entry per predecessor, regardless of how many edges there are.
Definition at line 326 of file X86SpeculativeLoadHardening.cpp.
References llvm::SmallPtrSetImplBase::clear(), llvm::SmallVectorBase< Size_T >::empty(), llvm::SmallPtrSetImpl< PtrType >::insert(), MBB, MI, llvm::SmallVectorImpl< T >::pop_back_val(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().