SpectreRewind: Leaking Secrets to Past Instructions
Jacob Fustos Michael Bechtel Heechul Yun
cs.CR
























  
  
   University of Kansas
 
 
  



  
   University of Kansas


  

  
  
   University of Kansas


  












Transient execution attacks utilize micro-architectural covert channels to leak secrets that should not have been accessible during logical program execution. Commonly used micro-architectural covert channels are those that leave lasting footprints in the micro-architectural state, for example, a cache state change, from which the secret is recovered after the transient execution is completed. 


In this paper, we present SpectreRewind, a new approach to create contention based covert channels for transient execution attacks. 
In our approach, a covert channel is established by issuing the necessary instructions logically before the transiently executed victim code. 
Unlike prior contention based covert channels, which require simultaneous multi-threading (SMT), SpectreRewind supports single hardware thread based covert channels, making it viable on systems where attacker cannot utilize SMT. We show that contention on the floating point division unit on commodity processors can be used to create a high-performance (∼100 KB/s), low-noise covert channel for transient execution attacks instead of commonly used flush+reload based cache covert channels.

We implement a Meltdown attack utilizing the proposed covert channel showing competitive performance compared to the state-of-the-art cache based covert channel implementation. We also show that the covert channel works in the JavaScript engine of a Chrome browser. 































<ccs2012>
<concept>
<concept_id>10002978.10003006.10003011</concept_id>
<concept_desc>Security and privacy Browser security</concept_desc>
<concept_significance>500</concept_significance>
</concept>
<concept>
<concept_id>10002978.10003001.10010777.10011702</concept_id>
<concept_desc>Security and privacy Side-channel analysis and countermeasures</concept_desc>
<concept_significance>500</concept_significance>
</concept>
</ccs2012>




SpectreRewind: Leaking Secrets to Past Instructions
    Heechul Yun
    December 30, 2023
===================================================






§ INTRODUCTION


Modern out-of-order microprocessors support speculative execution to improve performance. In speculative execution, 
instructions can be executed speculatively before knowing whether they are in the correct program execution path. 
If the speculation was wrong, the instructions that were executed incorrectly—known as transient instructions <cit.>—are squashed and the processor then simply retries to fetch and execute the correct instruction stream. 
Unfortunately, it turned out that these transient instructions can potentially bypass both software and hardware defenses to access secrets. The disclosure of Spectre <cit.> and Meltdown <cit.> and many other subsequently disclosed transient execution attacks <cit.> have shown the danger of these transient instructions, as the secrets they had access to could be encoded and transmitted into microarchitectural covert channels, from which normal, non-speculative instructions could then read, allowing the secrets to be visible to the attacker.

All known transient execution attacks share the same three basic steps: (1) the attacker initiates speculative execution where the secret is read improperly from memory or registers; (2) the secret dependent transient instructions then encode and transmit the secret to a micro-architectural covert channel; (3) finally, the secret is recovered from the covert channel by normal (non-transient) receiver instructions. 
Commonly used covert channels, such as cache, are stateful as they leave lasting footprints in the micro-architectural state, from which the secret is recovered after the transient execution is completed. 
Many hardware defense proposals aim to prevent such stateful covert channels either by  hiding the changes into additional hardware buffers <cit.> or by reverting them <cit.> when the transient instructions are squashed. Such a mitigation strategy is attractive from a performance standpoint, as the transient instructions are allowed to execute normally, retaining many of the performance benefits of speculative execution.

These type of defenses are effective at blocking transient execution attacks that utilize stateful covert channels. Unfortunately, these techniques cannot be used to block attacks that both transmit into and read from covert channel before transient instructions have been squashed.
SmotherSpectre <cit.> is the first to demonstrate such an attack, by utilizing a simultaneous covert channel in a simultaneous multi-threading (SMT) setup where contention on issue ports within the processor is used as a covert channel to transmit secret between the hardware threads in the context of Spectre-based attack. Such contention cannot be buffered or reverted, as instructions have already waited to use the issue ports, affecting their execution time.


