February 2018: Spectre and Meltdown

Welcome to the February 2018 edition of the Embedded Artistry Newsletter! This is a monthly newsletter of curated and original content to help you build better embedded systems. This newsletter is intended to supplement the website and covers topics not mentioned there.

This month we'll cover:

  • Two vulnerabilities that have rocked the computing world: Spectre and Meltdown
    • An overview of speculative execution
    • The Spectre vulnerability
    • The Meltdown vulnerability
    • What you can do today
    • Reliable sources for more information
  • Interesting links from around the web
  • Articles Published in January
  • Most Popular articles in January

A Tale of Two Vulnerabilities: Spectre and Meltdown

The new year did not get off to a great start for the electronics industry. A design flaw in modern processor architectures was exposed with the announcement of two critical vulnerabilities: Spectre and Meltdown. Both attacks are based on speculative execution, a technique in modern process design used to increase performance by pre-loading memory and future CPU instructions. Processor design has been largely focused on improving performance, and unfortunately the security implications of these improvements were not questioned. Spectre and Meltdown show that attackers can exploit speculative execution to access arbitrary memory locations.

Collectively, Spectre and Meltdown affect most processors that are on the market today. While Meltdown is a potentially patchable issue affecting most Intel and some ARM processors, Spectre can only be fully resolved by re-thinking our processor designs.

An Overview of Speculative Execution

Modern processors utilize instruction pipelines, effectively breaking up incoming instructions into sequential stages to keep the processor continually busy. Each pipeline stage handles its part of the current instruction, passes the result to the next stage, then handles the next instruction. This means that a processor effectively is working on multiple instructions in parallel.

The problem with instruction pipelines arises when a conditional branching decision is encountered. Consider the following simple statement:

if(x < 10)
    A();
else
    B();

The condition if(x < 10) must be evaluated before the processor knows whether it needs to call function A() or function B(). The pipeline stalls until the correct path is chosen, and valuable computational cycles are wasted.

Speculative execution is an optimization technique that tries to prevent those wasted computational cycles. Instead of stalling, the processor executes beyond the branch point (e.g. by calling A()) before it knows whether the branch will be taken. If the speculation was correct, then we gained the advantage of not wasting any computational cycles. If it was incorrect, the CPU discards the resulting state and continues executing on the correct path.

Note that the "speculated state" is not discarded until the correct execution path is known. This opens up the mis-speculation window, the time in which the CPU has speculatively executed the wrong code while not detecting that a mis-speculation has occurred.

Compounding with the mis-speculation window is caching, another performance optimization. When data is loaded into memory, caches are updated. If we need to refer to that memory again in the future, we can reduce the access time by fetching that information from the cache instead.

However, once the memory state is rolled back after a mis-speculation is detected, the data for the speculated state is still present in the cache. Clever attackers can take advantage of these speculative execution breadcrumbs to execute code and access memory that is not normally accessible.

There are currently three known variants of speculative execution vulnerabilities:

  1. Bounds check bypass (Spectre)
  2. Branch target injection (Spectre)
  3. Rogue data cache load (Meltdown)

At a high level, the Spectre exploits can be used to trick processors into running instructions they should not have run, granting access to arbitrary memory from another program's memory space. Meltdown applies primarily to Intel processors and can be used to access protected kernel memory in user space.

The Spectre Vulnerability

Spectre's name reflects the vulnerability's root cause (speculative execution) as well as the fact that it will haunt us for years to come. If your processor utilizes speculative execution techniques, you are probably affected. This includes the Intel, AMD, and ARM processors that power our personal computers, smart phones, and cloud servers. There are two primary variants of the Spectre vulnerability: branch target injection and bounds check bypass.

The branch target injection method relies on influencing how a processor's branch predictors operate. By influencing the branch predictors an attacker can control the speculative execution path and ensure that the malicious code is speculatively executed.

The bounds check bypass method takes advantage of speculative execution that occurs while the processor is checking if the targeted memory location is in-bounds. The processor will speculatively access out-of-bounds memory before the bounds check resolves. The attacker can read normally inaccessible memory by using a bounds check bypass combined with an intermediary program or module with better memory access privileges.

The end result is the same: processors inadvertently grant access to arbitrary memory from another program's memory space by running speculative instructions. After the code has been speculatively executed, an attacker can use the caches to reconstruct the target data.

