x86/cet: Use dedicated NOP4 for cf_clobber
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 8 Mar 2022 13:47:25 +0000 (13:47 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 17 Mar 2022 20:34:06 +0000 (20:34 +0000)
commit89a24719b6591b48f9953fe1bd9db67adbf74736
tree65337e79293ae920d3f95eca1352fb4d50c1c399
parente421ed0f68488863599532bda575c03c33cde0e0
x86/cet: Use dedicated NOP4 for cf_clobber

For livepatching, we need to look at a potentially clobbered function and
determine whether it used to have an ENDBR64 instruction.

Use a non-default 4-byte P6 long nop, not emitted by toolchains, and extend
check-endbr.sh to look for it.  The same logic can check for the absence of
any endbr32 instructions, so include a check for those too.

The choice of nop has some complicated consequences.  nopw (%rax) has a ModRM
byte of 0, which the Bourne compatible shells unconditionally strip from
parameters, meaning that we can't pass it to `grep -aob`.

Therefore, use nopw (%rcx) so the ModRM byte becomes 1.

This then demonstrates another bug.  Under perl regexes, \1 thru \9 are
subpattern matches, and not octal escapes, while the behaviour of \10 and
higher depend on the number of capture groups.  Switch the `grep -P` runes to
use hex escapes instead, which are unambiguous.

The build time check then requires that the endbr64 poison have the same
treatment as endbr64 to avoid placing the byte pattern in immediate operands.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/alternative.c
xen/arch/x86/include/asm/endbr.h
xen/tools/check-endbr.sh