5 ms·
Unfortunately, this gets some big things wrong. Meltdown is not about speculative execution. (Spectre is.) Meltdown is about out-of-order execution - no branche
by scott_s 9y ago
Unfortunately, this gets some big things wrong. Meltdown is not about speculative execution. (Spectre is.) Meltdown is about out-of-order execution - no branches required. The authors are clear about this in the paper. From Section 2.1:
"In practice, CPUs supporting out-of-order execution support running operations speculatively to the extent that the processor’s out-of-order logic processes instructions before the CPU is certain whether the instruction will be needed and committed. In this paper, we refer to speculative execution in a more restricted meaning, where it refers to an instruction sequence following a branch, and use the term out-of-order execution to refer to any way of getting an operation executed before the processor has committed the results of all prior instructions."
In this explanation, the author starts by showing two different code branches, which is misleading. Meltdown does not require code branches - which is what makes it so surprising. This is the C code example from the paper:
raise_exception();
// the line below is never reached
access(probe_array[data * 4096]);
No branches: you have an exception, and then in the code following that exception, you have some memory access. Despite the exception, the access happens because of out-of-order execution. The actual exploit is, in assembly:
; rcx = kernel address
; rbx = probe array
retry:
mov al, byte [rcx]
shl rax, 0xc
jz retry
mov rbx, qword [rbx + rax]
The exception is raised on the mov command, as it loads a kernel address. This exception will eventually cause the processor to abandon all of the current code it is executing, and the program will terminate from a segmentation fault. But. There is a race condition: before the processor deals with the exception, but after the memory has been accessed, the second mov instruction executes, which uses the data which caused the exception. This shouldn't matter, as execution is abandoned, but data is brought into the cache based on this value, and using side-channel attacks, we can figure out what this value was. From the paper:
"To load data from the
main memory into a register, the data in the main memory
is referenced using a virtual address. In parallel to
translating a virtual address into a physical address, the
CPU also checks the permission bits of the virtual address,
i.e., whether this virtual address is user accessible
or only accessible by the kernel. As already discussed in
Section 2.2, this hardware-based isolation through a permission
bit is considered secure and recommended by the
hardware vendors. Hence, modern operating systems always
map the entire kernel into the virtual address space
of every user process.
As a consequence, all kernel addresses lead to a valid
physical address when translating them, and the CPU can
access the content of such addresses. The only difference
to accessing a user space address is that the CPU
raises an exception as the current permission level does
not allow to access such an address. Hence, the user
space cannot simply read the contents of such an address.
However, Meltdown exploits the out-of-order execution
of modern CPUs, which still executes instructions in the
small time window between the illegal memory access
and the raising of the exception."
I find the paper to be very readable. They give a good overview of modern computer architecture, and then walk through all of the steps of their attack. I highly recommend reading it: https://meltdownattack.com/meltdown.pdf https://meltdownattack.com/meltdown.pdf
- Bartweiss 9y agoThanks for this, and for recommending going straight to the paper. It's vastly more readable than most of the simplified explanations of the attack.
- captn3m0 9y agoThanks for pointing this out. I'll be updating the post shortly with changes. I've added a note about going to the source and reading the paper alongside. For others on this thread: +1 on the above recommendation for reading the paper itself. It is very well written and accessible. If you've read the blog post, you know pretty much everything you need to understand the paper.
- scott_s 9y agoNote that this includes your explanation with the check_function() - that is not part of the exploit. The branches in their assembly are only about dealing with the zeros. And, to reiterate: any explanation of Meltdown that depends on branches is incorrect. It's not enough to just use the phrase "out-of-order". All of your examples with if-statements need to change.
- akvadrako 9y agoWhat you are describing is literally speculative. It's executing the 2nd mov, because it speculates it will occur. The choice to throw an exception or not is a branch.
- scott_s 9y ago"Speculative execution" is a term-of-art, with a specific meaning. I can serve you a warmed up Hershey's bar, and it is literally "hot chocolate", but it is not what anyone would expect from that description. When discussing technical matters, it is important to use the right technical terms - hence why the Meltdown and Spectre authors were so careful. But more important than the term is that the submitted description explains the Meltdown attack in terms of branch instructions, which is not how it works. A reader of the submitted description will come away with an incorrect understanding of what actually happens.