Bounds Check Bypass / CVE-2017-5753 / INTEL-SA-00088

Published: 01/03/2018

Last Updated: 01/03/2018

 Disclosure date: 2018-01-03 Published date: 2018-01-03 Severity rating: 5.6 Medium Industry-wide severity ratings can be found in the National Vulnerability Database

Aliases

• Spectre Variant 1
• Bounds Check Bypass Store

Overview

This method takes advantage of speculative execution after conditional branch instructions. A malicious actor discovers or causes the creation of “confused deputy” code, which allows the attacker to use speculative operations to infer information not normally accessible to them.

Bounds check bypass uses speculative operations that occur while the processor is checking whether an input is in bounds, such as checking if the index of an array being read is within acceptable values. It takes advantage of memory accesses to out of bound memory that are performed speculatively before the bounds check resolves. These memory accesses can be used in certain circumstances to leak information to the attacker.

If the attacker can identify an appropriate “confused deputy” in a more privileged level, the malicious actor may be able to exploit that deputy to deduce the contents of memory accessible to that deputy but not to the malicious actor.

Bounds Check Bypass Store

One subvariant of this technique, known as bounds check bypass store, uses speculative stores to overwrite younger speculative loads in a way that creates a side channel controlled by a malicious actor. Refer to Analyzing Potential Bounds Check Bypass Vulnerabilities for further details on bounds check bypass store.

Mitigation

Software can insert a speculation stopping barrier between a bounds check and a later operation that could cause a speculative side channel. The LFENCE instruction, or any serializing instruction, can serve as such a barrier. These instructions suffice regardless of whether the bounds checking is implemented using conditional branches or through the use of bound-checking instructions (BNDCL and BNDCU) that are part of the Intel® Memory Protection Extensions (Intel® MPX).

LFENCE

We recommend inserting barriers, like LFENCE and other serializing instructions, to constrain speculation in appropriate locations in your code (refer to Chapter 8.3, Volume 3a of the Intel® 64 and IA-32 Architectures Software Developer Manuals). The LFENCE instruction and other serializing instructions ensure that no later instruction will execute, even speculatively, until all prior instructions have completed locally. LFENCE generally provides better performance and lower latency than other serializing instructions, but still must be used judiciously. Overapplication of LFENCE can compromise performance.

It is possible to create a set of static analysis rules to help find locations in software where speculation barriers might be needed. Our analysis of the Linux* kernel, for example, has only found a handful of places where inserting LFENCE is required, resulting in minimal performance impact. As with all static analysis tools, there are likely to be false positives in the initial results, so we recommend manually inspecting the code as well.

Bounds Clipping

Other instructions such as CMOVccANDADCSBB and SETcc can also be used to prevent bounds check bypass by constraining speculative execution on current family 6 processors (Intel® Core™, Intel® Atom™, Intel® Xeon® and Intel® Xeon Phi™ processors). However, these instructions may not be guaranteed to do so on future Intel processors. Check back for guidance on the usage of instructions to constrain speculation in the future before processors with different behavior are implemented.

Memory disambiguation can theoretically impact such speculation constraining sequences when they involve a load from memory.

In the following example, we insert a CMOVG instruction to prevent a side channel from being created with data from any locations beyond the array bounds.

CMP RDX, [array_bounds]
JG out_of_bounds_input
MOV RCX, 0
MOV RAX, [RDX + 0x400000]
CMOVG RAX, RCX
<... Further code that causes cache movement based on RAX value ... >


For this example, assume the value at array_bounds is 0x20, but that value was only recently stored to array_bounds. Assume that the prior value at array_bounds was significantly higher, such as 0xFFFF.

The processor can execute the CMP instruction speculatively using a value of 0xFFFF for the loaded value due to the memory disambiguation mechanism. The instruction will eventually be re-executed with the intended array bounds of 0x20. This can theoretically cause the above sequence to support the creation of a side channel that reveals information about the memory at addresses up to 0xFFFF instead of constraining it to addresses below 0x20.

Application Developers

Application developers should use the LFENCE and serializing instructions mitigations described above. Refer to the Analyzing Potential Bounds Check Bypass Vulnerabilities white paper for full analysis and mitigation of bounds check bypass.

Front-end Web Developers

