On Mon, Jan 8, 2018 at 6:23 AM, Alan Modra <amo...@gmail.com> wrote: > On Sun, Jan 07, 2018 at 04:36:20PM -0700, Jeff Law wrote: >> On 01/07/2018 03:58 PM, H.J. Lu wrote: >> > This set of patches for GCC 8 mitigates variant #2 of the speculative >> > execution >> > vulnerabilities on x86 processors identified by CVE-2017-5715, aka Spectre. > [snip] >> My fundamental problem with this patchkit is that it is 100% x86/x86_64 >> specific. > > It's possible that x86 needs spectre variant 2 mitigation that isn't > necessary on other modern processors like ARM and PowerPC, so let's > not rush into general solutions designed around x86.. > > Here's a quick overview of Spectre. For more, see > https://spectreattack.com/spectre.pdf > https://googleprojectzero.blogspot.com.au/2018/01/reading-privileged-memory-with-side.html > https://developer.arm.com/-/media/Files/pdf/Cache_Speculation_Side-channels.pdf > > The simplest example of ideal "gadget" code that can be exploited by > an attacker who can control the value of x, perhaps as a parameter to > some service provided by the victim is: > > char *array1, *array2; > y = array2[array1[x] * cache_line_size]; > > The idea being that with the appropriate x, array1[x] can load any > byte of interest in the victim, with the array2 load evicting a cache > line detectable by the attacker. The value of the byte of interest > can then be inferred by which cache line was affected. > > Typical code of course checks user input. > > if (x < array1_size) > y = array2[array1[x] * cache_line_size]; > > Spectre variant 1 preloads the branch predictor to make the condition > predict as true. Then when the out-of-range value of x is given, > speculative execution runs the gadget code affecting the cache. Even > though this speculative execution is rolled back, the cache remains > affected.. > > Spectre variant 2 preloads the branch target predictor for indirect > branches so that some indirect branch in the victim, eg. a PLT call, > speculatively executes gadget code found somewhere in the victim. > > > So, to mitigate Spectre variant 1, ensure that speculative execution > doesn't get as far as the array2 load. You could do that by modifying > the above code to > > if (x < array1_size) > { > /* speculation barrier goes here */ > y = array2[array1[x] * cache_line_size]; > } > > But you could also do > > if (x < array1_size) > { > tmp = array1[x] * cache_line_size; > /* speculation barrier goes here */ > y = array2[tmp]; > } > > This has the advantage of killing variant 2 attacks for this gadget > too. If you ensure there are no gadgets anywhere, then variant 2 > attacks are not possible. Besides compiler changes to prevent gadgets > being emitted you also need compiler and linker changes to not emit > read-only data in executable segments, because data might just happen > to be a gadget when executed.
See: https://sourceware.org/ml/binutils/2017-11/msg00369.html -- H.J.