11 ms·
I enjoyed reading this a lot. I wonder why the developers decided to allow reading kernel-memory in the first place. When a scalar processor reads kernel memory
by njitbew 9y ago
I enjoyed reading this a lot. I wonder why the developers decided to allow reading kernel-memory in the first place. When a scalar processor reads kernel memory, it crashes. When a speculative processor reads kernel memory, it relies on the assumption that the read is never committed to prevent leakage. It takes no expert to realise this is a potentially dangerous decision (and, as becomes clear now, is only valid in the absence of a cache).
To me it would make a lot more sense to use a special value to indicate the read did not succeed and propagate this value until it is time to crash. I guess this introduces some overhead (e.g. reserve a special value); but are there any other drawbacks?
- infinite8s 9y agoThis is the part I don't understand. How is the processor able to read a cacheline from a protected memory page without crashing (even if it was speculative and wouldn't happen in the idealized execution due to branching).
- teacpde 9y agot, w_ = a+b, kern_mem[address] u, x_ = t+c, w_&0x100 v, y_ = u+d, user_mem[x_] if v: # fault w, x, y = w_, x_, y_ # we never get here Form the author's example, it seems like the processor is able to read the kernel memory privately (`w_`) and crashes if the code attempts to commit `w_` to `w`. It would be interesting to know how the processor does that.
- pwg 9y agoBecause in the Intel design, for memory reads issued by speculative instructions, any "access denied" results are also delayed until the CPU control unit determines the instruction that issued the read should really have been executed. But the actual read from is allowed to occur, even if the "access denied" signal is given. Which allows the read to effect the state of the data caches. This was likely done this way as a performance booster, because this would allow speculative instructions to also perform cache pre-fetching during their speculation window. That seems to be why AMD CPU's are immune to Meltdown. AMD's design prevents the read from occurring when the "access denied" signal appears, so the cache state is not effected, so there is no side channel to detect.
- stordoff 9y ago> But the actual read from is allowed to occur, even if the "access denied" signal is given. Which allows the read to effect the state of the data caches. This was likely done this way as a performance booster, because this would allow speculative instructions to also perform cache pre-fetching during their speculation window. Why is this? Is it because the CPU doesn't know ahead of time what is valid (because it depends on the "outcome" of instructions in flight), or is there something I'm overlooking?
- pwg 9y agoWell, if you try to put yourself in the mindset of a CPU designer, without extensive cryptography experience [1] to be fully aware of timing side-channel attacks, you would see the speculative execution memory reads as harmless. If the predicted path is wrong, you'll reset the CPU state (cpu registers) so the running program sees nothing different. And if you skip running the reads through the full memory protection gamut (you still have to do the address translation) during the speculation window you'll save a few cycles on the reads, and maybe a tiny bit of power. And in the case that the predicted path was correct, any "access denied" signals need to be delayed until the accessing instruction would commit anyway (to maintain proper sync with how the signal works, in that it indicates which instruction took the memory access fault, so you can't raise the signal until you know for sure the instruction would have executed). And if you see the reads as harmless (because they are thrown away if the speculative guess was wrong) then you might also see them as "free" cache pre-fetch instructions (because they do pre-warm the cache when the speculative path is the correct path). In the end the result is a confluence of several different topic (speculative execution, data caching, high resolution timers [although these can be simulated with a plural CPU system]) that each in isolation is all but harmless, but together emergent behavior appears that was not immediately apparent from each one viewed individually. I.e., without caches there's no side channel to monitor. Without speculative execution there's no way to trick read a bad address and avoid taking a memory access fault. Without high enough resolution timers it becomes very hard detecting the time difference between a cache hit and miss. [1] a reasonably safe assumption - most CPU architecture designers are not cryptographers, and most cryptographers are not CPU architecture designers, and most timing side-channel attacks have historically been against crypto. algorithm implementations.
- jimmies 9y agoThe explanation is at end of page 4 and begin of page 5 on the meltdown paper. In a nutshell, the speculative feature allows the read to happen, it "doesn't segfault," and only signals the OS of the segfault or whatever until it's actually executed.