In this paper, we present a new class of contention-based covert channels for transient execution attacks, which we call SpectreRewind. Like SmotherSpectre, SpectreRewind allows the attacker to both transmit and receive secret data before transient execution has completed, allowing the attacker to bypass most defense mechanisms that attempt to revert or hide micro-architectural changes caused by the attack. However, unlike SmotherSpectre, SpectreRewind does not require the attacker to utilize SMT, instead the attack can be executed from a single hardware thread. 
While traditional transient attacks locate the instructions that will read from the covert channel logically after the instruction that triggers the transient execution (e.g., a branch), SpectreRewind takes the opposite approach and locates these instructions logically before the triggering instruction. This structure allows the transmitting and receiving instructions to execute concurrently on a modern out-of-order core and communicate the secret even before the transient execution completes.

We start by presenting our SpectreRewind strategy and examining the unique challenges associated with it (Section  <ref> and Section <ref>). 
We then apply SpectreRewind to create a new covert channel, which utilizes contention on a floating point division unit in commodity Intel and AMD processors (Section  <ref>). 

Next, we analyze how SpectreRewind can be integrated into different transient execution attacks, modifying the Meltdown POC programs to utilize our covert channel, and implementing our covert channel within the Google Chrome JavaScript sandbox (Section  <ref>). 
Finally, we discuss the security implications that this attack has on currently proposed and implemented hardware and software defenses (Section  <ref>). Our evaluation results show that our technique allows the creation of a simultaneous covert channel from a single threaded context that has low noise, and is viable for use in transient execution attacks, and can leak data at a rate up to 100 KB/s with an error rate of less than 0.01%.





















































§ BACKGROUND


In this section, we provide necessary background on out-of-order cores, transient execution attacks, and simultaneous multithreading (SMT) hardware. 



 §.§ Out-of-order Processors




Modern high performance microprocessors utilize out-of-order execution to execute multiple independent instructions in parallel—taking advantage of instruction level parallelism—allowing for higher throughput, while also reducing the penalty of a stall caused by independent instructions. 

Figure <ref> shows a simplified example of an out-of-order processor. 
In this example, instructions have first been translated into micro-operations (ops). 

These ops are first placed into the ReOrder Buffer (ROB) in logical program order. 
They are then passed to the scheduler where they are then issued to a proper functional unit, once their operands become available and the necessary resources are available. In this example, the functional units are clustered into two execution units. Each execution unit contains a single issue port, which can only issue a single op to one of the enclosed functional units every clock cycle, but once issued, the functional units run independent of each other. Once executed by a functional unit, the scheduler is notified so that it can forward the results to following dependent ops. The op then waits in the ROB until it reaches the head where it may be retired. It is only now that the changes made by the op become architecturally visible, giving the illusion—from the architecture's point of view—that the instructions are executed in-order. 


To further reduce branch related stalls, modern processors implement complex branch predictors to predict what instructions should be executed. As the results of execution are not made architecturally visible until the instructions retire, it is architecturally safe to create a checkpoint of the processor's state before the prediction and then store the predicted instruction stream in the ROB and execute the instructions—speculative execution—further improving performance if the prediction was correct. If the prediction was false, these instructions are squashed—returning the processor state to the checkpoint—where the processor can begin executing the correct instructions. Instructions that were executed but were then squashed—will never become architecturally visible—are known as transient instructions.



 §.§ Transient Execution Attacks


As transient instructions were not supposed to have executed, it follows that they can perform tasks—such as accessing secret data—that should not have been accessible during proper program execution. While they do not retire—and do not become architecturally visible—they still can contend for shared resources with instructions that will retire, creating a microarchitectural side-channel that can leak the secrets.



