On the Effectiveness of Hardware Mitigations Against Cross-Privilege Spectre-v2 Attacks
BHI (or Spectre-BHB) is a revival of cross-privilege Spectre-v2 attacks on modern systems deploying in-hardware defenses. And we have a very neat end-to-end exploit leaking arbitrary kernel memory on modern Intel CPUs to prove it (PoC||GTFO right?). We started asking ourselves if hardware Spectre-v2 mitigations (Intel eIBRS and Arm CSV2) delivered on their promises of isolating different privilege domains in speculative execution land. The answer is “kind of”. They did deliver some isolation, but the isolation is incomplete. Hence, our kernel exploit:
Let’s rewind a bit and understand what happened.
Back in the days when Spectre was found, you could easily exploit Branch Target Injection (BTI or Spectre-v2), the most dangerous Spectre variant, across privilege levels. For example, an unprivileged userland attacker could feed any branch target to the indirect branch predictor from userland and trick the kernel into speculatively jumping into the injected target code location and executing the code found there.
Upon Spectre disclosure, software vendors such as Linux deployed stopgap mitigations in software (i.e., retpoline). But such mitigations were slow. Fast forward a couple of years and Intel and Arm release efficient hardware mitigations (i.e., eIBRS and CSV2) to prevent such trivial BTI exploits. These solutions are complex—read the paper to learn more about them—but the gist of them is that the predictor “somehow” keeps track of the privilege level (user/kernel) in which a target is executed. And, as you may expect, if the target belongs to a lower privilege level, kernel execution won’t use it (i.e., no more arbitrary attacker-provided code locations to speculatively hijack the kernel control flow into).
Here is where BHI comes into play. Branch History Injection (BHI or Spectre-BHB) is a new flavor of Spectre-v2 in that it can circumvent eIBRS and CSV2 to simplify cross-privilege mistraining. The hardware mitigations do prevent the unprivileged attacker from injecting predictor entries for the kernel. However, the predictor relies on a global history to select the target entries to speculatively execute. And the attacker can poison this history from userland to force the kernel to mispredict to more “interesting” kernel targets (i.e., gadgets) that leak data.
The implications of our exploits are even broader, though. In our paper, we not only show that BHI re-enables cross-privilege Spectre-v2 exploits, but that the underlying assumption that same-privilege-level attacks are unfeasible is flawed. In fact, we also demonstrate the feasibility of kernel-to-kernel (so-called intra-mode BTI) exploits, in which an attacker performs no injection of the branch history from userland.
Our Branch History Injection paper (PDF) is accepted for publication at the 31th USENIX Security Symposium 2022.
- RE Code, testing tools and exploit code
- Security advisories:
How does this differ from Spectre-v2?
BHI essentially is an extension of Spectre v2, where we leverage the global history to re-introduce the exploitation of cross-privilege BTI. Therefore the attacker primitive is still Spectre v2, but by injecting the history across privilege boundaries (BHI), we can exploit systems that deploy new in-hardware mitigations (i.e., Intel eIBRS and Arm CSV2).
I heard about Spectre-BHB, BHI, intra-mode BTI. What’s the difference?
We know the naming is a bit of a mess. In our defense, we made an effort to keep the naming as sensible as possible for the community (and clearly failed). We initially called our primitive Spectre-BHB since it was “Spectre-v2 aided by the Branch History Buffer (BHB)”.
This primitive for Spectre-v2 mistraining can be exercised inter-mode (e.g., user→kernel) and also intra-mode (e.g., kernel→kernel). Intel proposed two names for the two attack models: they use Branch History Injection (BHI) to define the inter-mode history mistraining (CVE-2022-0001); and intra-mode BTI for exploits in which the specific branches used for mistraining and misprediction are located in the same privilege domain, regardless of the Branch History (CVE-2022-0002).
Arm still relies on our initial naming convention, i.e., Spectre-BHB (CVE-2022-23960). That is, Spectre-BHB == BHI == cross-mode history injection. For the intra-mode history injection, Arm uses the name kernel-only Spectre-BHB.
As such, kernel-only Spectre-BHB and intra-mode BTI are slightly different: the first describes the possibility of history injection directly in the kernel, while the latter only describes same-mode Spectre-v2 attacks—whatever the means of mistraining.
Are Intel eIBRS and Arm CSV2 broken?
Sort of. That is, the mitigations work as intended, but the residual attack surface is much more significant than vendors originally assumed. Arm even alludes in its documentation that the indirect branch predictor can be controlled with CSV2 “only in a hard-to-determine way” (suggesting there is margin for attackers). Nevertheless, finding exploitable gadgets is harder than before since the attacker can’t directly inject predictor targets across privilege boundaries. That is, the kernel won’t speculatively jump to arbitrary attacker-provided targets, but will only speculatively execute valid code snippets it already executed in the past. As a result, the attacker can mistrain via BHI, but can’t force the kernel to jump to arbitrary code locations.
Which systems are affected by BHI?
Short answer: If you have an Intel or Arm CPU that was affected by Spectre-v2, you’re likely to be affected by BHI too. AMD seems not to be affected.
Long answer: Intel says most of their CPUs are affected apart from their Atom CPU family (full list available in their whitepaper). And they’re releasing software solutions to protect against BHI (CVE-2022-0001) and intra-mode BTI (CVE-2022-0002).
Arm listed all their affected processors in their advisory: Cortex-A15, Cortex-A57, Cortex-A72, Cortex-A73, Cortex-A75, Cortex-A76, Cortex-A76AE, Cortex-A77, Cortex-A78, Cortex-A78AE, Cortex-A78C, Cortex-X1, Cortex-X2, Cortex-A710, Neoverse N1, Neoverse N2, and Neoverse V1. They released 5 different mitigations depending on the system. Check their advisory for more information.
Are kernel-to-kernel attacks practical?
We believe so. In our work we showcase a complete kernel-to-kernel exploit abusing eBPF. But let’s be clear, eBPF is just a tool, not the underlying problem. We believe equally powerful exploits may be possible abusing leak gadgets already present in the kernel and not JIT’ed by an unprivileged attacker. In the past, we developed Kasper: a framework that looks for exploitable Spectre-v1, MDS, and LVI gadgets in the kernel. Kasper demonstrates that automated gadget scanners can easily uncover a new attack surface that escapes manual code audits. Similarly, more gadget scanning work is needed to find exploitable non-eBPF Spectre-v2 gadgets.
So, is disabling unprivileged eBPF sufficient?
As hinted in the answer above, we believe this is not the case. However, we believe unprivileged eBPF does tremendously facilitate speculative execution (and other) attacks. Hence, we recommend disabling it. Most Linux distributions have been taking this path in the past few months after our disclosure and other vulnerabilities. You can simply verify that you system has unprivileged eBPF disabled by looking at
Are there any official security advisories and CVEs?
Intel released a whitepaper and a security advisory describing the issues. It also assigned CVE-2022-0001 to BHI and CVE-2022-0002 to intra-mode BTI.
Arm also released a whitepaper and assigned CVE- 2022-23960 to both issues.
We thank the anonymous reviewers for their valuable comments. We also thank Alyssa Milburn and Andrew Cooper for their feedback. This work was supported by the EU’s Horizon 2020 research and innovation programme under grant agreement No. 825377 (UNICORE), by Intel Corporation through the Side Channel Vulnerability ISRA, and by Netherlands Organisation for Scientific Research through projects “TROPICS”, “Theseus”, and “Intersect”.