Hi folks. <insert caveat about possibly me misunderstanding things>
Spectre is also a vulnerability. It's been discussed in the context of web browsers, but it does have repercussions for kernel. The gist of it seems to be, if you have code that looks like this: Variant 1: if (malicious offset is safe) value = array[malicious_offset]; value2 = (value & 1) value3 = array2[value2] You can read arbitrary memory, as cached memory will be faster. repeat this bit by bit. Variant 2: relies on poisoning the branch predictor if_transmit = mydriver_transmit; .. regular code if_transmit(); /* indirect call */ .. malicious_ptr: value = array[malicious_offset]; value2 = (value & 1) value3 = array2[value2] Now, we poison the branch target buffer, to predict that if_transmit = malicious_ptr. It does not even appear like a possible code path, but it is. This means that code being loaded is enough to pose a risk, even if there is no easy path to it. Some things that help this: - Rather than look for a gadget like this, they went for eBPF, which is like dtrace. It also has a JIT. You can load bytecode and it will verify and execute it. So you can make your own speculation-gadget. - Some archs do not allow fine-grained cache control like x86 clflush, but this isn't necessary for abuse. just fill the cache before going. they have done similar from JavaScript. Some that harm it: - Even speculative execution obeys access restrictions, so SMEP, SMAP, marking memory NX will prevent execution. - Instructions like 'lfence' stop speculative execution. - Intel and AMD have pushed microcode updates that introduce instructions, for Intel they are 'IBPB' and 'IBRS'. - ARM has 'BPIALL' to invalidate the branch target to stop branch predictor poisoning - Retpoline, stuff_RSB etc. to modify jumps to be less likely to jump into user-controlled code. People seemed to occasionally mentioned that 'as many as 100 instructions will be executed speculatively', so that is how far we are talking. Own thoughts: - Variant 1 seems possible to avoid with low cost. It will likely result in an error somewhere along the line, which is detectable. Flushing the entire cache on userret will make it hard to exploit. Do all bound checks failing result in an easily noticed error? - Variant 2 however is harder without custom instructions. Those may rely on a CPU being new enough to receive microcode updates, and them being applied. - I'm not sure how easy it is to find a good enough gadget without something like eBPF, but the mere presence of the code in memory was a risk. - Linux could've marked eBPF non-executable when it is unused, so its presence in memory does not pose risk. Discuss.