Figure <ref> shows an example of a speculative execution attack—Spectre variant 1 <cit.>—in this example, the if statement of line 1 has been trained by the attacker such that the body—lines 2 and 3— is executed, even though x is out-of-bounds—transient execution. This allows the attacker to chose the value of x such that it points to the value of the secret and when line 2 is executed, the value of the secret—something that would have been blocked during normal program flow—will be unintentionally loaded from memory. The secret value is then encoded in line 3 to leak its value into the cache state. Later—after the transient instructions have been squashed—the attacker can read the cache state—from architecturally visible instructions—and decode it to complete the side-channel.

Transient execution attacks can be broken down into two categories. Spectre type attacks utilize control- and data-flow mis-speculation to force a victim to access secrets from their own address space and leak them into the covert channel where they can be accessed by the attacker. Each Spectre variant—1 <cit.>, 1.1 <cit.>, 2 <cit.>, 4 <cit.>, and ret2spec <cit.>—is distinguished by the microarchitectural component that is responsible for causing the mis-speculation namely—Branch History Buffer (BHB), Branch Target Buffer (BTB), Memory Disambiguator, Return Stack Buffer (RSB). Meltdown style attacks take advantage that processor exceptions are deferred until the instruction that caused the exception is retired—becomes architecturally visible—instructions that occur logically after the exception should not execute in regards to logical program order—but can be executed out-of-order—potentially bypassing the security that the exception intended to provide. These attacks can be run from within the attacker's own address space while allowing them to access secrets from other processes and privilege levels. Each Meltdown variants—1.2 <cit.>, 3 <cit.>, 3a <cit.>, Lazy FP <cit.>, and L1TF <cit.>—correspond to the exception that caused the fault. Microarchitectural Data Sampling(MDS) <cit.> are also considered Meltdown-type attacks. These attacks target speculative loads that have incorrectly loaded data from internal buffers—Store Buffer, Load Port, Line Fill Buffer—and leak the data into covert channels before realizing the fault. The data that was incorrectly loaded could have come from other SMT threads on the same processor executing at any privilege level.



 §.§ Simultaneous Multithreading (SMT)


To improve hardware utilization, 

manufacturers often employ a technique called Simultaneous Multithreading (SMT) <cit.>, where a single core is allowed to execute multiple hardware threads—instruction streams—simultaneously. These hardware threads share the underutilized structures, improving utilization, while appearing—from the architectural point of view—to be independent processing cores.
Because the hardware threads in a SMT capable core share various hardware structures—e.g. issue ports and functional units—these structures can be used to create covert channels and microarchitectural side channels between processes running on the multiple threads within a single core.



§ THREAT MODEL



























We assume that the attacker has the ability to control some code that executes both logically before and after a transiently execution attack in program order. 
We assume that the attacker would like to construct code that will transmit the secret over a covert channel such that they may read the value of the secret at the architectural level.
We assume that stateful covert channels, such as caches, are not available to the attacker because the platform either does not provide necessary means to control cache state (e.g., clflush) or implements hardware level defense mechanisms that prevent stateful covert channels <cit.>.




§ SPECTREREWIND






SpectreRewind is an approach to utilize contention-based covert channels for transient execution attacks. It allows the attacker to both transmit into and receive from a covert channel before the transient execution phase of the attack is completed.








Figure <ref> illustrates the basic concept of SpectreRewind in comparison to the conventional stateful covert channel based approach. 
In this figure, we break up involved ops into three distinct categories: the ops that come logically before, during, and after the transient execution attack. In both approaches, we assume that we send only a single bit over a covert channel at a time. For each approach, we depict two timing diagrams: transmitting `0' and `1' over a covert channel. 

