From 3e4279dc5144a5afcda101df23792b13e94c3859 Mon Sep 17 00:00:00 2001 From: "Jose Fernandez (Anthropic)" Date: Fri, 30 Oct 2026 18:14:22 +0000 Subject: [PATCH] bpf: Fix jited line info off by the CFI preamble With CONFIG_CFI=y, every jited line info entry after a function's first is cfi_get_offset() bytes too high on x86-64, riscv64 and arm64, so tools that use it show the wrong source line. The JITs count the insn_to_jit_off[] offsets from the start of the image. Since the CFI commits below, prog->bpf_func starts cfi_get_offset() bytes into the image, and bpf_prog_fill_jited_linfo() adds the offsets to prog->bpf_func. s390 corrects its offsets before the call, the other three JITs do not. Subtract cfi_get_offset() once in bpf_prog_fill_jited_linfo() and drop the s390 correction. jited_linfo[0] stays prog->bpf_func, the function's ksym address. Without CONFIG_CFI, cfi_get_offset() is 0 and nothing changes. Fixes: 4f9087f16651 ("x86/cfi,bpf: Fix BPF JIT call") Fixes: e63985ecd226 ("bpf, riscv64/cfi: Support kCFI + BPF on riscv64") Fixes: 710618c760c0 ("arm64/cfi,bpf: Support kCFI + BPF on arm64") Reported-by: Sashiko Reported-by: Alexei Starovoitov Signed-off-by: Jose Fernandez (Anthropic) Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261030-b4-arm64-bpf-linfo-cfi-v2-1-4eac83435d4b@linux.dev Closes: https://lore.kernel.org/all/20260904014748.C04AA1F000E9@smtp.kernel.org/ Closes: https://lore.kernel.org/all/DLNXZ2WK7TPD.2RZBUNRS4FA4L@gmail.com/ --- arch/s390/net/bpf_jit_comp.c | 2 -- kernel/bpf/core.c | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 56ec49894dda..83da3a00db7e 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -2428,8 +2428,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr fp->jited_len = jit.size - cfi_get_offset(); if (!fp->is_func || extra_pass) { - for (int i = 0; i < fp->len; i++) - jit.addrs[i] -= cfi_get_offset(); bpf_prog_fill_jited_linfo(fp, jit.addrs + 1); free_addrs: kvfree(jit.addrs); diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 7cf37690d41f..b9709e3b7656 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -206,7 +206,9 @@ void bpf_prog_jit_attempt_done(struct bpf_prog *prog) * here is relative to the prog itself instead of the main prog. * This array has one entry for each xlated bpf insn. * - * jited_off is the byte off to the end of the jited insn. + * jited_off is the byte off to the end of the jited insn, counted from + * the start of the jited image, which is cfi_get_offset() bytes before + * prog->bpf_func. * * Hence, with * insn_start: @@ -220,7 +222,7 @@ void bpf_prog_jit_attempt_done(struct bpf_prog *prog) * * For i > linfo_idx, * - * jited_linfo[i] = prog->bpf_func + + * jited_linfo[i] = prog->bpf_func - cfi_get_offset() + * insn_to_jit_off[linfo[i].insn_off - insn_start - 1] */ void bpf_prog_fill_jited_linfo(struct bpf_prog *prog, @@ -248,7 +250,7 @@ void bpf_prog_fill_jited_linfo(struct bpf_prog *prog, /* The verifier ensures that linfo[i].insn_off is * strictly increasing */ - jited_linfo[i] = prog->bpf_func + + jited_linfo[i] = prog->bpf_func - cfi_get_offset() + insn_to_jit_off[linfo[i].insn_off - insn_start - 1]; }