Re: [patch 00/38] x86/retbleed: Call depth tracking mitigation

Joao Moreira
2022-07-18T22:47:45Z

On 2022-07-18 15:22, Thomas Gleixner wrote:
> On Mon, Jul 18 2022 at 23:18, Peter Zijlstra wrote:
>> On Mon, Jul 18, 2022 at 10:44:14PM +0200, Thomas Gleixner wrote:
>>> And we need input from the Clang folks because their CFI work also
>>> puts
>>> stuff in front of the function entry, which nicely collides.
>>
>> Right, I need to go look at the latest kCFI patches, that sorta got
>> side-tracked for working on all the retbleed muck :/
>>
>> Basically kCFI wants to preface every (indirect callable) function
>> with:
>>
>> __cfi_\func:
>> int3
>> movl $0x12345678, %rax
>> int3
>> int3
>> \func:
>> endbr
>> \func_direct:
>>
>> Ofc, we can still put the whole:
>>
>> sarq $5, PER_CPU_VAR(__x86_call_depth);
>> jmp \func_direct
>>
>> thing in front of that. But it does somewhat destroy the version I had
>> that only needs the 10 bytes padding for the sarq.
>
> Right, because it needs the jump. I was just chatting with Jaoa about
> that over IRC.
>
> The jump slow things down. Jaoa has ideas and will reply soonish.

So, IIRC, kCFI will do something like this to validate call targets
based on the hash as described on Peter's e-mail:

func_whatever:
...
cmpl $0x\hash, -6(%rax)
je 1f
ud2
1:
call *%rax
...

Thus the hash will be 6 bytes before the function entry point. Then we
can get the compiler to emit a padding area before the __cfi_\func
snippet and, during boot, if the CPU needs the call depth tracking
mitigation, we:
- move the __cfi_func into the padding area
- patch the call depth tracking snippet ahead of it (overwriting the old
__cfi_\func:)
- fix the cmpl offset in the caller

func_whatever:
...
cmpl $0x\hash, -FIXED_OFFSET(%rax)
je 1f
ud2
1:
call *%rax
...

This approach is very similar to what we discussed in the past for
replacing kCFI with FineIBT if CET is available. Also, it would prevent
the need for any jump and would keep the additional padding area in 10
bytes.

Tks,
Joao