Retpoline: A Branch Target Injection Mitigation [pdf]
software.intel.com
software.intel.com
That definitely was not the intent! Getting retpoline to the place it is today took a ton of work from a ton of people, including the awesome folks at Google like Paul Turner, and countless people in the Linux community.
> In response to issues identified by external researchers, Intel has performed an in-depth comprehensive security review of its Intel® Management Engine (ME), Intel® Trusted Execution Engine (TXE), and Intel® Server Platform Services (SPS) with the objective of enhancing firmware resilience.
As a result, Intel has identified several security vulnerabilities that could potentially place impacted platforms at risk. Systems using ME Firmware versions 6.x/7.x/8.x/9.x/10.x//11.0/11.5/11.6/11.7/11.10/11.20, SPS Firmware version 4.0, and TXE version 3.0 are impacted.
https://security-center.intel.com/advisory.aspx?intelid=INTE...
And pretty much all of Intel's press releases surrounding Meltdown and Spectre have been almost as misleading, too, one way or another.
[iwork@google]
"When the return stack buffer “stack” is empty on [>= Skylake] processors, a RET instruction may speculate based on the contents of the indirect branch predictor, the structure that retpoline is designed to avoid. The RSB may become empty under the following conditions:
1. Call stacks deeper than the minimum RSB depth (16) may empty the RSB when executing RET instructions. This includes CALL instructions and RET instructions within aborting TSX transactions.
[list of ~10 other situations that empty the RSB stack]"
They describe an "RSB stuffing" procedure, but I don't see any realistic way to guarantee that it happens properly with general code. How many call stacks do you have that are more than 16 frames deep? How many of those are recursive or dynamic?
You ask how it can be guaranteed with "general code". The first thing to remember is that retpoline is not for "general code". Linux, for instance, does not support arbitrary call depth and barely uses recursion.
Also, take a close look at the "Exploit Composition" section of the paper. Those five conditions are much harder to satisfy at 'RET' than they are during the demonstrated Spectre variant 2 exploit points. For instance, a long speculation window (#5) for 'RET' is interesting to generate since it means a stall while waiting on something to come off the stack.
(Of course, that means that all libraries you link with or dynamically load have to be compiled with retpoline too.)