Meltdown and Spectre. Oh My!
Meador Inge - Fri, 05 Jan 2018

Introduction

Meltdown and Spectre. Oh My!

There have been a lot of new terms floating around the internet these last few days: Meltdown, Spectre, etc... What does it all mean? In this post, I will explain the high-level pieces, what systems are affected by this, and what you can do to better protect yourself against it. For a more technical deep dive of these topics, I strongly recommend reading the linked references.

Explanation

In short, Meltdown [3] and Spectre [4] are exploits that take advantage of features available in modern processors to read data from memory that it otherwise might not be able to.

Currently there are three important CVEs related to this:

  1. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5753

  2. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715

  3. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5754

Spectre covers 1 and 2. Meltdown covers 3. Note that these exploits were discovered independently by Google's Project Zero and the Spectre/Meltdown researchers.

These attacks require that an attacker has the ability to execute code on the target machine. They are possible because processors at times execute instructions out of order or speculatively for performance reasons. This can cause instructions that would otherwise not be executed to execute which can modify the state of the processor cache. All of this works as designed for performance reasons, but leaves the door open to timing-based side channel attacks.

Enter Meltdown and Spectre...

Meltdown

Meltdown exploits a feature of modern processors called out-of-order execution. This is an optimization that allows for a processor to execute operations in an order than is different from their original program order.

Consider the following example from the Meltdown paper:

raise_exception();
// the line below is never reached
access(probe_array[data * 4096]);

Under normal program order, the access(probe_array[data * 4096]) part would never be executed because an exception would be raised first. However, if the processor decides to execute the code out of order, then the code in question will be executed, but the results will be thrown away once the processor figures out that an exception has been raised. Although the results of the computation are thrown away, the processor cache state is still modified. This is an extremely important detail of what makes this attack posssible.

How does Meltdown leverage this? Again consider a code snippet from the Meltdown paper:

; rcx = kernel address
; rbx = probe array
retry:
mov al, byte [rcx]
shl rax, 0xc
jz retry
mov rbx, qword [rbx + rax]

This code would run in user space and the mov al, byte [rcx] instruction accesses a kernel space memory address, which will raise an exception. However, the second move instruction mov rbx, qword [rbx + rax] will be executed out of order and is dependent on the value read out of kernel space memory (in al). This will cause an address that is dependent on the value read from kernel space to be updated in the processor's cache.

At this point, an attacker can use a timing-based side-channel attack on the processor cache to determine the value read from kernel space. In particular, Meltdown uses a Flush+Reload attack that flushes the cache and times memory accesses to determine which addresses have been reloaded. With respect to the previous code snippet, the value of rax could be recovered.

This technique can be used to read any value currently in physical memory -- kernel space or user space. Note that user space values may include values from other processes besides the one running the attack.

Intel processors are definitely susceptible to this attack. The Meltdown researchers attempted to exploit several AMD and ARM processors, but were not successful.

All the major operating systems (Windows, Linux, and OS X) are susceptible. Furthermore, containerized environments such as Docker are susceptible.

Spectre

Spectre exploits a feature of modern processors called speculative execution. This is an optimization where the processor attempts to predict what computations should be done next in the face of branches and speculatively executes them. If the guess was right, then the results of the operation are committed. If the guess was wrong, then the results of the operation are thrown away.

Consider an example from the Spectre paper [3]:

if (x < array1_size)
   y = array2[array1[x] * 256];

With speculative execution, a processor could execute the load from array2[array1[x] * 256] even if x >= array1_size. The results will just be thrown away once it figures out that the branch is not taken. Similar to the Meltdown attack, the processor cache state is still modified if the results are thrown away. Also similar to Meltdown, this is an extremely important detail of what makes this attack posssible.

If an attacker controls the value of x, then it can allow them (like Meltdown) to use a timing-based side-channel attack on the processor cache to read arbitrary memory locations in the address space for the victim process containing the code. Like Meltdown, Spectre uses a Flush+Reload attack. It also has a variant that uses the Evict+Reload attack.

Another variant of Spectre uses indirect branches (e.g. calls through function pointers or virtual functions). It is also interesting to note that this variant takes advantage of an ROP-like approach where "gadgets" in target programs need to be found and manipulated (i.e. the snippet above would be a gadget in a victim program).

