[PATCH v2 0/2] x86/bpf: Fix FineIBT vs eBPF

Peter Zijlstra
2023-11-30T13:43:25Z

Hi!

There's a problem with FineIBT and eBPF using __nocfi when
CONFIG_BPF_JIT_ALWAYS_ON=n, in which case the __nocfi indirect call can target
a normal function like __bpf_prog_run32().

Specifically the various preambles look like:

FineIBT JIT

__cfi_foo:
endbr64
subl $hash, %r10d
jz 1f
ud2
1: nop
foo: foo:
osp nop3 endbr64
... ...

So while bpf_dispatcher_*_func() does a __nocfi call to foo()+0 and this
matches what the JIT generates, it does not work for regular FineIBT functions,
since their +0 endbr got poisoned and things go *boom*.

Cure this by teaching the BPF JIT about all the various CFI forms. Notably this
removes the last __nocfi call on x86.

If the BPF folks agree (and the robots don't find fail) I'd like to take this
through the x86 tree, because I have a few more patches that turn the non-fatal
'osp nop3' poison into a 4 byte ud1 instruction which is rather fatal. As a
result this problem will also surface on !IBT hardware.

Changes since v1:
- added wee comment to asm/cfi.h (ast)
- added asm comments to bytecode (ast)
- renamed bpf_func_proto() to __bpf_prog_runX() (ast)
- added bpf_prog_aux::ksym_prefix (ast)