Retpoline integration
Mike Hearn
mike at plan99.net
Thu Jan 4 14:38:40 UTC 2018
Hello,
I'm sure many of us spent this morning reading about the new set of side
channel based attacks that dropped today (Spectre and Meltdown
<https://spectreattack.com/>). Looks like the talk I gave on side channels
to the Graal team in Zürich may have been well timed!
While some of these attacks are mitigated by kernel changes, Spectre seems
to have the problematic property that it works across protection domains
against programs that contain indirect jumps/virtual calls i.e. all of
them. Programs that contain such code patterns can have sensitive data
extracted that was meant to be protected by the page table mappings.
There is a fix, at least for the current wave of side channel attacks (we
will without a doubt see more advanced attacks in future). It is truly
atrocious but easy to implement inside a JIT compiler. Google describe it
conceptually here:
https://support.google.com/faqs/answer/7625886
A patch for LLVM is available here - I provide a Google cache link because
LLVM's review website appears to have been taken offline, probably by
weight of traffic right now. Arm's website is also hosed, very likely for
the same reason.
http://webcache.googleusercontent.com/search?q=cache%3Ahttps%3A%2F%2Freviews.llvm.org%2FD41723&oq=cache%3Ahttps%3A%2F%2Freviews.llvm.org%2FD41723&aqs=chrome..69i57j69i58.950j0j4&sourceid=chrome&ie=UTF-8
Essentially all calls that cannot be devirtualised have to jump through a
special code pattern that has the effect of breaking the speculative
execution unit on the core (the so-called "ret trampoline" or "retpoline").
Unfortunately this has a performance impact: LLVM team report about 10% on
real world software, that's *after* PGO is applied. I hope that the JVM is
capable of devirtualising more calls than LLVM can.
Please note that the actual code pattern that should be used seems to be
varying between different projects, perhaps due to the early collapse of
the security embargo. The Linux kernel is using *lfence* instructions to
block speculative execution, but the Google web page describes using *pause*
to put the speculated execution stream into an infinite loop. According to
a footnote in the Spectre paper *lfence* is sufficient to block speculation
and Intel is updating their ISA reference to make this behaviour officially
documented, so *lfence* is probably the one to go for.
Are there any plans to update Graal or C2 to include this optional
mitigation? (optional because, it only matters if you share your CPU cores
with untrusted code).
More information about the graal-dev
mailing list