3

In spectre vulnerability describing paper, we can see that it talks about this specific vulnerability

if (x < array1_size)
   y = array2[array1[x] * 256];

In spectre vulnerability, according to the paper, they first pass many legal values for x such that branch predictor gets trained and starts speculating the next statement i.e. start executing y = array2[array1[x] * 256];. And after long enough iterations , when branch predictor has been trained , malicious value of x is passed and in this case processor starts speculatively executing y = array2[array1[x] * 256]; and this time it loads array1[x] in cache which cannot be reverted as of now and can be used by attacker for a side channel attack.

So my question is why do we need to have this if statement as well. If there would have been this statement only

   y = array2[array1[x] * 256];

Shouldn't this above statement along ( without if ) would have been sufficient to load this array1[x] into cache. Why do we need even this if statement ?

mridul_verma
  • 265
  • 1
  • 10
  • 2
    `Why do we need even this if statement?` - When talk about vulnerability attacks, **attacker has no control over the victim's code**: the code is already written and compiled into the software. In given case original code already includes `if` statement, which (normally) should prevent branch to be executed on incorrect `x`. – Tsyvarev Mar 04 '18 at 09:30
  • 1
    Yeah got it thanks @Tsyvarev. Actually i misunderstood this as a attackers code but came to realise later on that this clients code and attack is basically feeding x to the client's program. – mridul_verma Mar 04 '18 at 18:09

2 Answers2

0

Why do we need even this if statement ?

We need the if statement to 1) create a time window, so the attack is possible and 2) avoid program to crash.

Creating Time Window for the Attack

The main purpose of the if is to create a time window. To make it happened, array1_size MUST NOT be in cache.

Once we get to the if statement, CPU waits for the array1_size to load from the main memory. Meanwhile, branch predictor says "take the branch" and speculative execution goes forward, accessing data outside the array1 and making side effects on array2.

It would not be possible if the array1_size were in cache. Indeed, CPU would realized very quickly that the x is outside the range and aborted the speculative execution.

Avoid Crashes

While we train the branch, all the x values are within array1. But once we want to read data outside the array1 (i.e. read a secret), we pass a huge, out of range x. If we have no access to that memory (i.e. the memory is in kernel space), our program will crash with Segmentation Fault or similar error.

CPU masks any faults during speculative execution until the instruction is actually retired. The if makes sure the instructions with invalid x will never be retired. They just make a side effect and get flushed once the CPU realizes the speculation went wrong.

Simple Example

Here is my simple example of Specter-Based Meltdown attack (i.e. 2-in-1): https://github.com/berestovskyy/spectre-meltdown

IMO it is much simpler and easier to understand than the original code from the Specre paper. And it has just 99 lines in C (including comments).

Andriy Berestovskyy
  • 8,059
  • 3
  • 17
  • 33
  • What i have come to know from my readings from paper and different blogs , spectre is a client side vulnerability in which we take advantage of this kind of code in which we check for bounds and then try to access the array like in any safe language. Like in browsers we can execute this piece of code ( for spectre ) and then transfer the inner memory contents of the process like stored passwords back to the attacker. – mridul_verma Mar 06 '18 at 16:47
  • @mridul_verma Right. Instead of `if` statement we can can also use other techniques, like signal handler (to avoid crashes) or transactional memory. We can use Spectre to attack from browser sandbox (JavaScript) or to access kernel space (like my Specter-Based Meltdown example above). There are a variety of possible usages, that is why it is called Spectre ;) – Andriy Berestovskyy Mar 06 '18 at 19:49
0

The array access is always bounded by a boundary check, without this boundary check, it is a normal buffer overflow programming BUG which can be easily exploited without using speculative execution.

winter
  • 51
  • 4