[PATCH bpf v2] bpf: Fix jited line info off by the CFI preamble
From: Jose Fernandez (Anthropic)
Date: Fri Oct 30 2026 - 14:19:41 EST
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 <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/20260904014748.C04AA1F000E9@xxxxxxxxxxxxxxx/
Reported-by: Alexei Starovoitov <ast@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/DLNXZ2WK7TPD.2RZBUNRS4FA4L@xxxxxxxxx/
Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@xxxxxxxxx>
---
Changes in v2:
- Fix it once in bpf_prog_fill_jited_linfo() instead of in the arm64
JIT, which covers x86-64 and riscv64 too, and drop the s390
correction loop.
- Link to v1: https://lore.kernel.org/r/20260925-b4-arm64-bpf-linfo-cfi-v1-1-e930ab335170@xxxxxxxxx
Stable trees that do not have commit 227b4e108adc ("s390/bpf: Add
kCFI support") take this without the s390 hunk.
Drafted with the help of an AI assistant and reviewed by the sender.
---
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];
}
---
base-commit: fb7bd3a2aad70a76232a7168a505386d0a1396af
change-id: 20260925-b4-arm64-bpf-linfo-cfi-f5c3897e408c
Best regards,
--
Jose Fernandez (Anthropic) <jose.fernandez@xxxxxxxxx>