What Is Spectre? The Spectre Vulnerability Explained
What is Spectre? In this blog, we'll explain what is Spectre and how to prevent similar software vulnerabilities.
Read along or jump ahead to the section that interests you the most:
- What Is Spectre?
- What Is Spectre: The Spectre Vulnerability Explained
- How Klocwork Detects the Spectre Vulnerability
- How to Prevent the Spectre Vulnerability With Klocwork
What Is Spectre?
Spectre is a software vulnerability that allows arbitrary locations in memory to be read.
What Is Spectre: The Spectre Vulnerability Explained
The vulnerability involves a malicious program gaining access to data that it shouldn’t have the right to see. It does so by exploiting two important techniques used to speed up computer chips called speculative execution and caching.
Top 10 Security Vulnerabilities
Spectre is just one potential vulnerability. There are countless others. Get the top 10 in our white paper.
How Klocwork Detects the Spectre Vulnerability
To understand how the Klocwork checker works, we’ll walk through this example found in the Spectre white paper (PDF). The protected data resides in an out-of-boundary memory area of:
Examining lines 14 and 15 above, the code looks generally secure. The execution of the following piece of code is protected by the bounds check seen on line 14:
secret_value = arr1->data[offset]
However, due to the possibility of speculative execution, the protection of this bounds check can be bypassed if the following conditions exist:
- The protected data has the potential to be cached in a CPU register due to speculative execution.
- The offset variable is also in the CPU cache due to speculative execution.
If these conditions are satisfied, the exploit proceeds this way:
- On line 14, offset is compared with:
- Given offset is a cache hit and arr1->length is a cache miss, the CPU requests the value of arr1->length to be loaded into the L1 cache.
- As it may take several hundred CPU cycles to load the value, the CPU may start executing line 15 speculatively.
- On line 15, the value of the offset (assuming it’s been maliciously set by an attacker through a timing attack) points to the protected data, and the value is read as a cache hit, becoming immediately available and stored in secret_value.
- On line 17, given the read arr2->data is a cache miss, the CPU requests the value to be loaded from the next level cache (or DRAM).
- Once the value of arr1->length arrives in L1 cache, the CPU realizes the branch was mispredicted, and execution starts along the else branch instead.
- The value of arr2->data[secret_value * 256] now arrives in the L1 cache and is exposed to an attacker via a timing attack.
Why Use a Spectre Checker?
The checker in Klocwork tracks tainted, untrusted, or otherwise suspicious data along all possible execution paths in code.
Specifically, SPECTRE.VARIANT1 checker does two things:
Detects possible instances of tainted data. In the above example, Klocwork has flagged the input parameter offset for this reason.
Identifies suspicious code patterns. Klocwork has highlighted lines 14-15 below due to the possibility of speculative execution.
How to Prevent Spectre With Klocwork
Now that we’ve explained the vulnerability and discussed how Klocwork’s SPECTRE.VARIANT1 checker works, we’ll walk you through a real-life example, demonstrating step-by-step how Klocwork helps you detect and remediate this serious exploit.
The code we use for our example was originally published by Erik August Johnson. (We highly encourage you to download it and try our checker for yourself.) This walkthrough uses the Klocwork Desktop Plugin for Visual Studio, but similar steps can be applied to any version of Klocwork that you have.
1. Use the Klocwork Spectre Checker
Here are our instructions on how to use Klocwork’s checker:
- Configuring the Checker.
- Open the Klocwork Solution Properties dialogue box by right-clicking a solution in the Solution Explorer.
- Then select Klocwork Solution Properties and enable SPECTRE.VARIANT1.
2. Locate the Spectre Vulnerability
Once the analysis is complete, you’ll see the results highlighted in the desktop editor.
In the below code, there are two conditions that indicate the potential for the vulnerability to exist:
Potentially untrusted data ‘x’ on line 42.
Untrusted data ‘x’ used in a branch that may be executed under speculative execution.
3. Fix Spectre Vulnerability Defects
As per Intel’s recommendation, the vulnerability can be remediated using the LFENCE instruction to stop speculative execution locally. Using _mm_lfence(), Intel’s compiler can implement this instruction. Inserting it before the untrusted data is used to access the array on line 43, and re-running Klocwork analysis, removes the reported defect.
4. Use Your Own Spectre Mitigation Function
If you have your own Spectre mitigation function, you can include a custom KB in the Klocwork analysis, identifying areas of code to the checker that you know aren’t vulnerable. To illustrate this case, we will insert the following fence instruction intrinsic function on line 45, and re-run Klocwork analysis:
The same defect as before is reported because Klocwork doesn’t recognize my_fence_intrinsic() as remediation to the exploit. Since we know that it is, we include a custom KB file into the project (instructions here) with the following KB record:
my_fence_intrinsic – FENCE
Running the analysis again removes the reported defect once Klocwork recognizes the intrinsic function.
Prevent Vulnerabilities — Like Spectre — With Klocwork
Sign up for our on-demand demo of Klocwork to learn how it can prevent software vulnerabilities. Or, register for a free trial.