8

I have understood that Spectre works mainly by exploiting the branch predictor state. Bounds check bypass and branch target injection are two faces of the same coin, the interaction of speculative execution with the branch predictor.

Now, immediately when hearing this I thought we need an instruction to clear the branch predictor state. Such an instruction could be used when switching context from user space to kernel space or vice versa or between two user space processes.

Apparently I am not alone in this. Mark has an excellent answer to the question Just how bad is Spectre? and Mark proposes the same thing. This has also been proposed at Real World Tech discussion forums.

Is this however a complete fix to Spectre? What about VMs such as JVMs that need to run untrusted code in the same user space process that runs also trusted code? Could the instruction help in securing such VMs?

juhist
  • 273
  • 1
  • 6
  • 1
    It doesn't work by exploiting the branch predictor state. The branch is just a tool used to cause the CPU to not actually finish executing the instructions that read from read protected memory so that the program doesn't crash like it should. The worse the branch prediction is the easier it is to exploit Spectre. The true flaw is that the CPU doesn't check if memory reads are legal until speculative instructions complete execution. – Alex Cannon Feb 09 '18 at 03:05

1 Answers1

7

A predictor-flush instruction is necessary but not sufficient for protection from Spectre. A full protection against the Spectre attack requires two things:

  1. Flushing the branch predictor state on context switch. This prevents one process from attacking another by giving each process its own branch-predictor state. It does not, however, prevent a sandboxed component of a process (such as JIT-compiled Javascript) from attacking other components of the same process.
  2. Branch predictor state must take the full address of the branch instruction into account (currently, to save space, only the low-order bits are used). This will prevent a process from attacking itself, since different parts of the process must have different addresses. It does not, however, prevent one process from attacking another, since different processes may use the same address.
Mark
  • 34,390
  • 9
  • 85
  • 134
  • The first is fairly easy, an instruction in the kernel's `entry_64.S` or so to flush the branch predictor cache would work. – forest Jan 05 '18 at 10:54
  • @forest, it requires that the CPU *have* a "flush branch predictor" instruction. If x86 or x86-64 has one, I'm not seeing it in the instruction set reference. – Mark Jan 05 '18 at 19:10
  • I don't see how clearing the branch predictor on a context switch would do anything useful against Spectre, since a process could execute a loop many times so as to execute a valid fetch, and then "not execute" an invalid fetch. – supercat Jan 06 '18 at 00:09
  • Part 2 may fix Spectre, but it does not fully prevent branch predictor side channel attacks within the same process. – user253751 Apr 29 '18 at 23:12