A new attack that uses processors' speculative-execution capabilities to leak data, named Speculative Store Bypass (SSB), has been published after being independently discovered by Microsoft's Security Response Center and Google Project Zero. Processors from Intel and AMD, along with some of those using ARM's designs, are all affected.

Since the Meltdown and Spectre flaws were announced earlier this year, the speculative and predictive capabilities of modern microprocessors have been closely examined, revealing several new attacks

All the attacks follow a common set of principles. Each processor has an architectural behavior (the documented behavior that describes how the instructions work and that programmers depend on to write their programs) and a microarchitectural behavior (the way an actual implementation of the architecture behaves). These can diverge in subtle ways. For example, architecturally, a program that loads a value from a particular address in memory will wait until the address is known before trying to perform the load. Microarchitecturally, however, the processor might try to speculatively guess at the address so that it can start loading the value from memory (which is slow) even before it's absolutely certain of which address it should use.

If the processor guesses wrong, it will ignore the guessed-at value and perform the load again, this time with the correct address. The architecturally defined behavior is thus preserved. But that faulty guess will disturb other parts of the processor—in particular the contents of the cache. These microarchitectural disturbances can be detected and measured, allowing a malicious program to make inferences about the values stored in memory.

The Meltdown and Spectre attacks all exploit this difference. So, too, does SSB. From Microsoft's write-up of the problem, the problematic sequence of events is as follows:

Store a value at a memory location "slowly." Load the value at the same memory location "quickly." Use the value just read to disturb the cache in a detectable way.

Here, "slowly" and "quickly" refer to how fast the processor can determine the memory location to be read and written from. The trick is to make the first step, the store, depend on the results of previous instructions; this means that the processor has to wait before it knows where to store the value. The second step, the load, is, in contrast, constructed in such a way that the address can be determined quickly, without waiting. In this situation, the processor's speculative execution will "ignore" or "bypass" the store (because it doesn't yet know where the value is actually being stored) and just assume that the data currently held at the memory location is valid. This gives the attack its name: the store is speculatively bypassed, enabling the processor to be tricked into reading values that it shouldn't.

Eventually the processor will figure out that the store and the load used the same memory address, thus the load picked up the wrong value. The speculative execution is discarded and the correct calculation performed with the correct values. The architectural behavior is therefore properly preserved. But at this point the microarchitectural state of the processor has already been changed. These changes can be detected, and an attacker can use those changes to figure out which value was read.

Good news and bad news

As with Spectre and Meltdown, SSB requires the attacker to be able to run code on a victim system. This makes it a particular concern for cloud service providers (where a malicious party might try to attack the hypervisor and break out of their virtual machine) and for browser JavaScript engines (where malicious scripts might try to break out of their sandbox), but conversely, it means that outside of these scenarios the scope is limited. Generally, the need to be able to run arbitrary attack code in the first place means that one or more other flaws must already exist. Similarly, this attack only permits data to be read. While occasionally that data is itself useful (for example, passwords or encryption keys), more often it will simply be providing additional information (such as details on the layout of kernel memory) to help perform another attack using some other flaw.

In terms of risk and exploitability, this attack is similar to the first Spectre variant. The first Spectre variant, the array-bounds bypass, uses a similar pattern of two operations in sequence (for SSB, a store then a load; for Spectre v1, a branch then a load), where the first operation architecturally changes the outcome of the load but is speculatively executed as if it doesn't. This structural similarity means that the same application-level modifications that address Spectre v1 also address SSB. Specifically, at-risk applications should insert an extra instruction between the first operation and the load operation to prevent the load from being performed speculatively. This is not necessarily the only way of making an application safe, but it's a consistent and relatively easy-to-apply one. Blocking the speculative execution will reduce program performance somewhat, but if applied judiciously—because not every load is at risk—the impact can be negligible.

We're also going to see a barrage of operating system, microcode, and firmware updates, just as we did for the second Spectre variant. Recent AMD processors include a feature to disable this particular kind of speculative execution, and Microsoft is going to release Windows patches that permit this feature to be used. Intel is releasing microcode updates that provide its processors with a similar facility to disable this kind of speculation. These will eventually be distributed as firmware and operating system updates.

In both cases, however, the companies are recommending that users not turn on this system-wide option. The performance impact can be quite high—Intel says between two and eight percent reduction in benchmarks such as SYSmark and SPECint—and so modifications to at-risk applications is the better solution. The system-wide change is a fallback if that's not possible.