In case of the traditional transient execution attack approach, the attacker will use a covert channel that causes a lasting state change in the micro-architecture, and read from the covert channel from ops that occur logically after the transient execution. 
Data can read from the channel by measuring the timing differences of these op (t3-t4 for a value `0' and t3-t5 for a value `1'). 
Hardware defenses (e.g.,  <cit.>) that remove secret from covert channel after transient execution (t2) will be able to stop this attack by disrupting the transmission of the secret.


In case of the SpectreRewind approach, however, transient instructions will contend for resources with the ops that come logically before the transient instructions. 
Because the covert channel will be read from before transient execution completes (t2), the aforementioned hardware defense mechanisms which  attempt to remove the secret from the covert channel at that time will be ineffective.
In our approach, the attacker measures the entire execution time of the attack to detect the timing differences. Since the covert channel must be read from before transient execution completes, this gives the added challenge of needing to fit the entire attack in the ROB at the same time.



SpectreRewind assumes that older transient ops can contend with younger ops that began before the transient ops on certain micro-architectural resources. In the following, we will discuss the kinds of micro-architectural resources are viable covert channels in SpectreRewind. 





§ NOT FULLY PIPELINED FUNCTIONAL UNITS




Since we aim to contend with instructions that are logically older than us this will limit our covert channel options. 
We will not be able to cause port contention or contention on fully pipelined functional units as in  <cit.>. 
However, we will show that it is still possible to cause contention on certain functional units that contain at least one non-pipelined stage.

Figure <ref> shows visual examples of this problem. In Figure <ref>, we see an example of an attacker op trying to cause slowdown on a victim op that is trying to use a shared integer multiplier. Unfortunately, because both the attacker and victim are ready to issue, the scheduler will choose the older victim, preventing any contention. 

Figure <ref>, shows the situation where the attacker becomes ready the cycle before the victim. The attacker is issued into the multiplier, but still cannot create contention on the victim, as the victim is issued on the next cycle that it becomes ready, just as if the attacker was not there. 

Finally, figure <ref> shows an attack on a non-pipelined shared functional unit (stage 1 takes 3 clock cycles to complete). As the victim is not initially ready, the attacker is scheduled on the unit. As the unit is not pipelined, the victim cannot be issued on the unit until the attacker completes, which effects the execution time of the victim, making a covert channel possible. Thus, for our attack we will only focus on functional units that have at least one stage that is not fully pipelined. 
Note that it is well known that floating point division is difficult to pipeline because for division each step depends on the previous step <cit.>. In the following, we will develop a floating point division unit based covert channel. 








§ FLOATING POINT DIVISION COVERT CHANNEL


In this section, we utilize our SpectreRewind approach to create a covert channel on real commodity hardware that can transmit data from transient execution without using stateful covert channels, or SMT co-scheduled processes. We do this by causing contention on the floating point division unit.









    

    




        






    













    






    
















        



        


    















Our covert channel utilizes contention on a functional unit, namely the floating point division unit (see Figure <ref>), to transmit data from transient instructions to non-transient instructions, which will retire and become architecturally visible. 
The floating point division unit was chosen as it is not fully pipelined (see Section <ref>) in all Intel, AMD, and ARM microarchitectures we tested. Table <ref> shows the tested microarchitectures, and their latency and throughput characteristics of the DIVSD instruction, which are obtained from <cit.> [As defined in <cit.>, latency refers to the clock cycles needed from the time the op is issued to the time the result become available to dependent ops, while throughput refers to the clock cycles needed from the time the op is issued until to the time the functional unit becomes available again.] Note that in all tested microarchitectures, the throughput of the  instruction is 4 or 8 cycles, meaning that while an DIVSD instruction is being executed, a pending DIVSD instruction has to wait 4 or 8 cycles before entering the floating point division unit. This delay makes the floating point division unit an ideal candidate for us to create a covert channel.






Figure <ref> shows the code used to form the ideal covert channel. 

(1) A timer is started (Line 5);
(2) A chain of dependent floating point division instructions begins execution (Line 8). Because the instructions are dependent, each instruction suffers the full round-trip latency of the floating point division unit (see Table <ref>). This chain of division instructions acts as a receiver;
(3) The result of the receiver instruction chain is compared in the if statement (Line 14). The if statement has been previously trained to be true, so the body will execute speculatively while the result of the receiver chain is being calculated;
(4) A single bit of the (secret) message to transmit is accessed (Line 15) and the inner if statement branches depending on the value of the secret bit (Line 16);
(5) The inner if statement is trained to be false. Thus, if the secret bit was `1',  the processor backtracks

and begins to speculatively execute a set of independent floating point division instructions (Line 18-23), which act as a sender.
The “sender” instructions are independent with each other so as to be issued concurrently and maximally contend with the “receiver” instructions on the floating point division unit of the processor. 
(6) When the “receiver” instructions are completed, the processor will realize the mis-speculation (recv in Line 14 was 0) and squash the speculative instructions from the “sender”. We then stop the timer (Line 28) and measure the time difference.

Note that if the secret bit was `1', the observed time difference will be longer, due to the contention in the floating point division unit with the mis-speculated “sender” instructions, compared to the case when the secret bit was `0' where there was no contention. 
This secret-dependent timing difference creates a covert channel.



















































































 §.§ Covert Channel Properties



















We experimentally evaluate the characteristics the covert channel on a number of commodity Intel, AMD, and ARM systems, as listed in Table <ref>.

Each system runs Linux (Ubuntu 18.04 or 16.04). For x86 platforms from Intel and AMD, we use  instructions for cycle accurate timing measurements. For ARM, we use an additional thread based software counter instead due to the architectural limitation. We repeatedly send 0 and 1 values over the covert channel, each for 1,000,000 times, and measure the timing results. To minimize noise, we use Linux's performance governor disable Turbo-boost (for X86 platforms) to improve reliability of the measurements. 



Figure <ref> shows the results. The X-axis shows the number of cycles taken to transmit, while the Y axis displays the probability a measurement has to take that many cycles.
Note first that on all tested platforms, we are able to see clear timing differences between `0' and `1' values. 
As explained in Section <ref>, not fully pipelined floating point division units in these platforms allow the mis-speculated division instructions to contend with the logically prior “receiver” instructions, resulting in clearly measurable timing differences. 

Another interesting observation is that the two AMD processors and the ARM Cortex-A57 show discreet timing characteristics—large proportion of the samples are concentrated on a few small measured cycles—whereas Intel processors show more varied timing behaviors, especially the Skylake processors. These differences are likely due to the way the floating point division unit is implemented in each of these vendors.

We also evaluated floating point multiplication instructions but were not able to observe any noticeable timing difference, suggesting that the floating point multiplication units in these platforms are well pipelined, and thus cannot be used to create covert channels. 



 §.§ Performance Analysis



Next, we analyze the performance of the covert channel in terms of transfer rate and error rate. The measured transfer rates of our tested platforms are calculated by simply dividing the total bits sent (1 million bits of 0 and 1 million bits of 1) with the time it took to send them. 
The error rate of each system is calculated as follows. We first sort each million timing samples of 0 and 1. We then find 99 percentile value of the `0' samples and 1 percentile value of the `0' samples. If the former (99 percentile of `0' samples) is smaller than the latter (1 percentile of `1' samples), we pick the average of the two value as the threshold to determine 0 or 1. If the 99 percentile of 0 is bigger than the 1 percentile of 1, we set the average of the median values of 0 and 1 samples as the threshold value. We then apply the threshold against the collected samples to determine if it correctly classifies the sample against its known correct value.  

The results are shown in Table <ref> (see the `Transfer Rate' and `Error Rate' columns). First, notice that the proposed covert channel supports very high transfer rates on all tested platforms, ranging from 63 to 105 KB/s. Furthermore, the error rates are also very low, especially on Intel processors, as we observe less than 0.5% error rates. AMD processors show higher error rates, of up to 5.5% on low end Ryzen3 APU. 



 §.§ Sensitivity Analysis