The Meltdown Vulnerability

Meltdown is named for the fact that it "melts" normally enforced security boundaries between user memory and kernel (system) memory. Meltdown affects Intel, Qualcomm, and some ARM cores. Since Intel chips form the basis of many server platforms, most of the cloud service providers are affected by Meltdown.

Meltdown is only possible on processors which allow speculative execution across "privilege boundaries", such as the boundary which separates kernel memory from normal user programs. Normally, direct kernel memory access from user space is expected to fail with a page fault access error. However, certain processors might speculatively access the protected memory and use it for subsequent instructions prior to finishing the permissions check. If the permissions were not correct, a flag would be set and an exception thrown.

However, the kernel memory was still speculatively accessed and available in the cache during the mis-speculation window, allowing kernel memory to be read from user space.

What You Can Do Today

Your system is at risk if someone can run malicious code on your machine. This includes your personal computers, your phone, systems with multiple accounts, servers, cloud platforms, and virtualized environments. If your system is isolated from a network and only has a single user account, you probably don't need to worry about this exploit. If you're unsure of whether or not you need to take action, WindRiver's CEO provided a detailed framework for deciding how to respond.

If you are using an Intel chip or a cloud platform, make sure to stay up to date on patches for your system. The KPTI/KAISER patches for Meltdown have been applied to the latest Linux kernels but may need to be migrated to your specific kernel version. Similar patches have also been made for Windows and OS X. ARM has announced that some of its chips are affected by Meltdown, so check and see if your platform is affected.

Spectre is a trickier beast, especially since most modern processors are affected. A complete resolution is only possible through re-architecting the way processors are designed. We will be living with this threat for many years. Spectre-hardening software efforts are in progress, including ARM speculation barrier, MSVC mitigations, and LLVM mitigations.

Solutions for both of these vulnerabilities will be evolving over time, so be sure to stay up-to-date if you are affected.

Reliable References

The announcement has been surrounded with quite a bit of drama: CERT's initial recommended solution was to "replace CPU hardware", Linus Torvalds called Intel's patches "insane" and "complete garbage", and Intel admitted that its patches for Meltdown and Spectre are flawed.

Given all this drama, here are reliable sources you can refer to for more information:


Around the Web

For some non-Spectre-and-Meltdown news, check out the following articles.

Nordic Semiconductor has announced a new nRF91 chipset targeted for low-power IoT systems. The nRF91 System-inPackage (SiP) integrates an LTE cellular modem and transceiver, ARM Cortex-M33 processor, flash memory, RAM, and power management into a single package.

The Vancouver startup Riot Micro announced the RM1000, a low-power cellular baseband chip targeted for IoT applications.

Michael Barr proposes dropping the term "bug" in "Is it a Bug or an Error?". Jack Ganssle shared similar thoughts in "I've Never Had a Bug in My Code"

A new C++ programming language standard is now available.

Arne Mertz of Simplify C++ published a series on the topic of code reviews. The humble code review is one of the most powerful tools that teams can utilize to improve software quality and reduce errors. How can your team improve its review process?

  1. Code Reviews - Why?
  2. Code Reviews - What?
  3. Code Reviews - Preparation
  4. Code Reviews - How?
  5. Code Reviews - The Human Aspect

Articles Published in January

These posts were added to the website in January:

  1. Implementing an Asynchronous Dispatch Queue With FreeRTOS
  2. Getting Started with Snapdragon Flight: Dev Environment Setup & Useful Resources
  3. Implementing an Asynchronous Dispatch Queue with ThreadX
  4. Implementing malloc with FreeRTOS
  5. Jenkins: Configuring a Linux Slave Node
  6. Installing ROS on an NVIDIA Tegra TX2

Popular Articles

These were the most popular articles in January:

  1. Circular Buffers in C/C++
  2. Installing LLVM/Clang on OSX
  3. C++ Casting, or: Oh No, They Broke Malloc!"
  4. std::string vs C-strings
  5. An Overview of C++ STL Containers
  6. Implementing Malloc: First-fit Free List
  7. Creating and Enforcing a Code Formatting Standard with clang-format
  8. A Simple Consulting Services Agreement
  9. A GitHub Pull Request Template for Your Projects
  10. Implementing an Asynchronous Dispatch Queue

Happy hacking!

-Phillip