On Fri, 2026-06-26 at 23:43 +0800, Leon Hwang wrote:
> The interpreter is unable to handle the user BPF_ADDR_SPACE_CAST insn,
> whose '->off' is 1:
> 
> static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)
> {
>       ALU64_MOV_X:
>               switch (OFF) {
>               case 0:
>                       DST = SRC;
>                       break;
>               case 8:
>                       DST = (s8) SRC;
>                       break;
>               case 16:
>                       DST = (s16) SRC;
>                       break;
>               case 32:
>                       DST = (s32) SRC;
>                       break;
>               }
>               CONT;
> }
> 
> On the fallback path from JIT in __bpf_prog_select_runtime(), reject
> the insn to avoid being ignored by interpreter.
> 
> Fixes: 142fd4d2dcf5 ("bpf: Add x86-64 JIT support for bpf_addr_space_cast 
> instruction.")
> Signed-off-by: Leon Hwang <[email protected]>
> ---
>  kernel/bpf/core.c | 29 +++++++++++++++++++++++------
>  1 file changed, 23 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 0db6e55bad52..e92eb8b7f945 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2608,23 +2608,37 @@ static struct bpf_prog *bpf_prog_jit_compile(struct 
> bpf_verifier_env *env,
> struc
>       return prog;
>  }
>  
> +static bool bpf_insn_requires_jit(struct bpf_insn *insn)
> +{
> +     if (insn_is_cast_user(insn))
> +             return true;
> +
> +     return false;
> +}
> +
>  /* Fix up helper call offsets on JIT fallback path. */
> -static void bpf_fixup_fallback_helpers(struct bpf_verifier_env *env, struct 
> bpf_prog *fp)
> +static int bpf_fixup_fallback_helpers(struct bpf_verifier_env *env, struct 
> bpf_prog *fp)
>  {
>       struct bpf_insn *insn = fp->insnsi;
>       const struct bpf_func_proto *fn;
>       int i;
>  
> -     if (!env || !env->ops->get_func_proto)
> -             return;
> +     if (!env)
> +             return 0;
>  
>       for (i = 0; i < fp->len; i++, insn++) {
> -             if (bpf_helper_call(insn) && 
> bpf_jit_inlines_helper_call(insn->imm)) {
> +             if (env->ops->get_func_proto && bpf_helper_call(insn) &&
> +                 bpf_jit_inlines_helper_call(insn->imm)) {
>                       fn = env->ops->get_func_proto(insn->imm, env->prog);
>                       if (fn && fn->func)
>                               insn->imm = fn->func - __bpf_call_base;
It might be better to use the BPF_CALL_IMM macro. insn->imm = 
BPF_CALL_IMM(fn->func);
>               }
> +
> +             if (bpf_insn_requires_jit(insn))
> +                     return -EOPNOTSUPP;
>       }
> +
> +     return 0;
>  }
>  
>  struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, 
> struct bpf_prog *fp,
> @@ -2663,8 +2677,11 @@ struct bpf_prog *__bpf_prog_select_runtime(struct 
> bpf_verifier_env *env,
> struct
>                       return fp;
>               }
>  
> -             if (!fp->jited)
> -                     bpf_fixup_fallback_helpers(env, fp);
> +             if (!fp->jited) {
> +                     *err = bpf_fixup_fallback_helpers(env, fp);
> +                     if (*err)
> +                             return fp;
> +             }
>       } else {
>               *err = bpf_prog_offload_compile(fp);
>               if (*err)

-- 
Thanks,
KaFai

Reply via email to