An interesting aspect of our covert channel is that the size (duration) of the speculation window can be controlled by adjusting the number of dependent division instructions used in the “receiver” part of the covert channel—i.e., Line 8-11 in Figure <ref>. This is because speculatively executed sender instructions are squashed after the receiver instruction change is completed. As such, the longer the receiver instruction chain is, the longer the sender instructions can contend on the floating point division unit. To understand the effect of the length of the receiver to the effectiveness of the covert channel, we measure the characteristics of the covert channel as a function of the number divisions in the receiver chain. 



Table <ref> shows the results. The first column shows the number of division instructions in the receiver chain. The second and third columns show the median cycles observed when sending `0' and `1' values over the covert channel, respectively. The fourth column is the cycle difference between 0 and 1 samples. Finally, the fifth and the last columns show the transfer and error rates of the channel.

Note first that the transfer rate is inversely proportional to the number of divisions in the receiver, which is expected as the more divisions are used, the longer time is needed to execute them before squashing the speculation. As such, from the transfer rate perspective, using a smaller number of divisions in the receiver may be desirable. However, when the number of divisions is too small, as in the case of 3 divisions, the covert channel becomes ineffective as the error rate is too high(>45% error rate). This is because the speculation window is not long enough for the sender instructions to be able to effectively contend with the receiver instructions on the floating point division unit. 

