From 8e3c7f6cf649a94dbe8ad61c7534500eb3fac490 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 19 Jul 2018 23:46:24 +0000 Subject: [PATCH] [x86/SLH] Clean up helper naming for return instruction handling and remove dead declaration of a call instruction handling helper. This moves to the 'harden' terminology that I've been trying to settle on for returns. It also adds a really detailed comment explaining what all we're trying to accomplish with return instructions and why. Hopefully this makes it much more clear what exactly is being "hardened". Differential Revision: https://reviews.llvm.org/D49571 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337510 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86SpeculativeLoadHardening.cpp | 30 ++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86SpeculativeLoadHardening.cpp b/lib/Target/X86/X86SpeculativeLoadHardening.cpp index 54ceaae1df0..4b232748ba3 100644 --- a/lib/Target/X86/X86SpeculativeLoadHardening.cpp +++ b/lib/Target/X86/X86SpeculativeLoadHardening.cpp @@ -192,8 +192,7 @@ private: SmallPtrSetImpl &HardenedInstrs); bool canHardenRegister(unsigned Reg); void hardenPostLoad(MachineInstr &MI); - void checkReturnInstr(MachineInstr &MI); - void checkCallInstr(MachineInstr &MI); + void hardenReturnInstr(MachineInstr &MI); }; } // end anonymous namespace @@ -529,7 +528,7 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction( if (!MI.isReturn()) continue; - checkReturnInstr(MI); + hardenReturnInstr(MI); } LLVM_DEBUG(dbgs() << "Final speculative load hardened function:\n"; MF.dump(); @@ -1969,7 +1968,30 @@ void X86SpeculativeLoadHardeningPass::hardenPostLoad(MachineInstr &MI) { ++NumPostLoadRegsHardened; } -void X86SpeculativeLoadHardeningPass::checkReturnInstr(MachineInstr &MI) { +/// Harden a return instruction. +/// +/// Returns implicitly perform a load which we need to harden. Without hardening +/// this load, an attacker my speculatively write over the return address to +/// steer speculation of the return to an attacker controlled address. This is +/// called Spectre v1.1 or Bounds Check Bypass Store (BCBS) and is described in +/// this paper: +/// https://people.csail.mit.edu/vlk/spectre11.pdf +/// +/// We can harden this by introducing an LFENCE that will delay any load of the +/// return address until prior instructions have retired (and thus are not being +/// speculated), or we can harden the address used by the implicit load: the +/// stack pointer. +/// +/// If we are not using an LFENCE, hardening the stack pointer has an additional +/// benefit: it allows us to pass the predicate state accumulated in this +/// function back to the caller. In the absence of a BCBS attack on the return, +/// the caller will typically be resumed and speculatively executed due to the +/// Return Stack Buffer (RSB) prediction which is very accurate and has a high +/// priority. It is possible that some code from the caller will be executed +/// speculatively even during a BCBS-attacked return until the steering takes +/// effect. Whenever this happens, the caller can recover the (poisoned) +/// predicate state from the stack pointer and continue to harden loads. +void X86SpeculativeLoadHardeningPass::hardenReturnInstr(MachineInstr &MI) { MachineBasicBlock &MBB = *MI.getParent(); DebugLoc Loc = MI.getDebugLoc(); auto InsertPt = MI.getIterator(); -- 2.11.0