[PowerPC] Recommit r340016 after fixing the reported issue
[llvm-core.git] / docs / SpeculativeLoadHardening.md
blobbf5c7d354fefec4b8b9e758c0aedbd3528b2e211
1 # Speculative Load Hardening
3 ### A Spectre Variant #1 Mitigation Technique
5 Author: Chandler Carruth - [chandlerc@google.com](mailto:chandlerc@google.com)
7 ## Problem Statement
9 Recently, Google Project Zero and other researchers have found information leak
10 vulnerabilities by exploiting speculative execution in modern CPUs. These
11 exploits are currently broken down into three variants:
12 * GPZ Variant #1 (a.k.a. Spectre Variant #1): Bounds check (or predicate) bypass
13 * GPZ Variant #2 (a.k.a. Spectre Variant #2): Branch target injection
14 * GPZ Variant #3 (a.k.a. Meltdown): Rogue data cache load
16 For more details, see the Google Project Zero blog post and the Spectre research
17 paper:
18 * https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html
19 * https://spectreattack.com/spectre.pdf
21 The core problem of GPZ Variant #1 is that speculative execution uses branch
22 prediction to select the path of instructions speculatively executed. This path
23 is speculatively executed with the available data, and may load from memory and
24 leak the loaded values through various side channels that survive even when the
25 speculative execution is unwound due to being incorrect. Mispredicted paths can
26 cause code to be executed with data inputs that never occur in correct
27 executions, making checks against malicious inputs ineffective and allowing
28 attackers to use malicious data inputs to leak secret data. Here is an example,
29 extracted and simplified from the Project Zero paper:
30 ```
31 struct array {
32   unsigned long length;
33   unsigned char data[];
35 struct array *arr1 = ...; // small array
36 struct array *arr2 = ...; // array of size 0x400
37 unsigned long untrusted_offset_from_caller = ...;
38 if (untrusted_offset_from_caller < arr1->length) {
39   unsigned char value = arr1->data[untrusted_offset_from_caller];
40   unsigned long index2 = ((value&1)*0x100)+0x200;
41   unsigned char value2 = arr2->data[index2];
43 ```
45 The key of the attack is to call this with `untrusted_offset_from_caller` that
46 is far outside of the bounds when the branch predictor will predict that it
47 will be in-bounds. In that case, the body of the `if` will be executed
48 speculatively, and may read secret data into `value` and leak it via a
49 cache-timing side channel when a dependent access is made to populate `value2`.
51 ## High Level Mitigation Approach
53 While several approaches are being actively pursued to mitigate specific
54 branches and/or loads inside especially risky software (most notably various OS
55 kernels), these approaches require manual and/or static analysis aided auditing
56 of code and explicit source changes to apply the mitigation. They are unlikely
57 to scale well to large applications. We are proposing a comprehensive
58 mitigation approach that would apply automatically across an entire program
59 rather than through manual changes to the code. While this is likely to have a
60 high performance cost, some applications may be in a good position to take this
61 performance / security tradeoff.
63 The specific technique we propose is to cause loads to be checked using
64 branchless code to ensure that they are executing along a valid control flow
65 path. Consider the following C-pseudo-code representing the core idea of a
66 predicate guarding potentially invalid loads:
67 ```
68 void leak(int data);
69 void example(int* pointer1, int* pointer2) {
70   if (condition) {
71     // ... lots of code ...
72     leak(*pointer1);
73   } else {
74     // ... more code ...
75     leak(*pointer2);
76   }
78 ```
80 This would get transformed into something resembling the following:
81 ```
82 uintptr_t all_ones_mask = std::numerical_limits<uintptr_t>::max();
83 uintptr_t all_zeros_mask = 0;
84 void leak(int data);
85 void example(int* pointer1, int* pointer2) {
86   uintptr_t predicate_state = all_ones_mask;
87   if (condition) {
88     // Assuming ?: is implemented using branchless logic...
89     predicate_state = !condition ? all_zeros_mask : predicate_state;
90     // ... lots of code ...
91     //
92     // Harden the pointer so it can't be loaded
93     pointer1 &= predicate_state;
94     leak(*pointer1);
95   } else {
96     predicate_state = condition ? all_zeros_mask : predicate_state;
97     // ... more code ...
98     //
99     // Alternative: Harden the loaded value
100     int value2 = *pointer2 & predicate_state;
101     leak(value2);
102   }
106 The result should be that if the `if (condition) {` branch is mis-predicted,
107 there is a *data* dependency on the condition used to zero out any pointers
108 prior to loading through them or to zero out all of the loaded bits. Even
109 though this code pattern may still execute speculatively, *invalid* speculative
110 executions are prevented from leaking secret data from memory (but note that
111 this data might still be loaded in safe ways, and some regions of memory are
112 required to not hold secrets, see below for detailed limitations). This
113 approach only requires the underlying hardware have a way to implement a
114 branchless and unpredicted conditional update of a register's value. All modern
115 architectures have support for this, and in fact such support is necessary to
116 correctly implement constant time cryptographic primitives.
118 Crucial properties of this approach:
119 * It is not preventing any particular side-channel from working. This is
120   important as there are an unknown number of potential side channels and we
121   expect to continue discovering more. Instead, it prevents the observation of
122   secret data in the first place.
123 * It accumulates the predicate state, protecting even in the face of nested
124   *correctly* predicted control flows.
125 * It passes this predicate state across function boundaries to provide
126   [interprocedural protection](#interprocedural-checking).
127 * When hardening the address of a load, it uses a *destructive* or
128   *non-reversible* modification of the address to prevent an attacker from
129   reversing the check using attacker-controlled inputs.
130 * It does not completely block speculative execution, and merely prevents
131   *mis*-speculated paths from leaking secrets from memory (and stalls
132   speculation until this can be determined).
133 * It is completely general and makes no fundamental assumptions about the
134   underlying architecture other than the ability to do branchless conditional
135   data updates and a lack of value prediction.
136 * It does not require programmers to identify all possible secret data using
137   static source code annotations or code vulnerable to a variant #1 style
138   attack.
140 Limitations of this approach:
141 * It requires re-compiling source code to insert hardening instruction
142   sequences. Only software compiled in this mode is protected.
143 * The performance is heavily dependent on a particular architecture's
144   implementation strategy. We outline a potential x86 implementation below and
145   characterize its performance.
146 * It does not defend against secret data already loaded from memory and
147   residing in registers or leaked through other side-channels in
148   non-speculative execution. Code dealing with this, e.g cryptographic
149   routines, already uses constant-time algorithms and code to prevent
150   side-channels. Such code should also scrub registers of secret data following
151   [these
152   guidelines](https://github.com/HACS-workshop/spectre-mitigations/blob/master/crypto_guidelines.md).
153 * To achieve reasonable performance, many loads may not be checked, such as
154   those with compile-time fixed addresses. This primarily consists of accesses
155   at compile-time constant offsets of global and local variables. Code which
156   needs this protection and intentionally stores secret data must ensure the
157   memory regions used for secret data are necessarily dynamic mappings or heap
158   allocations. This is an area which can be tuned to provide more comprehensive
159   protection at the cost of performance.
160 * [Hardened loads](#hardening-the-address-of-the-load) may still load data from
161   _valid_ addresses if not _attacker-controlled_ addresses. To prevent these
162   from reading secret data, the low 2gb of the address space and 2gb above and
163   below any executable pages should be protected.
165 Credit:
166 * The core idea of tracing misspeculation through data and marking pointers to
167   block misspeculated loads was developed as part of a HACS 2018 discussion
168   between Chandler Carruth, Paul Kocher, Thomas Pornin, and several other
169   individuals.
170 * Core idea of masking out loaded bits was part of the original mitigation
171   suggested by Jann Horn when these attacks were reported.
174 ### Indirect Branches, Calls, and Returns
176 It is possible to attack control flow other than conditional branches with
177 variant #1 style mispredictions.
178 * A prediction towards a hot call target of a virtual method can lead to it
179   being speculatively executed when an expected type is used (often called
180   "type confusion").
181 * A hot case may be speculatively executed due to prediction instead of the
182   correct case for a switch statement implemented as a jump table.
183 * A hot common return address may be predicted incorrectly when returning from
184   a function.
186 These code patterns are also vulnerable to Spectre variant #2, and as such are
187 best mitigated with a
188 [retpoline](https://support.google.com/faqs/answer/7625886) on x86 platforms.
189 When a mitigation technique like retpoline is used, speculation simply cannot
190 proceed through an indirect control flow edge (or it cannot be mispredicted in
191 the case of a filled RSB) and so it is also protected from variant #1 style
192 attacks. However, some architectures, micro-architectures, or vendors do not
193 employ the retpoline mitigation, and on future x86 hardware (both Intel and
194 AMD) it is expected to become unnecessary due to hardware-based mitigation.
196 When not using a retpoline, these edges will need independent protection from
197 variant #1 style attacks. The analogous approach to that used for conditional
198 control flow should work:
200 uintptr_t all_ones_mask = std::numerical_limits<uintptr_t>::max();
201 uintptr_t all_zeros_mask = 0;
202 void leak(int data);
203 void example(int* pointer1, int* pointer2) {
204   uintptr_t predicate_state = all_ones_mask;
205   switch (condition) {
206   case 0:
207     // Assuming ?: is implemented using branchless logic...
208     predicate_state = (condition != 0) ? all_zeros_mask : predicate_state;
209     // ... lots of code ...
210     //
211     // Harden the pointer so it can't be loaded
212     pointer1 &= predicate_state;
213     leak(*pointer1);
214     break;
216   case 1:
217     predicate_state = (condition != 1) ? all_zeros_mask : predicate_state;
218     // ... more code ...
219     //
220     // Alternative: Harden the loaded value
221     int value2 = *pointer2 & predicate_state;
222     leak(value2);
223     break;
225     // ...
226   }
230 The core idea remains the same: validate the control flow using data-flow and
231 use that validation to check that loads cannot leak information along
232 misspeculated paths. Typically this involves passing the desired target of such
233 control flow across the edge and checking that it is correct afterwards. Note
234 that while it is tempting to think that this mitigates variant #2 attacks, it
235 does not. Those attacks go to arbitrary gadgets that don't include the checks.
238 ### Variant #1.1 and #1.2 attacks: "Bounds Check Bypass Store"
240 Beyond the core variant #1 attack, there are techniques to extend this attack.
241 The primary technique is known as "Bounds Check Bypass Store" and is discussed
242 in this research paper: https://people.csail.mit.edu/vlk/spectre11.pdf
244 We will analyze these two variants independently. First, variant #1.1 works by
245 speculatively storing over the return address after a bounds check bypass. This
246 speculative store then ends up being used by the CPU during speculative
247 execution of the return, potentially directing speculative execution to
248 arbitrary gadgets in the binary. Let's look at an example.
250 unsigned char local_buffer[4];
251 unsigned char *untrusted_data_from_caller = ...;
252 unsigned long untrusted_size_from_caller = ...;
253 if (untrusted_size_from_caller < sizeof(local_buffer)) {
254   // Speculative execution enters here with a too-large size.
255   memcpy(local_buffer, untrusted_data_from_caller,
256          untrusted_size_from_caller);
257   // The stack has now been smashed, writing an attacker-controlled
258   // address over the return adress.
259   minor_processing(local_buffer);
260   return;
261   // Control will speculate to the attacker-written address.
265 However, this can be mitigated by hardening the load of the return address just
266 like any other load. This is sometimes complicated because x86 for example
267 *implicitly* loads the return address off the stack. However, the
268 implementation technique below is specifically designed to mitigate this
269 implicit load by using the stack pointer to communicate misspeculation between
270 functions. This additionally causes a misspeculation to have an invalid stack
271 pointer and never be able to read the speculatively stored return address. See
272 the detailed discussion below.
274 For variant #1.2, the attacker speculatively stores into the vtable or jump
275 table used to implement an indirect call or indirect jump. Because this is
276 speculative, this will often be possible even when these are stored in
277 read-only pages. For example:
279 class FancyObject : public BaseObject {
280 public:
281   void DoSomething() override;
283 void f(unsigned long attacker_offset, unsigned long attacker_data) {
284   FancyObject object = getMyObject();
285   unsigned long *arr[4] = getFourDataPointers();
286   if (attacker_offset < 4) {
287     // We have bypassed the bounds check speculatively.
288     unsigned long *data = arr[attacker_offset];
289     // Now we have computed a pointer inside of `object`, the vptr.
290     *data = attacker_data;
291     // The vptr points to the virtual table and we speculatively clobber that.
292     g(object); // Hand the object to some other routine.
293   }
295 // In another file, we call a method on the object.
296 void g(BaseObject &object) {
297   object.DoSomething();
298   // This speculatively calls the address stored over the vtable.
302 Mitigating this requires hardening loads from these locations, or mitigating
303 the indirect call or indirect jump. Any of these are sufficient to block the
304 call or jump from using a speculatively stored value that has been read back.
306 For both of these, using retpolines would be equally sufficient. One possible
307 hybrid approach is to use retpolines for indirect call and jump, while relying
308 on SLH to mitigate returns.
310 Another approach that is sufficient for both of these is to harden all of the
311 speculative stores. However, as most stores aren't interesting and don't
312 inherently leak data, this is expected to be prohibitively expensive given the
313 attack it is defending against.
316 ## Implementation Details
318 There are a number of complex details impacting the implementation of this
319 technique, both on a particular architecture and within a particular compiler.
320 We discuss proposed implementation techniques for the x86 architecture and the
321 LLVM compiler. These are primarily to serve as an example, as other
322 implementation techniques are very possible.
325 ### x86 Implementation Details
327 On the x86 platform we break down the implementation into three core
328 components: accumulating the predicate state through the control flow graph,
329 checking the loads, and checking control transfers between procedures.
332 #### Accumulating Predicate State
334 Consider baseline x86 instructions like the following, which test three
335 conditions and if all pass, loads data from memory and potentially leaks it
336 through some side channel:
338 # %bb.0:                                # %entry
339         pushq   %rax
340         testl   %edi, %edi
341         jne     .LBB0_4
342 # %bb.1:                                # %then1
343         testl   %esi, %esi
344         jne     .LBB0_4
345 # %bb.2:                                # %then2
346         testl   %edx, %edx
347         je      .LBB0_3
348 .LBB0_4:                                # %exit
349         popq    %rax
350         retq
351 .LBB0_3:                                # %danger
352         movl    (%rcx), %edi
353         callq   leak
354         popq    %rax
355         retq
358 When we go to speculatively execute the load, we want to know whether any of
359 the dynamically executed predicates have been misspeculated. To track that,
360 along each conditional edge, we need to track the data which would allow that
361 edge to be taken. On x86, this data is stored in the flags register used by the
362 conditional jump instruction. Along both edges after this fork in control flow,
363 the flags register remains alive and contains data that we can use to build up
364 our accumulated predicate state. We accumulate it using the x86 conditional
365 move instruction which also reads the flag registers where the state resides.
366 These conditional move instructions are known to not be predicted on any x86
367 processors, making them immune to misprediction that could reintroduce the
368 vulnerability. When we insert the conditional moves, the code ends up looking
369 like the following:
371 # %bb.0:                                # %entry
372         pushq   %rax
373         xorl    %eax, %eax              # Zero out initial predicate state.
374         movq    $-1, %r8                # Put all-ones mask into a register.
375         testl   %edi, %edi
376         jne     .LBB0_1
377 # %bb.2:                                # %then1
378         cmovneq %r8, %rax               # Conditionally update predicate state.
379         testl   %esi, %esi
380         jne     .LBB0_1
381 # %bb.3:                                # %then2
382         cmovneq %r8, %rax               # Conditionally update predicate state.
383         testl   %edx, %edx
384         je      .LBB0_4
385 .LBB0_1:
386         cmoveq  %r8, %rax               # Conditionally update predicate state.
387         popq    %rax
388         retq
389 .LBB0_4:                                # %danger
390         cmovneq %r8, %rax               # Conditionally update predicate state.
391         ...
394 Here we create the "empty" or "correct execution" predicate state by zeroing
395 `%rax`, and we create a constant "incorrect execution" predicate value by
396 putting `-1` into `%r8`. Then, along each edge coming out of a conditional
397 branch we do a conditional move that in a correct execution will be a no-op,
398 but if misspeculated, will replace the `%rax` with the value of `%r8`.
399 Misspeculating any one of the three predicates will cause `%rax` to hold the
400 "incorrect execution" value from `%r8` as we preserve incoming values when
401 execution is correct rather than overwriting it.
403 We now have a value in `%rax` in each basic block that indicates if at some
404 point previously a predicate was mispredicted. And we have arranged for that
405 value to be particularly effective when used below to harden loads.
408 ##### Indirect Call, Branch, and Return Predicates
410 (Not yet implemented.)
412 There is no analogous flag to use when tracing indirect calls, branches, and
413 returns. The predicate state must be accumulated through some other means.
414 Fundamentally, this is the reverse of the problem posed in CFI: we need to
415 check where we came from rather than where we are going. For function-local
416 jump tables, this is easily arranged by testing the input to the jump table
417 within each destination:
419         pushq   %rax
420         xorl    %eax, %eax              # Zero out initial predicate state.
421         movq    $-1, %r8                # Put all-ones mask into a register.
422         jmpq    *.LJTI0_0(,%rdi,8)      # Indirect jump through table.
423 .LBB0_2:                                # %sw.bb
424         testq   $0, %rdi                # Validate index used for jump table.
425         cmovneq %r8, %rax               # Conditionally update predicate state.
426         ...
427         jmp     _Z4leaki                # TAILCALL
429 .LBB0_3:                                # %sw.bb1
430         testq   $1, %rdi                # Validate index used for jump table.
431         cmovneq %r8, %rax               # Conditionally update predicate state.
432         ...
433         jmp     _Z4leaki                # TAILCALL
435 .LBB0_5:                                # %sw.bb10
436         testq   $2, %rdi                # Validate index used for jump table.
437         cmovneq %r8, %rax               # Conditionally update predicate state.
438         ...
439         jmp     _Z4leaki                # TAILCALL
440         ...
442         .section        .rodata,"a",@progbits
443         .p2align        3
444 .LJTI0_0:
445         .quad   .LBB0_2
446         .quad   .LBB0_3
447         .quad   .LBB0_5
448         ...
451 Returns have a simple mitigation technique on x86-64 (or other ABIs which have
452 what is called a "red zone" region beyond the end of the stack). This region is
453 guaranteed to be preserved across interrupts and context switches, making the
454 return address used in returning to the current code remain on the stack and
455 valid to read. We can emit code in the caller to verify that a return edge was
456 not mispredicted:
458         callq   other_function
459 return_addr:
460         testq   -8(%rsp), return_addr   # Validate return address.
461         cmovneq %r8, %rax               # Update predicate state.
464 For an ABI without a "red zone" (and thus unable to read the return address
465 from the stack), mitigating returns face similar problems to calls below.
467 Indirect calls (and returns in the absence of a red zone ABI) pose the most
468 significant challenge to propagate. The simplest technique would be to define a
469 new ABI such that the intended call target is passed into the called function
470 and checked in the entry. Unfortunately, new ABIs are quite expensive to deploy
471 in C and C++. While the target function could be passed in TLS, we would still
472 require complex logic to handle a mixture of functions compiled with and
473 without this extra logic (essentially, making the ABI backwards compatible).
474 Currently, we suggest using retpolines here and will continue to investigate
475 ways of mitigating this.
478 ##### Optimizations, Alternatives, and Tradeoffs
480 Merely accumulating predicate state involves significant cost. There are
481 several key optimizations we employ to minimize this and various alternatives
482 that present different tradeoffs in the generated code.
484 First, we work to reduce the number of instructions used to track the state:
485 * Rather than inserting a `cmovCC` instruction along every conditional edge in
486   the original program, we track each set of condition flags we need to capture
487   prior to entering each basic block and reuse a common `cmovCC` sequence for
488   those.
489   * We could further reuse suffixes when there are multiple `cmovCC`
490     instructions required to capture the set of flags. Currently this is
491     believed to not be worth the cost as paired flags are relatively rare and
492     suffixes of them are exceedingly rare.
493 * A common pattern in x86 is to have multiple conditional jump instructions
494   that use the same flags but handle different conditions. Naively, we could
495   consider each fallthrough between them an "edge" but this causes a much more
496   complex control flow graph. Instead, we accumulate the set of conditions
497   necessary for fallthrough and use a sequence of `cmovCC` instructions in a
498   single fallthrough edge to track it.
500 Second, we trade register pressure for simpler `cmovCC` instructions by
501 allocating a register for the "bad" state. We could read that value from memory
502 as part of the conditional move instruction, however, this creates more
503 micro-ops and requires the load-store unit to be involved. Currently, we place
504 the value into a virtual register and allow the register allocator to decide
505 when the register pressure is sufficient to make it worth spilling to memory
506 and reloading.
509 #### Hardening Loads
511 Once we have the predicate accumulated into a special value for correct vs.
512 misspeculated, we need to apply this to loads in a way that ensures they do not
513 leak secret data. There are two primary techniques for this: we can either
514 harden the loaded value to prevent observation, or we can harden the address
515 itself to prevent the load from occuring. These have significantly different
516 performance tradeoffs.
519 ##### Hardening loaded values
521 The most appealing way to harden loads is to mask out all of the bits loaded.
522 The key requirement is that for each bit loaded, along the misspeculated path
523 that bit is always fixed at either 0 or 1 regardless of the value of the bit
524 loaded. The most obvious implementation uses either an `and` instruction with
525 an all-zero mask along misspeculated paths and an all-one mask along correct
526 paths, or an `or` instruction with an all-one mask along misspeculated paths
527 and an all-zero mask along correct paths. Other options become less appealing
528 such as multiplying by zero, or multiple shift instructions. For reasons we
529 elaborate on below, we end up suggesting you use `or` with an all-ones mask,
530 making the x86 instruction sequence look like the following:
532         ...
534 .LBB0_4:                                # %danger
535         cmovneq %r8, %rax               # Conditionally update predicate state.
536         movl    (%rsi), %edi            # Load potentially secret data from %rsi.
537         orl     %eax, %edi
540 Other useful patterns may be to fold the load into the `or` instruction itself
541 at the cost of a register-to-register copy.
543 There are some challenges with deploying this approach:
544 1. Many loads on x86 are folded into other instructions. Separating them would
545    add very significant and costly register pressure with prohibitive
546    performance cost.
547 1. Loads may not target a general purpose register requiring extra instructions
548    to map the state value into the correct register class, and potentially more
549    expensive instructions to mask the value in some way.
550 1. The flags registers on x86 are very likely to be live, and challenging to
551    preserve cheaply.
552 1. There are many more values loaded than pointers & indices used for loads. As
553    a consequence, hardening the result of a load requires substantially more
554    instructions than hardening the address of the load (see below).
556 Despite these challenges, hardening the result of the load critically allows
557 the load to proceed and thus has dramatically less impact on the total
558 speculative / out-of-order potential of the execution. There are also several
559 interesting techniques to try and mitigate these challenges and make hardening
560 the results of loads viable in at least some cases. However, we generally
561 expect to fall back when unprofitable from hardening the loaded value to the
562 next approach of hardening the address itself.
565 ###### Loads folded into data-invariant operations can be hardened after the operation
567 The first key to making this feasible is to recognize that many operations on
568 x86 are "data-invariant". That is, they have no (known) observable behavior
569 differences due to the particular input data. These instructions are often used
570 when implementing cryptographic primitives dealing with private key data
571 because they are not believed to provide any side-channels. Similarly, we can
572 defer hardening until after them as they will not in-and-of-themselves
573 introduce a speculative execution side-channel. This results in code sequences
574 that look like:
576         ...
578 .LBB0_4:                                # %danger
579         cmovneq %r8, %rax               # Conditionally update predicate state.
580         addl    (%rsi), %edi            # Load and accumulate without leaking.
581         orl     %eax, %edi
584 While an addition happens to the loaded (potentially secret) value, that
585 doesn't leak any data and we then immediately harden it.
588 ###### Hardening of loaded values deferred down the data-invariant expression graph
590 We can generalize the previous idea and sink the hardening down the expression
591 graph across as many data-invariant operations as desirable. This can use very
592 conservative rules for whether something is data-invariant. The primary goal
593 should be to handle multiple loads with a single hardening instruction:
595         ...
597 .LBB0_4:                                # %danger
598         cmovneq %r8, %rax               # Conditionally update predicate state.
599         addl    (%rsi), %edi            # Load and accumulate without leaking.
600         addl    4(%rsi), %edi           # Continue without leaking.
601         addl    8(%rsi), %edi
602         orl     %eax, %edi              # Mask out bits from all three loads.
606 ###### Preserving the flags while hardening loaded values on Haswell, Zen, and newer processors
608 Sadly, there are no useful instructions on x86 that apply a mask to all 64 bits
609 without touching the flag registers. However, we can harden loaded values that
610 are narrower than a word (fewer than 32-bits on 32-bit systems and fewer than
611 64-bits on 64-bit systems) by zero-extending the value to the full word size
612 and then shifting right by at least the number of original bits using the BMI2
613 `shrx` instruction:
615         ...
617 .LBB0_4:                                # %danger
618         cmovneq %r8, %rax               # Conditionally update predicate state.
619         addl    (%rsi), %edi            # Load and accumulate 32 bits of data.
620         shrxq   %rax, %rdi, %rdi        # Shift out all 32 bits loaded.
623 Because on x86 the zero-extend is free, this can efficiently harden the loaded
624 value.
627 ##### Hardening the address of the load
629 When hardening the loaded value is inapplicable, most often because the
630 instruction directly leaks information (like `cmp` or `jmpq`), we switch to
631 hardening the _address_ of the load instead of the loaded value. This avoids
632 increasing register pressure by unfolding the load or paying some other high
633 cost.
635 To understand how this works in practice, we need to examine the exact
636 semantics of the x86 addressing modes which, in its fully general form, looks
637 like `(%base,%index,scale)offset`. Here `%base` and `%index` are 64-bit
638 registers that can potentially be any value, and may be attacker controlled,
639 and `scale` and `offset` are fixed immediate values. `scale` must be `1`, `2`,
640 `4`, or `8`, and `offset` can be any 32-bit sign extended value. The exact
641 computation performed to find the address is then: `%base + (scale * %index) +
642 offset` under 64-bit 2's complement modular arithmetic.
644 One issue with this approach is that, after hardening, the  `%base + (scale *
645 %index)` subexpression will compute a value near zero (`-1 + (scale * -1)`) and
646 then a large, positive `offset` will index into memory within the first two
647 gigabytes of address space. While these offsets are not attacker controlled,
648 the attacker could chose to attack a load which happens to have the desired
649 offset and then successfully read memory in that region. This significantly
650 raises the burden on the attacker and limits the scope of attack but does not
651 eliminate it. To fully close the attack we must work with the operating system
652 to preclude mapping memory in the low two gigabytes of address space.
655 ###### 64-bit load checking instructions
657 We can use the following instruction sequences to check loads. We set up `%r8`
658 in these examples to hold the special value of `-1` which will be `cmov`ed over
659 `%rax` in misspeculated paths.
661 Single register addressing mode:
663         ...
665 .LBB0_4:                                # %danger
666         cmovneq %r8, %rax               # Conditionally update predicate state.
667         orq     %rax, %rsi              # Mask the pointer if misspeculating.
668         movl    (%rsi), %edi
671 Two register addressing mode:
673         ...
675 .LBB0_4:                                # %danger
676         cmovneq %r8, %rax               # Conditionally update predicate state.
677         orq     %rax, %rsi              # Mask the pointer if misspeculating.
678         orq     %rax, %rcx              # Mask the index if misspeculating.
679         movl    (%rsi,%rcx), %edi
682 This will result in a negative address near zero or in `offset` wrapping the
683 address space back to a small positive address. Small, negative addresses will
684 fault in user-mode for most operating systems, but targets which need the high
685 address space to be user accessible may need to adjust the exact sequence used
686 above. Additionally, the low addresses will need to be marked unreadable by the
687 OS to fully harden the load.
690 ###### RIP-relative addressing is even easier to break
692 There is a common addressing mode idiom that is substantially harder to check:
693 addressing relative to the instruction pointer. We cannot change the value of
694 the instruction pointer register and so we have the harder problem of forcing
695 `%base + scale * %index + offset` to be an invalid address, by *only* changing
696 `%index`. The only advantage we have is that the attacker also cannot modify
697 `%base`. If we use the fast instruction sequence above, but only apply it to
698 the index, we will always access `%rip + (scale * -1) + offset`. If the
699 attacker can find a load which with this address happens to point to secret
700 data, then they can reach it. However, the loader and base libraries can also
701 simply refuse to map the heap, data segments, or stack within 2gb of any of the
702 text in the program, much like it can reserve the low 2gb of address space.
705 ###### The flag registers again make everything hard
707 Unfortunately, the technique of using `orq`-instructions has a serious flaw on
708 x86. The very thing that makes it easy to accumulate state, the flag registers
709 containing predicates, causes serious problems here because they may be alive
710 and used by the loading instruction or subsequent instructions. On x86, the
711 `orq` instruction **sets** the flags and will override anything already there.
712 This makes inserting them into the instruction stream very hazardous.
713 Unfortunately, unlike when hardening the loaded value, we have no fallback here
714 and so we must have a fully general approach available.
716 The first thing we must do when generating these sequences is try to analyze
717 the surrounding code to prove that the flags are not in fact alive or being
718 used. Typically, it has been set by some other instruction which just happens
719 to set the flags register (much like ours!) with no actual dependency. In those
720 cases, it is safe to directly insert these instructions. Alternatively we may
721 be able to move them earlier to avoid clobbering the used value.
723 However, this may ultimately be impossible. In that case, we need to preserve
724 the flags around these instructions:
726         ...
728 .LBB0_4:                                # %danger
729         cmovneq %r8, %rax               # Conditionally update predicate state.
730         pushfq
731         orq     %rax, %rcx              # Mask the pointer if misspeculating.
732         orq     %rax, %rdx              # Mask the index if misspeculating.
733         popfq
734         movl    (%rcx,%rdx), %edi
737 Using the `pushf` and `popf` instructions saves the flags register around our
738 inserted code, but comes at a high cost. First, we must store the flags to the
739 stack and reload them. Second, this causes the stack pointer to be adjusted
740 dynamically, requiring a frame pointer be used for referring to temporaries
741 spilled to the stack, etc.
743 On newer x86 processors we can use the `lahf` and `sahf` instructions to save
744 all of the flags besides the overflow flag in a register rather than on the
745 stack. We can then use `seto` and `add` to save and restore the overflow flag
746 in a register. Combined, this will save and restore flags in the same manner as
747 above but using two registers rather than the stack. That is still very
748 expensive if slightly less expensive than `pushf` and `popf` in most cases.
751 ###### A flag-less alternative on Haswell, Zen and newer processors
753 Starting with the BMI2 x86 instruction set extensions available on Haswell and
754 Zen processors, there is an instruction for shifting that does not set any
755 flags: `shrx`. We can use this and the `lea` instruction to implement analogous
756 code sequences to the above ones. However, these are still very marginally
757 slower, as there are fewer ports able to dispatch shift instructions in most
758 modern x86 processors than there are for `or` instructions.
760 Fast, single register addressing mode:
762         ...
764 .LBB0_4:                                # %danger
765         cmovneq %r8, %rax               # Conditionally update predicate state.
766         shrxq   %rax, %rsi, %rsi        # Shift away bits if misspeculating.
767         movl    (%rsi), %edi
770 This will collapse the register to zero or one, and everything but the offset
771 in the addressing mode to be less than or equal to 9. This means the full
772 address can only be guaranteed to be less than `(1 << 31) + 9`. The OS may wish
773 to protect an extra page of the low address space to account for this
776 ##### Optimizations
778 A very large portion of the cost for this approach comes from checking loads in
779 this way, so it is important to work to optimize this. However, beyond making
780 the instruction sequences to *apply* the checks efficient (for example by
781 avoiding `pushfq` and `popfq` sequences), the only significant optimization is
782 to check fewer loads without introducing a vulnerability. We apply several
783 techniques to accomplish that.
786 ###### Don't check loads from compile-time constant stack offsets
788 We implement this optimization on x86 by skipping the checking of loads which
789 use a fixed frame pointer offset.
791 The result of this optimization is that patterns like reloading a spilled
792 register or accessing a global field don't get checked. This is a very
793 significant performance win.
796 ###### Don't check dependent loads
798 A core part of why this mitigation strategy works is that it establishes a
799 data-flow check on the loaded address. However, this means that if the address
800 itself was already loaded using a checked load, there is no need to check a
801 dependent load provided it is within the same basic block as the checked load,
802 and therefore has no additional predicates guarding it. Consider code like the
803 following:
805         ...
807 .LBB0_4:                                # %danger
808         movq    (%rcx), %rdi
809         movl    (%rdi), %edx
812 This will get transformed into:
814         ...
816 .LBB0_4:                                # %danger
817         cmovneq %r8, %rax               # Conditionally update predicate state.
818         orq     %rax, %rcx              # Mask the pointer if misspeculating.
819         movq    (%rcx), %rdi            # Hardened load.
820         movl    (%rdi), %edx            # Unhardened load due to dependent addr.
823 This doesn't check the load through `%rdi` as that pointer is dependent on a
824 checked load already.
827 ###### Protect large, load-heavy blocks with a single lfence
829 It may be worth using a single `lfence` instruction at the start of a block
830 which begins with a (very) large number of loads that require independent
831 protection *and* which require hardening the address of the load. However, this
832 is unlikely to be profitable in practice. The latency hit of the hardening
833 would need to exceed that of an `lfence` when *correctly* speculatively
834 executed. But in that case, the `lfence` cost is a complete loss of speculative
835 execution (at a minimum). So far, the evidence we have of the performance cost
836 of using `lfence` indicates few if any hot code patterns where this trade off
837 would make sense.
840 ###### Tempting optimizations that break the security model
842 Several optimizations were considered which didn't pan out due to failure to
843 uphold the security model. One in particular is worth discussing as many others
844 will reduce to it.
846 We wondered whether only the *first* load in a basic block could be checked. If
847 the check works as intended, it forms an invalid pointer that doesn't even
848 virtual-address translate in the hardware. It should fault very early on in its
849 processing. Maybe that would stop things in time for the misspeculated path to
850 fail to leak any secrets. This doesn't end up working because the processor is
851 fundamentally out-of-order, even in its speculative domain. As a consequence,
852 the attacker could cause the initial address computation itself to stall and
853 allow an arbitrary number of unrelated loads (including attacked loads of
854 secret data) to pass through.
857 #### Interprocedural Checking
859 Modern x86 processors may speculate into called functions and out of functions
860 to their return address. As a consequence, we need a way to check loads that
861 occur after a misspeculated predicate but where the load and the misspeculated
862 predicate are in different functions. In essence, we need some interprocedural
863 generalization of the predicate state tracking. A primary challenge to passing
864 the predicate state between functions is that we would like to not require a
865 change to the ABI or calling convention in order to make this mitigation more
866 deployable, and further would like code mitigated in this way to be easily
867 mixed with code not mitigated in this way and without completely losing the
868 value of the mitigation.
871 ##### Embed the predicate state into the high bit(s) of the stack pointer
873 We can use the same technique that allows hardening pointers to pass the
874 predicate state into and out of functions. The stack pointer is trivially
875 passed between functions and we can test for it having the high bits set to
876 detect when it has been marked due to misspeculation. The callsite instruction
877 sequence looks like (assuming a misspeculated state value of `-1`):
879         ...
881 .LBB0_4:                                # %danger
882         cmovneq %r8, %rax               # Conditionally update predicate state.
883         shlq    $47, %rax
884         orq     %rax, %rsp
885         callq   other_function
886         movq    %rsp, %rax
887         sarq    63, %rax                # Sign extend the high bit to all bits.
890 This first puts the predicate state into the high bits of `%rsp` before calling
891 the function and then reads it back out of high bits of `%rsp` afterward. When
892 correctly executing (speculatively or not), these are all no-ops. When
893 misspeculating, the stack pointer will end up negative. We arrange for it to
894 remain a canonical address, but otherwise leave the low bits alone to allow
895 stack adjustments to proceed normally without disrupting this. Within the
896 called function, we can extract this predicate state and then reset it on
897 return:
899 other_function:
900         # prolog
901         callq   other_function
902         movq    %rsp, %rax
903         sarq    63, %rax                # Sign extend the high bit to all bits.
904         # ...
906 .LBB0_N:
907         cmovneq %r8, %rax               # Conditionally update predicate state.
908         shlq    $47, %rax
909         orq     %rax, %rsp
910         retq
913 This approach is effective when all code is mitigated in this fashion, and can
914 even survive very limited reaches into unmitigated code (the state will
915 round-trip in and back out of an unmitigated function, it just won't be
916 updated). But it does have some limitations. There is a cost to merging the
917 state into `%rsp` and it doesn't insulate mitigated code from misspeculation in
918 an unmitigated caller.
920 There is also an advantage to using this form of interprocedural mitigation: by
921 forming these invalid stack pointer addresses we can prevent speculative
922 returns from successfully reading speculatively written values to the actual
923 stack. This works first by forming a data-dependency between computing the
924 address of the return address on the stack and our predicate state. And even
925 when satisfied, if a misprediction causes the state to be poisoned the
926 resulting stack pointer will be invalid.
929 ##### Rewrite API of internal functions to directly propagate predicate state
931 (Not yet implemented.)
933 We have the option with internal functions to directly adjust their API to
934 accept the predicate as an argument and return it. This is likely to be
935 marginally cheaper than embedding into `%rsp` for entering functions.
938 ##### Use `lfence` to guard function transitions
940 An `lfence` instruction can be used to prevent subsequent loads from
941 speculatively executing until all prior mispredicted predicates have resolved.
942 We can use this broader barrier to speculative loads executing between
943 functions. We emit it in the entry block to handle calls, and prior to each
944 return. This approach also has the advantage of providing the strongest degree
945 of mitigation when mixed with unmitigated code by halting all misspeculation
946 entering a function which is mitigated, regardless of what occured in the
947 caller. However, such a mixture is inherently more risky. Whether this kind of
948 mixture is a sufficient mitigation requires careful analysis.
950 Unfortunately, experimental results indicate that the performance overhead of
951 this approach is very high for certain patterns of code. A classic example is
952 any form of recursive evaluation engine. The hot, rapid call and return
953 sequences exhibit dramatic performance loss when mitigated with `lfence`. This
954 component alone can regress performance by 2x or more, making it an unpleasant
955 tradeoff even when only used in a mixture of code.
958 ##### Use an internal TLS location to pass predicate state
960 We can define a special thread-local value to hold the predicate state between
961 functions. This avoids direct ABI implications by using a side channel between
962 callers and callees to communicate the predicate state. It also allows implicit
963 zero-initialization of the state, which allows non-checked code to be the first
964 code executed.
966 However, this requires a load from TLS in the entry block, a store to TLS
967 before every call and every ret, and a load from TLS after every call. As a
968 consequence it is expected to be substantially more expensive even than using
969 `%rsp` and potentially `lfence` within the function entry block.
972 ##### Define a new ABI and/or calling convention
974 We could define a new ABI and/or calling convention to explicitly pass the
975 predicate state in and out of functions. This may be interesting if none of the
976 alternatives have adequate performance, but it makes deployment and adoption
977 dramatically more complex, and potentially infeasible.
980 ## High-Level Alternative Mitigation Strategies
982 There are completely different alternative approaches to mitigating variant 1
983 attacks. [Most](https://lwn.net/Articles/743265/)
984 [discussion](https://lwn.net/Articles/744287/) so far focuses on mitigating
985 specific known attackable components in the Linux kernel (or other kernels) by
986 manually rewriting the code to contain an instruction sequence that is not
987 vulnerable. For x86 systems this is done by either injecting an `lfence`
988 instruction along the code path which would leak data if executed speculatively
989 or by rewriting memory accesses to have branch-less masking to a known safe
990 region. On Intel systems, `lfence` [will prevent the speculative load of secret
991 data](https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf).
992 On AMD systems `lfence` is currently a no-op, but can be made
993 dispatch-serializing by setting an MSR, and thus preclude misspeculation of the
994 code path ([mitigation G-2 +
995 V1-1](https://developer.amd.com/wp-content/resources/Managing-Speculation-on-AMD-Processors.pdf)).
997 However, this relies on finding and enumerating all possible points in code
998 which could be attacked to leak information. While in some cases static
999 analysis is effective at doing this at scale, in many cases it still relies on
1000 human judgement to evaluate whether code might be vulnerable. Especially for
1001 software systems which receive less detailed scrutiny but remain sensitive to
1002 these attacks, this seems like an impractical security model. We need an
1003 automatic and systematic mitigation strategy.
1006 ### Automatic `lfence` on Conditional Edges
1008 A natural way to scale up the existing hand-coded mitigations is simply to
1009 inject an `lfence` instruction into both the target and fallthrough
1010 destinations of every conditional branch. This ensures that no predicate or
1011 bounds check can be bypassed speculatively. However, the performance overhead
1012 of this approach is, simply put, catastrophic. Yet it remains the only truly
1013 "secure by default" approach known prior to this effort and serves as the
1014 baseline for performance.
1016 One attempt to address the performance overhead of this and make it more
1017 realistic to deploy is [MSVC's /Qspectre
1018 switch](https://blogs.msdn.microsoft.com/vcblog/2018/01/15/spectre-mitigations-in-msvc/).
1019 Their technique is to use static analysis within the compiler to only insert
1020 `lfence` instructions into conditional edges at risk of attack. However,
1021 [initial](https://arstechnica.com/gadgets/2018/02/microsofts-compiler-level-spectre-fix-shows-how-hard-this-problem-will-be-to-solve/)
1022 [analysis](https://www.paulkocher.com/doc/MicrosoftCompilerSpectreMitigation.html)
1023 has shown that this approach is incomplete and only catches a small and limited
1024 subset of attackable patterns which happen to resemble very closely the initial
1025 proofs of concept. As such, while its performance is acceptable, it does not
1026 appear to be an adequate systematic mitigation.
1029 ## Performance Overhead
1031 The performance overhead of this style of comprehensive mitigation is very
1032 high. However, it compares very favorably with previously recommended
1033 approaches such as the `lfence` instruction. Just as users can restrict the
1034 scope of `lfence` to control its performance impact, this mitigation technique
1035 could be restricted in scope as well.
1037 However, it is important to understand what it would cost to get a fully
1038 mitigated baseline. Here we assume targeting a Haswell (or newer) processor and
1039 using all of the tricks to improve performance (so leaves the low 2gb
1040 unprotected and +/- 2gb surrounding any PC in the program). We ran both
1041 Google's microbenchmark suite and a large highly-tuned server built using
1042 ThinLTO and PGO. All were built with `-march=haswell` to give access to BMI2
1043 instructions, and benchmarks were run on large Haswell servers. We collected
1044 data both with an `lfence`-based mitigation and load hardening as presented
1045 here. The summary is that mitigating with load hardening is 1.77x faster than
1046 mitigating with `lfence`, and the overhead of load hardening compared to a
1047 normal program is likely between a 10% overhead and a 50% overhead with most
1048 large applications seeing a 30% overhead or less.
1050 | Benchmark                              | `lfence` | Load Hardening | Mitigated Speedup |
1051 | -------------------------------------- | -------: | -------------: | ----------------: |
1052 | Google microbenchmark suite            |   -74.8% |         -36.4% |          **2.5x** |
1053 | Large server QPS (using ThinLTO & PGO) |   -62%   |         -29%   |          **1.8x** |
1055 Below is a visualization of the microbenchmark suite results which helps show
1056 the distribution of results that is somewhat lost in the summary. The y-axis is
1057 a log-scale speedup ratio of load hardening relative to `lfence` (up -> faster
1058 -> better). Each box-and-whiskers represents one microbenchmark which may have
1059 many different metrics measured. The red line marks the median, the box marks
1060 the first and third quartiles, and the whiskers mark the min and max.
1062 ![Microbenchmark result visualization](speculative_load_hardening_microbenchmarks.png)
1064 We don't yet have benchmark data on SPEC or the LLVM test suite, but we can
1065 work on getting that. Still, the above should give a pretty clear
1066 characterization of the performance, and specific benchmarks are unlikely to
1067 reveal especially interesting properties.
1070 ### Future Work: Fine Grained Control and API-Integration
1072 The performance overhead of this technique is likely to be very significant and
1073 something users wish to control or reduce. There are interesting options here
1074 that impact the implementation strategy used.
1076 One particularly appealing option is to allow both opt-in and opt-out of this
1077 mitigation at reasonably fine granularity such as on a per-function basis,
1078 including intelligent handling of inlining decisions -- protected code can be
1079 prevented from inlining into unprotected code, and unprotected code will become
1080 protected when inlined into protected code. For systems where only a limited
1081 set of code is reachable by externally controlled inputs, it may be possible to
1082 limit the scope of mitigation through such mechanisms without compromising the
1083 application's overall security. The performance impact may also be focused in a
1084 few key functions that can be hand-mitigated in ways that have lower
1085 performance overhead while the remainder of the application receives automatic
1086 protection.
1088 For both limiting the scope of mitigation or manually mitigating hot functions,
1089 there needs to be some support for mixing mitigated and unmitigated code
1090 without completely defeating the mitigation. For the first use case, it would
1091 be particularly desirable that mitigated code remains safe when being called
1092 during misspeculation from unmitigated code.
1094 For the second use case, it may be important to connect the automatic
1095 mitigation technique to explicit mitigation APIs such as what is described in
1096 http://wg21.link/p0928 (or any other eventual API) so that there is a clean way
1097 to switch from automatic to manual mitigation without immediately exposing a
1098 hole. However, the design for how to do this is hard to come up with until the
1099 APIs are better established. We will revisit this as those APIs mature.