Re: [PATCH v4 09/10] x86/ibt: Implement FineIBT-BHI mitigation

Peter Zijlstra
2025-02-25T09:12:27Z

On Mon, Feb 24, 2025 at 01:37:12PM +0100, Peter Zijlstra wrote:
> While WAIT_FOR_ENDBR is specified to be a full speculation stop; it
> has been shown that some implementations are 'leaky' to such an extend
> that speculation can escape even the FineIBT preamble.
>
> To deal with this, add additional hardening to the FineIBT preamble.
>
> Notably, using a new LLVM feature:
>
> https://github.com/llvm/llvm-project/commit/e223485c9b38a5579991b8cebb6a200153eee245
>
> which encodes the number of arguments in the kCFI preamble's register.
>
> Using this register<->arity mapping, have the FineIBT preamble CALL
> into a stub clobbering the relevant argument registers in the
> speculative case.
>
> (This is where Scott goes and gives more details...)

Scott, could you give a blurb here? Would the below cover things?

The basic setup, for 1 argument, is something like:

__bhi_args_1:
jne .Lud
cmovne %r10, %rdi
ret
int3

__cfi_foo:
endbr
subl $hash, %r10d
call __bhi_args_1
foo:
osp nop3
...

such that when speculation of an indirect call is maliciously steered
here from a non-matching site, the hash check (__cfi_foo's SUB) will not
match, resulting in !ZF and non-zero R10. Subsequently the __bhi_args
stub will either hit #UD exception, which kills speculation, or when
steered wrong, hit the cmovne, which will then clobber the argument
register RDI with whatever non-zero garbage sits in R10. Making it much
harder to control whatever foo normally does with its input argument.

Additionally, CFI hashes are randomized at boot, making it much harder
still to predict/control the non-zero value.