Front-end web developers should use the LFENCE and serializing instructions mitigations described above. Refer to the Analyzing Potential Bounds Check Bypass Vulnerabilities white paper for full analysis and mitigation of bounds check bypass.

Runtime Developers

Mitigations include LFENCE for ordering instructions as well as indexing and data clipping. For detailed guidance with code examples, see: Managed Runtime Speculative Execution Side Channel Mitigations.

OS and Driver Developers

Where possible, dedicated operating system programming APIs should be used to mitigate bounds check bypass instead of using open-coded mitigations. Using the OS-provided APIs will help ensure that code can take advantage of new mitigation techniques or optimizations as they become available.

Linux*

The current Linux* kernel mitigation approach to bounds check bypass is described in the speculation.rst file in the Linux kernel documentation. This file is subject to change as developers and multiple processor vendors determine their preferred approaches.

ifence() : on x86 architecture, this issues an LFENCE and provides the compiler with the needed memory barriers to perform the mitigation. It can be used as lfence(), as in the examples above. On non-Intel processors, ifence() either generates the correct barrier code for that processor, or does nothing if the processor does not speculate.

array_ptr(array, index, max): this is an inline that, irrespective of the processor, provides a method to safely dereference an array element. Additionally, it returns NULL if the lookup is invalid. This allows you to take the many cases where you range check and then check that an entry is present, and fold those cases into a single conditional test.

Thus we can turn:

if (handle < 32) { x = handle_table[handle]; if (x) { function(x); return 0; } } return –EINVAL;

Into:

x = array_ptr(handle_table, handle, 32); if (x == NULL) return –EINVAL; function(*x); return 0;

Microsoft* Windows*

Windows C/C++ developers have a variety of options to assist in mitigating bounds check bypass. The best option will depend on the compiler/code generation toolchains you are using. Mitigation options include manual and compiler assisted.

In mixed-mode compiler environments, where object files for the same project are built with different toolchains, there are varying degrees of mitigation options available. Developers need to be aware of and apply the appropriate mitigations depending on their code composition and appropriate toolchain support dependencies.

We recommend inserting LFENCE instructions (either manually or with compiler assistance) for mitigating bounds check bypass on Windows. Refer to Analyzing Potential Bounds Check Bypass Vulnerabilities for details on how to insert the LFENCE instruction using currently available compiler tool chain mechanisms. These mechanisms are (from lowest level to highest level):

• Inline/external assembly
• _mm_lfence() compiler intrinsic
• Compiler automatic LFENCE insertion

Virtual Machine Monitor Developers

VMM developers should apply the OS mitigations described above for their guest OSes. Refer to the Analyzing Potential Bounds Check Bypass Vulnerabilities white paper for full analysis and mitigation of bounds check bypass.

Developers of Software Running in an Enclave

Developers of software designed to run in Intel® Software Guard Extensions (Intel® SGX) should apply the OS mitigations described above for their guest OSes. Refer to the Analyzing Potential Bounds Check Bypass Vulnerabilities white paper for full analysis and mitigation of bounds check bypass.

Bounds check bypass mitigations are not generally relevant if your code doesn’t have secrets that the user shouldn’t be able to access. For example, a simple image viewer probably contains no meaningful secrets that should be inaccessible to software it interacts with. The user of the software could potentially use bounds check bypass attacks to access the image, but they could also just hit the save button.

On the other hand, an image viewer with support for secure, encrypted content with access authorized from a central system might need to care about bounds check bypass because a user may not be allowed to save the document in normal ways. While the user can’t save such an image they can trivially photograph the image and send the photo to someone, so protecting the image may be less important. However, any keys are likely to be far more sensitive.

There are also clear cases like operating system kernels, firmware (refer to the Host Firmware Speculative Execution Side Channel Mitigation technical documentation) and managed runtimes (for example, Javascript* in web browsers) where there is both a significant interaction surface between differently trusted code, and there are secrets to protect.

Whether to apply mitigations, and what areas to target has to be part of your general security analysis and risk modelling, along with conventional security techniques, and resistance if appropriate to timing and other non-speculative side channel attacks. Bounds check bypass mitigations have performance impacts, so they should only be used where appropriate.

References

Product and Performance Information

1

Performance varies by use, configuration and other factors. Learn more at www.Intel.com/PerformanceIndex.