Arxiv:1905.10311V4 [Cs.CR] 10 Mar 2020
Total Page:16
File Type:pdf, Size:1020Kb
SpecFuzz Bringing Spectre-type vulnerabilities to the surface Oleksii Oleksenko†, Bohdan Trach†, Mark Silberstein‡, and Christof Fetzer† †TU Dresden, ‡ Technion Abstract This observation led to the development of software tools SpecFuzz is the first tool that enables dynamic testing for for Spectre mitigation. They identify the code snippets pur- speculative execution vulnerabilities (e.g., Spectre). The key ported to be vulnerable to the Spectre attacks and instrument is a novel concept of speculation exposure: The program is them to prevent or eliminate unsafe speculation. Inherently, instrumented to simulate speculative execution in software by the instrumentation incurs runtime overheads, thereby leading forcefully executing the code paths that could be triggered due to the apparent tradeoff between security and performance. to mispredictions, thereby making the speculative memory Currently, all the existing tools exercise only the extreme accesses visible to integrity checkers (e.g., AddressSanitizer). points in this tradeoff, offering either poor performance with Combined with the conventional fuzzing techniques, specula- high security, or poor security with high performance. tion exposure enables more precise identification of potential Specifically, conservative techniques [3, 21, 28, 53] pes- vulnerabilities compared to state-of-the-art static analyzers. simistically harden every speculatable instruction (e.g., every Our prototype for detecting Spectre V1 vulnerabilities suc- conditional branch) to either prevent the speculation or make cessfully identifies all known variations of Spectre V1 and it provably benign. This approach is secure, but may signifi- decreases the mitigation overheads across the evaluated appli- cantly hurt program performance [44]. cations, reducing the amount of instrumented branches by up On the other hand, static analysis tools [17, 27, 41] reduce to 77% given a sufficient test coverage. the performance costs by instrumenting only known Spectre gadgets—the code patterns that are typical for the attacks. 1 Introduction However, the analysis is imprecise and may overlook vulner- abilities, either because the vulnerable code does not match Spectre [22, 33, 34, 48] is a class of attacks that poses a sig- the expected patterns [32], or due to the limitations of the nificant threat to system security. It is a microarchitectural analysis itself (e.g., considers each function only in isolation). attack, an attack where a malicious actor extracts secrets by We seek to build a tool that exercises a different point on exploiting security flaws in the CPU architecture rather than the security-performance tradeoff curve by eliding unneces- in software. Such attacks are particularly dangerous as they sary instrumentation without restricting ourselves to specific compromise the security of bug-free programs. gadgets. Arguably, a key challenge is to precisely identify arXiv:1905.10311v4 [cs.CR] 10 Mar 2020 Spectre-type microarchitectural attacks exploit branch spec- vulnerable code regions, yet this task is hard to achieve via ulations to access victim’s memory. For example, if an array static analysis. Instead, in this work we harness dynamic access is guarded by an index bounds check, the CPU branch testing (e.g., fuzzing) to detect Spectre-type vulnerabilities. predictor might speculate that the check will pass and thus Fuzzing [63] is a well-established testing technique. The perform the memory access before the index is validated. If basic idea of fuzzing is simple: Add integrity checks to the the speculation turns out to be wrong, the CPU rolls back the tested software (e.g., with AddressSanitizer [49]) and feed it respective changes in the architectural state (e.g., in registers), with randomized inputs to find cases that trigger a bug. This but it does not cleanse its microarchitectural state (e.g., cached technique is commonly used to detect stability issues and data). Spectre-type attacks use this property to exfiltrate the memory errors [50]. results of computations executed on this mispredicted path. In principle, Spectre-type attacks effectively perform unau- Unfortunately, many variants of Spectre hardware vulner- thorized accesses to data via out-of-bound reads, thus they abilities are not expected to be fixed by hardware vendors, are supposed to be caught via fuzzing. Unfortunately, this is most notably Intel [18]. Therefore, the burden of protecting not the case because the accesses are invoked speculatively, programs lies entirely on software developers [40]. on a mispredicted path, therefore are discarded by hardware 1 i = input[0]; without being exposed to software. As a result, they remain 2 if (i < size) { invisible to runtime integrity checkers. 3 secret = foo[i]; We introduce speculation exposure, the first technique to 4 baz = bar[secret]; } enable dynamic testing for Spectre-type vulnerabilities. Spec- ulation exposure leverages software simulation of speculative Figure 1: A potential Bounds Check Bypass vulnerability. paths to turn speculative vulnerabilities into conventional ones and, thus, make them detectable by memory safety checkers. The concept is generic and can be applied to different Spectre brary, and improves the performance of hardened OpenSSL attacks. RSA function, resulting in only 3% slowdown over its vanilla Speculation exposure consists of four phases executed for version, compared to the 22% slower conservative hardening. every speculatable instruction: 1 take a checkpoint of the Our contributions include: process state, 2 simulate a misprediction, 3 execute the speculative path, and 4 rollback the process to the checkpoint • Speculation exposure, a generic simulation method for and continue normal execution. This way, we temporarily Spectre-type vulnerabilities that makes them detectable redirect the normal application flow into the speculative path through dynamic testing. so that all invalid memory accesses on it become visible to • SpecFuzz, an implementation of the method applied to software. This method simulates the worst-case scenario by detection of Bounds Check Bypass vulnerabilities. examining each possible mispredicted path, without making • A fuzzing strategy that makes nested speculative expo- assumptions about the way the underlying hardware decides sure feasible by prioritizing the paths that are the most whether to speculate or not. likely to contain vulnerabilities. We further extend speculation exposure to nested specu- lation, which occurs when a CPU begins a new speculation • An analysis technique for processing and ranking the before resolving the previous one. To simulate it, for each results of dynamic testing with SpecFuzz. speculatable instruction, we dynamically generate a tree of • Evaluation of SpecFuzz on a set of popular libraries. all possible speculative paths starting from this instruction and branching on every next speculatable instruction. The complete nested simulation, however, has proven to be too 2 Background slow. To make fuzzing practical we develop a heuristic which prioritizes traversal of the speculation sub-trees with high 2.1 Speculative Execution and Attacks likelihood of detecting new vulnerabilities. To showcase our method, we implement SpecFuzz, a tool Speculative Execution. In modern processors, execution of for detecting Bounds Check Bypass (BCB) vulnerabilities. a single instruction is carried out in several stages, such as SpecFuzz simulates conditional jump mispredictions by plac- fetching, decoding, and reading. To improve performance, ing an additional jump with an inverted condition before every nearly all modern CPUs execute them in a pipelined fashion: conditional jump. During the simulation it executes the in- When one instruction passes a stage, the next instruction can verted jump and then rolls back to return to the original control enter the stage without waiting for the first one to pass all the flow. To detect invalid accesses on the simulated speculative following stages. This allows for much higher levels of in- path, SpecFuzz relies on AddressSanitizer [49]. struction parallelism and for better utilization of the hardware SpecFuzz may serve as a tool for both offensive and de- resources. fensive security. For the former (e.g., penetration testing), However, in certain situations—called hazards—it is not it finds vulnerabilities in software, records their parameters, possible to begin executing the next instruction immediately. and generates test cases. For the latter, the fuzzing results are A hazard may happen in three cases: a structural hazard passed to automated hardening tools (e.g., Speculative Load appears when there are no available execution units, a data Hardening [3]) to elide unnecessary instrumentation of the hazard—when there is a data dependency between the instruc- instructions deemed safe. Note that the code not covered by tions, and control hazard—when the first instruction modifies fuzzing remains instrumented and protected conservatively the control flow (e.g., at a conditional branch) and the CPU as before, hence lower fuzzing coverage might affect perfor- does not know what instruction will run next. As the haz- mance but not security. ards are stalling the CPU, they can significantly reduce its Our evaluation shows that SpecFuzz successfully detects performance. vulnerable gadgets in all test programs. It detects more po- To deal with control hazards (and sometimes, with data tential vulnerabilities than the state-of-the-art and reduces the hazards), modern CPUs try to predict the