The error rate dramatically decreases as we increase the number of divisions in the receiver. At 9 or more divisions

the covert channel shows very low error rate while showing gradually decreasing transfer rates. 

For this platform, we can see using 12 divisions in the receiver chain is a “sweet spot” in the sense that it offers high enough performance and low noise. While different platforms may have different sweet spots, we nevertheless used the same 12 divisions in all platforms, unless noted otherwise, as it performed reasonably well in all of them. 





































































§ TRANSIENT EXECUTION ATTACKS 



In this section, we present transient execution attacks using the proposed SpectreRewind  covert channel.




 §.§ Meltdown Attack






Meltdown attacks <cit.> allow transient instructions to access secrets belonging to other processes and security domains, including the OS and virtual machines. In this section we describe our modifications to such attacks to utilize SpectreRewind covert channel.

In the Meltdown attack, the attacker attempts to read from a memory address, such as a kernel virtual address. While architecturally such an access will generate an exception, speculatively the access can forward secret data to a dependent load instruction, which encodes the secret into a cache state change, before it can be squashed. 

In our modification, we simply surround the exception generating memory access with DIVSD sender and receiver instructions as shown in Figure <ref>. In more detail, we base our implementation on the original Meltdown open-source repository . We modified a single function  in , which reads a single byte from the given address (), to utilize our SpectreRewind DIVSD covert channel. The rest of the code and other settings are unchanged.

Note that because a Meltdown attack generates exceptions, it is necessary to suppress such exceptions. In the original PoC, either Intel's Transactional Synchronization Extension (TSX) or signal handling was used to suppress  exceptions. In our approach, however, an exception generating secret memory access can only occur in a mis-speculated transient execution, which will be squashed when the the receiver code has completed. Thus, we effectively suppress the exception without needing to use TSX or signal handling methods used in the original Meltdown PoC.


<https://github.com/IAIK/meltdown>

Table <ref> compares the performance of our modified Meltdown attack  with the original ones, which utilize flush+reload based covert channels. Of the two original versions we evaluated, Original (SigHandle) suppresses exception by installing a signal handler while the Original (TSX) does so by utilizing TSX. We use the reliability PoC in the official Meltdown repository, which continuously reads a single byte from a kernel memory address and reports the number of reads and the success (i.e., correct reading) rate. In each configuration, we ran the reliability PoC for 60 seconds and measured the performance on the Intel Core i5-6500 (Skylake) processor, which supports TSX. As can be seen in the table, our SpectreRewind version of Meltdown performs significantly faster than the signal handler version of the original Meltdown in terms of the speed and the success rate, while it performs similarly compared to the TSX version of the original attack. 
















 §.§ Sandbox (JavaScript) Attack






One of the drawbacks of SpectreRewind is the amount of ops it requires to exist in the ReOrder Buffer simultaneously. While we have shown that this is not a problem when executing attacks in a native environment, sandbox environments—e.g. JavaScript—pose additional challenges. In this section, we show that it is possible to mount SpectreRewind attacks from sandbox environments by porting our floating point  based covert channel code to JavaScript, and successfully executing it on Google Chrome version 62.0.3202.75. For a high resolution timer, we take the same approach as past research <cit.> and utilize Web Workers along with . This allows for the creation of a separate thread, that continuously increments a value in shared memory that the original thread can use to time code execution. Overall, we found that minimal changes were needed to port our code. 

