Non-engineer here, this bit is key right:
> However, suppose we flush our cache before executing the code, and arrange a, b, c, and d so that v is zero. Now, the speculative load in the third cycle:
> v, y_ = u+d, user_mem[x_]
> will read from either address 0x000 or address 0x100 depending on the eighth bit of the result of the illegal read. Because v is zero, the results of the speculative instructions will be discarded, and execution will continue. If we time a subsequent access to one of those addresses, we can determine which address is in the cache. Congratulations: you’ve just read a single bit from the kernel’s address space!
To my understanding it is that saying that by...
1) ...flushing the cache so you have a 'clean' state, you can get...
2) ...the speculative execution to 'pull in' to cache the address user_mem[x_] but...
3) ...the particular address that's pulled into cache, 0x000 or 0x100, is determined by whether...
4) ...the illegal read of kern_mem[address] 8th bit was a 1 or 0...
5) ...which you can then subsequently determine the value of by...
6) ...timing how long it takes to access that user_mem[x] address once again and...
7) ...thereby leaking the value of kern_mem[address]...
So you still have to perform some logic on the result of the speed of the access to the secondary address read right?
If read of 0x000 is slow you know kern_mem[address] was a 1 and if fast kern_mem[address] a 0, and if 0x100 is slow you know kern_mem[address] was a 0 and if fast that kern_mem[address] was a 1?
Is that correct?
If it is it seems that timing is the key right, and actually the clever leap of creativity in completing the exploit, at least to my untrained mind.
Please do correct anything I've got wrong, I'm not an engineer/developer!