Re: [PATCH bpf-next v10 1/5] bpf: Move constants blinding out of arch-specific JITs
From: Xu Kuohai
Date: Wed Mar 25 2026 - 03:49:31 EST
On 3/24/2026 8:46 PM, bot+bpf-ci@xxxxxxxxxx wrote:
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 67eb12b637a5..8f52f4b6c3af 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
[ ... ]
@@ -1507,13 +1507,16 @@ static void adjust_insn_arrays(struct bpf_prog *prog, u32 off, u32 len)
#endif
}
-struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
+struct bpf_prog *bpf_jit_blind_constants(struct bpf_verifier_env *env, struct bpf_prog *prog)
{
[ ... ]
- tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten);
- if (IS_ERR(tmp)) {
+ if (env)
+ tmp = bpf_patch_insn_data(env, subprog_start + i, insn_buff, rewritten);
+ else
+ tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten);
When env is non-NULL, bpf_patch_insn_data() adjusts env->insn_aux_data
via adjust_insn_aux_data() and env->subprog_info via
adjust_subprog_starts(). This shifts subprogram start positions to
account for the expanded instructions.
Right, but only the subsequent subprogs are shifted, the current subprog
is not. Since we are patching the main prog when env is non-NULL, and
subprog_start is always 0 for a main prog, subprog_start is not needed
here and can be removed.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index cd008b146ee5..1b2b99f2d859 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
[ ... ]
}
bpf_prog_jit_attempt_done(prog);
return err;
When blinded is true, the rollback restores env->prog to orig_prog, but
env->subprog_info still holds the shifted start positions from blinding
(adjusted by adjust_subprog_starts() in bpf_patch_insn_data()). The
commit message states "env->insn_aux_data and env->subprog_info are no
longer used after JIT failure." However, on configurations without
CONFIG_BPF_JIT_ALWAYS_ON, fixup_call_args() falls through to the
interpreter fixup loop after jit_subprogs() fails:
fixup_call_args() {
err = jit_subprogs(env); /* fails, e.g. -ENOTSUPP */
...
for (i = 0; i < prog->len; ...) {
...
depth = get_callee_stack_depth(env, insn, i);
}
}
get_callee_stack_depth() computes a target address from orig_prog's
original instruction offsets and calls find_subprog(env, start). Since
env->subprog_info start positions were shifted by blinding but the
instruction addresses are from the unblinded orig_prog, find_subprog()
fails to find a matching entry and returns -ENOENT, triggering a
spurious "verifier bug" warning and rejecting the program.
Could env->subprog_info be restored alongside the prog rollback, or
could jit_subprogs() return -EFAULT when blinding was active to skip
the interpreter fallback path?
We can save and restore env->subprog_info. Since only the subprog start
values in the subprog_info array are adjusted by the patching function,
I will just back up the original values and restore them on failure,
without duplicating the full subprog_info array.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23488858455