Figure <ref> shows a snippet of the final code along with the generated assembly produced by the JavaScript JIT compiler side-by-side with the original attack code assembly. While the op footprint is increased from the native compiled version, we interestingly find that the majority of these extra instructions happen in the section of code that is responsible for accessing the message and branching on bit values. We see that the division operations are compiled down neatly into only a couple of floating point instructions, and we note that the extra vmovapd instructions added in the JIT compiler version do not take up any ops and thus the two areas of the code provide equivalent pressure on the ROB and scheduler. We also find the attack can still fit within the scheduler and ReOrder Buffer of a Kabylake R micro-architecture, and while the resolution of the SharedArrayBuffer is poor compared to native timers that the difference between timing bit values is sufficient for data transmission. We have however increased the number of receiver code divisions from 12 to 24 to improve signal over the lower resolution timer. We show the probability distribution of the transmission in Figure <ref>.






































































































§ DISCUSSION


In this section, we discuss the benefits and shortcomings of SpectreRewind, and its mitigation options.





 §.§ Comparison to Cache Covert Channels

To date, most transient execution attacks leverage cache based covert channels, especially Flush+Reload <cit.>, due to their high performance and low noise.
In this paper, we find that our floating point division unit based covert channel is available in a wide range of micro-architectures while providing similarly high performance and low noise characteristics. 
As such, we believe that our floating point division unit covert channel can be used as an alternative to cache based ones for transient execution attacks.
Our covert channel may be preferable to Flush+Reload in environments where instructions to flush cache lines (e.g.  in x86) are unavailable. In these environments, eviction sets must be created, but these channels can be noisy, especially in processors that use pseudo random cache replacement schemes <cit.>. 

We also note that recently many researchers have proposed solutions to protect cache based covert channels. For example,  
InvisiSpec <cit.> and SafeSpec <cit.> are both recently proposed hardware solutions that defer updating microarchitectural states of caches (and TLBs) until such changes are considered to be safe. 

Gonzalez et al <cit.> actually implemented such a defense on an out-of-order open source RISC-V processor core. 
CleanupSpec <cit.> lets the microarchitectural changes from transient instructions to occur but later undo those changes after recognizing mis-speculation. 
SpectreRewind can bypass these defense mechanisms, as complete transmission of secret over the covert channel is accomplished—in forms of increased execution time of the receiver—before the transient instructions are completed, which make the aforementioned defense mechanisms ineffective.



One downside of our approach is that it requires that sender and receiver instructions be present simultaneously at the same hardware thread, which restricts its use in cross-process attack scenarios (e.g., cross-process branch target injection attack <cit.>). 
In addition, the sender and receiver instructions must be in the same protection domain—either both in kernel or both in user. Therefore, initiating the receiver instructions at the user-level while executing the sender instructions at the kernel (e.g., a system call) may not be feasible. 













 §.§ Mitigation Strategies




As SpectreRewind requires out-of-order contention on not fully pipelined functional units in the processor, one mitigation strategy is to redesign the functional units to be fully pipelined. But such a re-desing may not always be possible.  


Another alternative is to adopt a strict in-order scheduling policy such that younger instructions (sender) can never be issued before all older instructions are issued first, though it would incur high performance cost. 





SpectreRewind also requires secret data be forwarded transiently to the dependent instructions that cause the contention. Therefore, it can be mitigated through solutions that block or delay such forwarding. SpectreGuard <cit.> is an example of such an approach, where secret data is marked as secret in the page tables and then is disallowed from being forwarded to dependent instructions until it reaches a point where it can be logically considered safe to forward. ConTExT <cit.> uses a similar approach, still marking data as secret in page tables and delaying forwarding of the secret value, but unlike SpectreGuard, not considering operations as safe until they reach the head of the ROB. Intel and NVIDIA also proposed new memory type based solutions <cit.>. STT <cit.> improved upon these approaches, by considering if the instructions being forwarded secret data could transiently leak data into a covert channel, and if it could not, allowing that instruction to execute speculatively. 
All these techniques that prevent secret dependent speculative execution may mitigate SpectreRewind covert channels. 


