Re: [patch 00/38] x86/retbleed: Call depth tracking mitigation
From: Joao Moreira
Date: Mon Jul 18 2022 - 18:47:44 EST
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