Meltdown, different from other attacks preceded it in the stack since last year, it is a combination of methods unified together in order to take advantage of a feature and not a bug. what makes this attack special? and how to implement a toy example?

Meltdown

The CPU  was created to work full time job without coffee breaks. due to that vow, latency time is not welcomed and it is something the processors manufacturers need to get rid of it.

Here comes the performance feature called out-of-order execution aiming to minimize the experienced latency when the CPU need to wait for fetching data from memory. during this busy execution, the processor schedule subsequent operations to the idle cpu units.

It sounds faithful intentions until meltdown exposed a flaw where the adversary can put hands on secret data in the time slot when the cpu read the data and realize what it has done is a mistake.

Under the hood

What makes meltdown so special is the fact that the adversary can dump the kernel memory or other processes virtual memory without the need to escalate execution privileges. This can be done in two steps.

Step 1: Utilize the out-of-order execution

We want to execute a command that grant us access to sensitive data such as kernel memory. if the malicious code raise an exception right before trying to read sensitive data, the out-of-order execution will try and load the sensitive data as shown in the next psaudo-code:

raise_exception();
access(probe_array[data * 4096]);

The second line will never get executed, However, thanks to the side-effect of the out-of-order execution, the subsequent instruction might be partially executed and the referenced memory is fetched into a register and also cached – As the processor doesn’t realize that the second line should not be executed.

Step 2: Running a Side-Channel attack

In the previous step, there is a possible race condition where the processor didn’t retired the subsequent command before running the out-of-order execution.  In this case, we can run a side channel attack to have a look into the cache hoping that maybe we have cached the referenced data in line 2. In this case, we can use the Flush+RELOAD attack in order to read the cache.

A trivial approach to run the attack is to fork a child process which will be responsible to access the invalid memory and crash. The parent will run the Flush+Reload attack in order to read the cache as depicted in the next snippet:

child = fork();
if(child == 0){
       address = access(probe_array[data * 4096]);
}else{
      run_flush_and_reload(address );
}
 

Of course it is possible to override a seg-fault signal handler in order to run the Flush+Reload.

Exposing the sensitive data sections

The address space of every process, contains the entire user space as well as the entire kernel space which include any mapped physical memory.

The Flush+Load need the data to enter the register. When the adversary tries to read the secret memory, it is represented as a virtual address. The CPU will translate the virtual address into physical address in order to claim the data which it can even if it is not accessible.

If the CPU finds out that the targeted data is not accessible due to permission bit or inappropriate permission level, it will raise an exception. This is the small time window where the meltdown comes in handy.

Limitations

As mentioned before, the attack must run after the out-of-order execution finishes its job and before the CPU raise access exception. However, if the CPU raises the exception before the out-of-order execution, The adversary will read false data which is equal to zero as the CPU will flush the process’s registers. In this case, the adversary need to check the referenced data which is zero or not.

Implementation

I am working on implementing a toy example for the flow. Follow this blog to stay tuned and star the repository at github. Here.