Note that unlike Meltdown, Spectre doesn't allow for privilege escalation to read kernel space memory. This is because Meltdown takes advantage of a privilege escalation flaw in Intel hardware that allows for certain speculatively executed instructions to get around memory protection. That being said, the Google Project Zero team did discover a way to read kernel memory using speculative execution and eBPF programs (JITed and non-JITed).

A related, and extremely interesting, result that the Spectre researchers achieved is an attack through JavaScript that allows an attacker to read memory from the browser's address space. Since modern browsers use a JIT compiler, JavaScript code can be written that is JITed to the needed exploit code.

Intel, AMD, and ARM processors are susceptible to this attack.

The attack can be implemented on all major operating systems (Windows, Linux, and OS X).

What can you do?

Long term, the affected hardware flaw should be fixed. We are all at the mercy of the semiconductor companies for this one. Obviously, that will only protect new processors as the currently existing ones containing the flaw cannot be updated.

In the short term, any fixes will need to be made in software. In particular, two areas of software can be modified to help prevent attacks: (1) operating systems and (2) compilers.

The operating system fixes use a KAISER-style approach to enforce a stricter separation between user and kernel address spaces. This is known to stop Meltdown.

The compiler fixes use a method spearheaded by Google that prevents the indirect call variation of Spectre.

Both approaches come with performance implications. In particular, the operating system fixes introduce additional context switch overhead and the compiler features will cause additional overhead for indirect calls. The exact impact is very dependent on the workload and application. If performance is a critical issue for you, then you should perform benchmarks specific to your environment and application for workloads you care about.

See the Fix References section for more details.

Conclusion

These exploits are very serious. They describe concrete weaponizable attacks, as well as set the stage for a whole new area of research into variations and other micro-architecture-based side-channel attacks. Any systems you have control over should be updated ASAP to integrate operating system vendor's patches to prevent Meltdown. Additionally, you should explore and consider using the aforementioned compiler enhancements to help mitigate Spectre attacks for vulnerable applications.

Another take away from all this is that the micro-architecture features that were leveraged to implement these attacks are there strictly for performance reasons. Although in this particular case I can understand how the security implications of these features would be hard to foresee, the trade-off between security and performance is something we should all keep in mind.

So what is the impact moving forward? If the KAISER-style patches truly work as advertised, then patched operating systems should be safe from Meltdown. Spectre, on the other hand, could prove to bear more fruit in the long run due to the application-specific nature of the possible attacks. As time moves on, folks will surely find ways to exploit specific applications to trigger Spectre.

Fix and Advisory References

Hardware

Intel has released:

ARM has released:

Operating Systems

Linux

For Meltdown, a set of Linux kernel patches referred to as KIPT is known to prevent the attack. The patches are still under review and were formally known as KAISER.

Several Linux distributions have been updated or are in the process of pulling these patches in:

  1. https://aws.amazon.com/de/security/security-bulletins/AWS-2018-013/

  2. https://access.redhat.com/security/vulnerabilities/speculativeexecution

  3. https://www.suse.com/c/suse-addresses-meltdown-spectre-vulnerabilities/

Windows

Microsoft has released a Windows Update and the following advisory:

  1. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/ADV180002

iOS and OS X

Apple has released updates and the following support note:

  1. https://support.apple.com/en-us/HT208394

Android

  1. https://source.android.com/security/bulletin/2018-01-01

Compilers

For Spectre, LLVM and GCC are both adding new features to help make the indirect-call variant of the attack more difficult:

  1. https://support.google.com/faqs/answer/7625886

  2. https://reviews.llvm.org/D41723

  3. https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00205.html

  4. https://sourceware.org/ml/binutils/2018-01/msg00030.html

Similar features have also been added to the Arm Compiler:

  1. https://developer.arm.com/support/security-update/compiler-support-for-mitigations

Browsers

  1. Firefox - https://www.mozilla.org/en-US/firefox/57.0.4/releasenotes/

  2. Chrome - https://www.chromium.org/Home/chromium-security/ssca

  3. Microsoft Edge - https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer/

References

  1. https://cyber.wtf/2017/07/28/negative-result-reading-kernel-memory-from-user-mode/

  2. https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html

  3. https://meltdownattack.com/

  4. https://spectreattack.com/

  5. https://gruss.cc/files/kaiser.pdf

  6. https://lkml.org/lkml/2017/12/4/709