[PATCH 3/3] objtool: Skip jump table jumps in the kCFI indirect call check
From: Kees Cook
Date: Mon Oct 12 2026 - 05:05:48 EST
With MITIGATION_RETPOLINE=y, GCC lowers the computed goto in
___bpf_prog_run() to a jump through __x86_indirect_thunk_rdx. objtool
puts that jump on the retpoline call list along with the indirect calls,
so with CONFIG_CFI=y the kCFI check wants a UD2 before it:
vmlinux.o: warning: objtool: ___bpf_prog_run+0x1e: no-cfi indirect call!
The jump goes through the "jumptable" array, which objtool already reads
from .data.rel.ro.c_jump_table, so its targets stay inside the function
and need no kCFI check. Skip jump table jumps in the check. Clang does
not emit this jump: with retpolines, it lowers the computed goto without
an indirect jump.
Build tested ARCH=x86_64 defconfig with CONFIG_LKDTM=y and CONFIG_CFI=y,
with GCC 17.0.0 (experimental, with the kCFI series).
Assisted-by: LLM
Signed-off-by: Kees Cook <kees@xxxxxxxxxx>
---
tools/objtool/check.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 464f6c9d9ff0..d35c5305075f 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4199,6 +4199,14 @@ static int validate_retpoline(struct objtool_file *file)
list_for_each_entry(insn, &file->retpoline_call_list, call_node) {
struct symbol *sym = insn_sym(insn);
+ /*
+ * A jump through a jump table stays inside the function, so
+ * it has no kCFI check. GCC turns the computed goto in
+ * ___bpf_prog_run() into one under MITIGATION_RETPOLINE.
+ */
+ if (is_jump_table_jump(insn))
+ continue;
+
if (sym && (is_notype_sym(sym) ||
is_func_sym(sym)) && !sym->nocfi) {
struct instruction *prev =
--
2.55.0