On 12/01/18 17:49, David Woodhouse wrote: > When we context switch from a shallow call stack to a deeper one, as we > 'ret' up the deeper side we may encounter RSB entries (predictions for > where the 'ret' goes to) which were populated in userspace. This is > problematic if we have neither SMEP nor KPTI (the latter of which marks > userspace pages as NX for the kernel), as malicious code in userspace > may then be executed speculatively. So overwrite the CPU's return > prediction stack with calls which are predicted to return to an infinite > loop, to "capture" speculation if this happens. This is required both > for retpoline, and also in conjunction with IBRS for !SMEP && !KPTI. > > On Skylake+ the problem is slightly different, and an *underflow* of the > RSB may cause errant branch predictions to occur. So there it's not so > much overwrite, as *filling* the RSB to attempt to prevent it getting > empty. This is only a partial solution for Skylake+ since there are many > other conditions which may result in the RSB becoming empty. The full > solution on Skylake+ is to use IBRS, which will prevent the problem even > when the RSB becomes empty. With IBRS, the RSB-stuffing will not be > required on context switch.
If you unconditionally fill the RSB on every entry to supervisor mode, then there are never guest-controlled RSB values to be found. With that property (and IBRS to protect Skylake+), you shouldn't need RSB filling anywhere in the middle. ~Andrew