On Mon, Oct 12, 2026 at 11:41:03AM -0700, Kees Cook wrote:
> On Mon, Oct 12, 2026 at 11:22:50AM +0200, Peter Zijlstra wrote:
> > I am confused.. I don't see a computed goto in __bpf_prog_run(), and we
> > build with -fno-jump-tables.
>
> It's the interpreter, ___bpf_prog_run() (three underscores) in
Durr, clearly I wasn't wearing my glasses or something.
> kernel/bpf/core.c, not the __bpf_prog_run() wrapper in filter.h:
>
> static const void * const jumptable[256] __annotate_jump_table = {
> [0 ... 255] = &&default_label,
> ...
> };
> ...
> select_insn:
> goto *jumptable[insn->code];
>
> So it's a manually constructed jump table, not the "normal"
> table-from-switch stuff that -fno-jump-tables suppresses (though see
> below about Clang). objtool already knows about it, with annotations
> added back in 2019 in commit e55a73251da33 ("bpf: Fix ORC unwinding in
> non-JIT BPF code").
>
> With retpolines, GCC emits a single dispatch that every handler uses:
>
> movzbl (%rbx),%esi
> movzbl %sil,%edx
> mov jumptable(,%rdx,8),%rdx
> jmp __x86_indirect_thunk_rdx
>
> Clang never has this jump: with retpolines, LLVM's IndirectBrExpand pass
> turns the label addresses into indexes and the "goto *" into a switch,
> which Clang's -fno-jump-tables then makes a compare tree. So it's only
> constructed this way under GCC, but since now we can turn on kCFI with
> GCC, the objtool warning about indirects without kcfi protection trips.
OK, then the next question; do we *want* to allow a 'naked' indirect
branch to survive?
We can simply disable the whole interpreter when kcfi=y. Isn't that
thing recommended disabled anyway?