|Vulnerability||CVE||UEFI Impact||UEFI Mitigation|
|Bounds Check Bypass||2017-5753||SMM||LFENCE after validation of untrusted data but before use|
|Branch Target Injection||2017-5715||SMM||RSB stuffing before RSM|
|Rogue Data Cache Load||2017-5754||None||No impact|
|Rogue System Register Read||2018-3640||None||No impact|
|Speculative Store Bypass||2018-3639||None||No impact|
- Firmware developers:
- Unified Extensible Firmware Interface (UEFI) firmware developers
- BIOS vendors
- Original Equipment Manufacturer (OEM) firmware developers
- Contributors to TianoCore*
- Consumers of UEFI firmware:
- Windows* operating system (OS) interface developers
- Linux* OS interface developers
This provides specific guidance for firmware based upon the EFI Developer Kit II (EDKII) and coreboot*. Because this document deals with host firmware internal requirements, it is not intended to provide side channel mitigation guidance for general application developers.
This addresses bare-metal firmware runtime risks and mitigation suggestions for the bounds check bypass, branch target injection, rogue data cache load, rogue system register read, and speculative store bypass side channel methods. Our examples and context are primarily focused on ring 0 firmware runtimes (for example: EFI Developer Kit II, PI SMM, and coreboot SMM). Other firmware execution environments are out of scope.
Side channel methods are techniques that may allow a malicious actor to obtain secret or privileged information that they would not normally be able to access through observing the system, such as by measuring the system’s microarchitectural properties.
Figure 1 below describes the various phases of UEFI style firmware. Refer to the UEFI specification for complete details. Typically, host firmware hands off from an OEM-extensible boot service domain. This is the reset through the ROM stage / RAM stage on coreboot, and the PEI/DXE phase on UEFI. Only the system board vendor should run code in this OEM-extensible boot service domain. After the OEM-extensible domain ends (for example, the EndOfDxe event in UEFI), the firmware flow progresses to a third-party-extensible boot service domain, and then to the operating system (OS) runtime. The System Management Mode (SMM) is loaded during the OEM-extensible phase, and is hardware-isolated from the OS-hosted runtime domain later in the boot process.
You can see these phases in both UEFI (Figure 1) and coreboot (Figure 2) below.
Figure 1. Phases of UEFI execution
Figure 2. Phases of coreboot execution
Boot firmware has several phases. A boot-service stage runs to completion and does not persist into the OS runtime. In UEFI, the OEM-extensible boot service stage contains the Security (SEC) phase, the Pre-EFI Initialization (PEI) phase, and the Driver eXecution Environment (DXE) phase. The DXE phase terminates with the event EndOfDxe. In coreboot, the OEM-extensible boot service stage contains the coreboot Boot block, the coreboot ROM stage, and the coreboot RAM stage.
Only the system board manufacturers should run code in the OEM-extensible boot service stage. Developers should consider any third-party code injections into the firmware boot service stage to be attacks, because all code in this stage executes in ring 0. You can find more details in the UEFI PI Spec and the coreboot book.
Traditionally, systems are configured to cause SMIs on all logical processors in a system; a rendezvous is done both before and after critical SMM code to ensure that almost all SMM runs while all other logical processors are quiesced. SMM is a separate CPU execution mode that is distinct from real mode, protected mode, and long-mode on Intel® architecture. SMM typically uses sequestered DRAM called System Management RAM (SMRAM) that is isolated from host DRAM and has cacheability attributes described by a model-specific register called the System Management Mode Range Register (SMRR).
For background on SMM, see the Intel® 64 and IA-32 Architectures Software Developer Manuals. SMM is covered in chapter 34 in volume 3. In particular, sections 34.3, 34.4, and 34.13 contain definitions and information that are likely to be useful to developers.
Bounds Check Bypass Mitigation
Bounds check bypass represents a broad class of vulnerabilities that take advantage of the speculative execution used in processors to achieve high performance. To avoid the processor having to wait for data to arrive from memory, or for previous operations to finish, the processor may speculate as to what will be executed. If it is incorrect, the processor will discard the wrong values and then go back and redo the computation with the correct values. At the program level this speculation is invisible, but because instructions were speculatively executed they might leave hints that a local malicious actor can measure, such as which memory locations have been brought into cache.
Using the bounds check bypass method, malicious actors can use code gadgets ("confused deputy" code) to infer data values that have been used in speculative operations. This presents a method to access data in the system cache and/or memory that the malicious actor should not otherwise be able to read.
Because the UEFI SEC, PEI, and DXE phases, as well as the coreboot bootblock, ROM stage, and RAM stage all finish running before any untrusted code can run, we do not suggest any mitigations for these firmware elements.
The SMM infrastructure in EDKII and SMM executes on all cores, suspending the foreground OS execution, making cross-thread exploits more difficult. However, for SMM that processes untrusted data, developers should consider implementing bounds check bypass mitigations like LFENCE.
UEFI firmware runtime code can also have assembly, as low-level critical elements of the implementation may be implemented in assembly for performance, and some of the mode switch code for SMM is written in assembly. Developers should investigate applying the mitigations for bounds check bypass to the assembly or surrounding C code.
A variety of options are available to assist C/C++ Windows* developers in mitigating bounds check bypass. Whichever option is best depends on which compiler/code generation toolchains you are using. Mitigation options include manual mitigation and compiler assisted mitigation. Both the Intel C/C++ compiler and the Microsoft* Visual C++ (MSVC) compiler support generating LFENCE instructions for 32- and 64-bit targets when you manually use the _mm_lfence() intrinsic in the required places. Please refer to Microsoft's public blog for other options.
GCC provides two methods of inserting compiler defenses. The built-in GCC intrinsic is __builtin_ia32_lfence(). The Linux kernel uses asm volatile (“lfence”::: “memory”).
For the OS interface code into the UEFI runtime, the appropriate LFENCE instructions should also be in place for Hal.dll on Windows and Linux.
Branch Target Injection Mitigation
The branch target injection method takes advantage of the indirect branch predictors inside the processor that are used to direct what operations are speculatively executed. By influencing how the indirect branch predictors operate, a malicious actor can cause malicious code to be speculatively executed and then measure the effects such code has on the processor cache/system memory to infer data values.
With an OS that is using retpoline, the UEFI runtime should either be recompiled with retpoline, or should have Indirect Branch Restricted Speculation (IBRS) set beforehand and restore old value afterwards to protect it from branch target injection attacks. An alternative is to use Single Thread Indirect Branch Predictors (STIPB) and Indirect Branch Predictor Barrier (IBPB) instead of IBRS. A microcode update may be required to enumerate IBRS as a hardware feature.
When hardware has implemented IBRS/STIBP/IBPB mitigations, additional mitigations are not needed at the SMM entry point. Refer to the Intel Analysis of Speculative Execution Side Channels technical documentation for further details.
UEFI runtime code is co-located in the OS kernel runtime. The OS cannot tell if the UEFI runtime code has been patched to mitigate side-channel vulnerabilities, as noted on the Linux* kernel mailing list. Therefore, the OS should apply the appropriate mitigations prior to invoking the UEFI runtime since the OS cannot depend upon the firmware to have any mitigations applied. The firmware might apply mitigations itself if the OS has not done so, but the firmware must never disable mitigations that the OS applies.
Certain processors may use branch predictors other than the Return Stack Buffer (RSB) when the RSB underflows. This might impact software using the retpoline mitigation strategy on such processors. On processors with different empty RSB behavior, SMM code should stuff the RSB with CALL instructions before returning from SMM to avoid interfering with non-SMM usage of the retpoline technique. Further details on the relevant processors and the requirements to stuff the RSB are available in the Retpoline: A Branch Target Injection Mitigation technical documentation.
This RSB stuffing would force a jeclear in retpoline following the rsm instruction. SMM does RSB stuffing prior to RSM to protect the OS.
You can implement branch target injection mitigation on Linux* with GCC by compiling with the following compiler switches:
When compiling for processors with different empty RSB behavior, you also need to generate the ret retpolines with the following compiler switches:
For GCC, there is an indirect branch register that enforces an indirect call and jump via register:
Rogue Data Cache Load Mitigation
The rogue data cache load method targets a processor’s speculative data loading mechanisms. Even though the processor’s access control may protect a piece of data, it may still be read speculatively before an illegal access is determined to exist.
Both UEFI and coreboot firmware executes in ring 0, and the operating system should provide these protections.
Rogue System Register Read Mitigation
Rogue system register read uses both speculative execution and side channel cache methods to infer the value of some processor system register state which is not architecturally accessible by the malicious actor. This method uses speculative execution of instructions that read the system register state while the processor is operating at a mode or privilege level that does not architecturally allow the reading of that state.
Malware must be running locally on a system to compromise security using the rogue system register read method. Where applicable, processors may receive microcode updates to ensure that the RDMSR instruction will not speculatively return data. No changes to UEFI or Coreboot are currently planned.
Speculative Store Bypass Mitigation
The speculative store bypass method takes advantage of a performance feature present in many high-performance processors that allows loads to speculatively execute even if the address of a preceding, potentially overlapping store is unknown. Such a case may allow a load to speculatively read a stale data value.
SMM code will behave as if speculative store bypass disable (SSBD) is set regardless of the actual value of the MSR bit. The processor will ensure that a load within SMM code does not speculatively consume stale data values due to bypassing an older store on the same logical processor. A microcode update may be required for SSBD to be enumerated as a hardware feature.
Intel recommends mitigations only for managed runtimes or other situations that use language-based security to guard against attacks within an address space. Refer to the Intel Analysis of Speculative Execution Side Channels technical documentation for further details. No changes to UEFI or Coreboot are currently planned.
General Best Practices
As part of a holistic approach to protect systems, we also recommend following good security development practices (for example, SDL), employing general best practices such as attack surface reduction and defense in depth, and applying updates as soon as is practical.
The latest microcode update must also be included when you release new firmware to ensure that all available mitigations can be used by either the firmware or the OS.
Firmware can also apply defenses that are already available, for example, the Data Execution Prevention (DEP) features in UEFI open source. These features are described in A Tour Beyond BIOS - Memory Protection in UEFI BIOS.
Patches are underway for EDKII and coreboot.
Software Security Guidance Home | Advisory Guidance | Technical Documentation | Best Practices | Resources