§ RELATED WORK


Cache based covert channels generally utilize the property that timing differences occur when accessing different levels of the cache, and these timing difference can be large—e.g. 1s of nanoseconds to access the L1 cache vs 100s of nanoseconds to access main memory on common high performance systems. Changes to the cache can also be long lasting (remain across context switches) as generally cache state changes remain until they are replaced by other memory accesses. Prime+Probe <cit.> takes advantage of the fact that caches are generally partitioned into sets that can hold a limited number of cache lines. Once the attacker finds a grouping that perfectly fills the set, measuring the access time of accessing the entire set allows the attacker to monitor other memory access across the system that are utilizing that same set which can be used as a side-channel to spy on a victim. Flush+Reload <cit.> is a cache based technique that uses special hardware instructions provided by architectures to flush cache lines from the caches. If the attacker shares memory with the victim, they need only flush a shared memory location, let the victim execute, and then time a reload to the memory location to determine if it was accessed by the attacker. Both techniques are commonly used in transient execution attacks to monitor cache activity performed by the transient instructions.  

Systems that implement simultaneous multi-threading (SMT), are particularly open to the creation of covert channels, as the multiple threads that run on a single core can potential share and thus compete for the resources on the core.
Wang and Lee explored functional unit sharing in SMT processors to create a covert channel <cit.>. In their work, they created a covert channel—on a Pentium 4 processor—by utilizing contention on the shared integer multiplication unit. Concurrently, Acıiçmez and Seifert utilized contention on the same Intel processor—again using the shared integer multiplication unit—to create a microarchitectural side channel <cit.>. Utilizing this channel, the attacker could spy on another process running a square and multiply cryptographic function that was running concurrently on a separate hardware thread on the same core. Our work differs from these papers, as we explore the unique challenges of both creating similar functional unit covert channels, but from a non-SMT context—single hardware thread—and utilizing such contention in Spectre Attacks.

In 2016, Fogh introduced a technique called Covert Shotgun <cit.> in-which two processes running on threads in the same SMT core run through an iterative set of instruction groupings and time the results to determine if those instructions can cause measurable contention on the shared resources. Recently, two works have concurrently implemented such an approach to test the viability of port contention as a covert channel between two such processes. This approach utilizes the fact that ports may only issue one instruction per cycle to their underlying functional units, thus if both processes attempt to issue instructions that require functional units on the same port, one of the processes will need to stall that clock cycle—causing a measurable timing difference. PortSmash <cit.> utilized port contention to create a microarchitectural side-channel to leak the secret key from a vulnerable version of OpenSSL. SmotherSpectre <cit.> utilized port contention as the covert channel in a Branch Target Injection (BTI <cit.>) Spectre attack. Using BTI allowed this attack to run attacker code to transiently access secret in the victim and then to execute specific instructions—dependent on secret value—that could be easily detected by the attacker's process. Our work differs from all three approaches as we focus on non-SMT contention channels which face unique challenges, and from the latter two as we focus on functional unit contention, and not port contention.







§ CONCLUSION AND FUTURE WORK

In this paper, we showed that it is possible to create a covert channel utilizing concurrent contention on functional units from a single hardware thread. We introduced a new covert channel, which utilizes contention on the floating point division unit in commodity Intel, AMD, and ARM processors. Our covert channel achieved high performance and low noise comparable to that of the widely used Flush+Reload cache covert channel. 
We then showed that how the covert channel can be used in transient execution attacks. We implemented a Meltdown attack with our covert channel. We also showed that our covert channel can be used in the JavaScript sandbox of a Chrome browser. 


As future work, we plan to investigate if other microarchitectural structures can be used to create concurrent contention based covert channels. 









ACM-Reference-Format



