* [PATCH bpf-next v8 0/2] Introduce jit_required to prevent a kernel panic
@ 2026-07-06 4:00 Tiezhu Yang
2026-07-06 4:00 ` [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() Tiezhu Yang
2026-07-06 4:00 ` [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available Tiezhu Yang
0 siblings, 2 replies; 8+ messages in thread
From: Tiezhu Yang @ 2026-07-06 4:00 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan
Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel
This series introduces a 'jit_required' flag in struct bpf_prog
to track programs that strictly require JIT.
The aim is to prevent a kernel panic by rejecting programs with
inlined helpers when JIT is not available.
v8:
-- Completely remove bpf_prog_has_kfunc_call().
-- Set jit_required at the entry of bpf_add_kfunc_call().
-- Generalize the error message to:
"program requires BPF JIT compiler but it is not available"
Tiezhu Yang (2):
bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call()
bpf: Reject programs with inlined helpers if JIT is not available
include/linux/bpf.h | 9 ++-------
kernel/bpf/core.c | 3 +--
kernel/bpf/fixups.c | 9 +++++----
kernel/bpf/verifier.c | 7 ++-----
4 files changed, 10 insertions(+), 18 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() 2026-07-06 4:00 [PATCH bpf-next v8 0/2] Introduce jit_required to prevent a kernel panic Tiezhu Yang @ 2026-07-06 4:00 ` Tiezhu Yang 2026-07-06 11:39 ` KaFai Wan 2026-07-06 4:00 ` [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available Tiezhu Yang 1 sibling, 1 reply; 8+ messages in thread From: Tiezhu Yang @ 2026-07-06 4:00 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel Introduce a 'jit_required' bitfield flag in struct bpf_prog. This bit tracks whether a BPF program strictly requires the JIT compiler to run, preventing dangerous runtime fallback to the interpreter for features not implemented there. Set the flag 'jit_required' to 1 at the entry of bpf_add_kfunc_call() right after the kfunc_tab allocation succeeds. This cleanly marks the lifecycle of any program attempting to utilize kernel functions. Furthermore, completely remove the bpf_prog_has_kfunc_call() helper, as its logic is now unified under the 'jit_required' flag. In bpf_fixup_call_args(), check with 'prog->jit_required' rather than bpf_prog_has_kfunc_call(), and generalize the error message to generic BPF JIT availability. In __bpf_prog_select_runtime(), check with 'fp->jit_required' rather than bpf_prog_has_kfunc_call() to unify the logic. Suggested-by: Alexei Starovoitov <ast@kernel.org> Suggested-by: KaFai Wan <kafai.wan@linux.dev> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> --- include/linux/bpf.h | 9 ++------- kernel/bpf/core.c | 3 +-- kernel/bpf/fixups.c | 5 ++--- kernel/bpf/verifier.c | 7 ++----- 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index ba09795e0bfd..0b620bfbbd9b 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1865,8 +1865,9 @@ struct bpf_prog_aux { struct bpf_prog { u16 pages; /* Number of allocated pages */ - u16 jited:1, /* Is our filter JIT'ed? */ + u32 jited:1, /* Is our filter JIT'ed? */ jit_requested:1,/* archs need to JIT the prog */ + jit_required:1, /* program strictly requires JIT compiler */ gpl_compatible:1, /* Is filter GPL compatible? */ cb_access:1, /* Is control block accessed? */ dst_needed:1, /* Do we need dst entry? */ @@ -3170,7 +3171,6 @@ const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog); void bpf_task_storage_free(struct task_struct *task); void bpf_cgrp_storage_free(struct cgroup *cgroup); -bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog); const struct btf_func_model * bpf_jit_find_kfunc_model(const struct bpf_prog *prog, const struct bpf_insn *insn); @@ -3509,11 +3509,6 @@ static inline void bpf_task_storage_free(struct task_struct *task) { } -static inline bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog) -{ - return false; -} - static inline const struct btf_func_model * bpf_jit_find_kfunc_model(const struct bpf_prog *prog, const struct bpf_insn *insn) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 6e19a030da6f..faef1de84fa7 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2675,8 +2675,7 @@ struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, struct if (fp->bpf_func) goto finalize; - if (IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON) || - bpf_prog_has_kfunc_call(fp)) + if (IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON) || fp->jit_required) jit_needed = true; if (!bpf_prog_select_interpreter(fp)) diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c index 12a8a4eb757f..02246df2f6c3 100644 --- a/kernel/bpf/fixups.c +++ b/kernel/bpf/fixups.c @@ -1378,7 +1378,6 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env) #ifndef CONFIG_BPF_JIT_ALWAYS_ON struct bpf_prog *prog = env->prog; struct bpf_insn *insn = prog->insnsi; - bool has_kfunc_call = bpf_prog_has_kfunc_call(prog); int depth; #endif int i, err = 0; @@ -1404,8 +1403,8 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env) return err; } #ifndef CONFIG_BPF_JIT_ALWAYS_ON - if (has_kfunc_call) { - verbose(env, "calling kernel functions are not allowed in non-JITed programs\n"); + if (prog->jit_required) { + verbose(env, "program requires BPF JIT compiler but it is not available\n"); return -EINVAL; } for (i = 0; i < env->subprog_cnt; i++) { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index d46f7db20d8f..e188d55e8116 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2714,6 +2714,8 @@ int bpf_add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, u16 offset) prog_aux->kfunc_tab = tab; } + env->prog->jit_required = 1; + /* func_id == 0 is always invalid, but instead of returning an error, be * conservative and wait until the code elimination pass before returning * error, so that invalid calls that get pruned out can be in BPF programs @@ -2768,11 +2770,6 @@ int bpf_add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, u16 offset) return 0; } -bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog) -{ - return !!prog->aux->kfunc_tab; -} - static int add_subprog_and_kfunc(struct bpf_verifier_env *env) { struct bpf_subprog_info *subprog = env->subprog_info; -- 2.42.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() 2026-07-06 4:00 ` [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() Tiezhu Yang @ 2026-07-06 11:39 ` KaFai Wan 2026-07-07 1:43 ` Tiezhu Yang 0 siblings, 1 reply; 8+ messages in thread From: KaFai Wan @ 2026-07-06 11:39 UTC (permalink / raw) To: Tiezhu Yang, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel On Mon, 2026-07-06 at 12:00 +0800, Tiezhu Yang wrote: > Introduce a 'jit_required' bitfield flag in struct bpf_prog. This bit > tracks whether a BPF program strictly requires the JIT compiler to run, > preventing dangerous runtime fallback to the interpreter for features > not implemented there. > > Set the flag 'jit_required' to 1 at the entry of bpf_add_kfunc_call() > right after the kfunc_tab allocation succeeds. This cleanly marks the > lifecycle of any program attempting to utilize kernel functions. > > Furthermore, completely remove the bpf_prog_has_kfunc_call() helper, > as its logic is now unified under the 'jit_required' flag. > > In bpf_fixup_call_args(), check with 'prog->jit_required' rather than > bpf_prog_has_kfunc_call(), and generalize the error message to generic > BPF JIT availability. > > In __bpf_prog_select_runtime(), check with 'fp->jit_required' rather > than bpf_prog_has_kfunc_call() to unify the logic. > If you have a new version, I think we could simplify the description of the code details a bit. The code is fine by me, others might have comments. > Suggested-by: Alexei Starovoitov <ast@kernel.org> > Suggested-by: KaFai Wan <kafai.wan@linux.dev> > Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> > --- -- Thanks, KaFai ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() 2026-07-06 11:39 ` KaFai Wan @ 2026-07-07 1:43 ` Tiezhu Yang 0 siblings, 0 replies; 8+ messages in thread From: Tiezhu Yang @ 2026-07-07 1:43 UTC (permalink / raw) To: KaFai Wan, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel On 2026/7/6 下午7:39, KaFai Wan wrote: > On Mon, 2026-07-06 at 12:00 +0800, Tiezhu Yang wrote: >> Introduce a 'jit_required' bitfield flag in struct bpf_prog. This bit >> tracks whether a BPF program strictly requires the JIT compiler to run, >> preventing dangerous runtime fallback to the interpreter for features >> not implemented there. >> >> Set the flag 'jit_required' to 1 at the entry of bpf_add_kfunc_call() >> right after the kfunc_tab allocation succeeds. This cleanly marks the >> lifecycle of any program attempting to utilize kernel functions. >> >> Furthermore, completely remove the bpf_prog_has_kfunc_call() helper, >> as its logic is now unified under the 'jit_required' flag. >> >> In bpf_fixup_call_args(), check with 'prog->jit_required' rather than >> bpf_prog_has_kfunc_call(), and generalize the error message to generic >> BPF JIT availability. >> >> In __bpf_prog_select_runtime(), check with 'fp->jit_required' rather >> than bpf_prog_has_kfunc_call() to unify the logic. >> > > If you have a new version, I think we could simplify the description of the code details a bit. OK, will do it in v9. > The code is fine by me, others might have comments. As suggested by Leon and you, I will modify the code to: "fp->jit_required = IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON)" in v9. Thanks, Tiezhu ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available 2026-07-06 4:00 [PATCH bpf-next v8 0/2] Introduce jit_required to prevent a kernel panic Tiezhu Yang 2026-07-06 4:00 ` [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() Tiezhu Yang @ 2026-07-06 4:00 ` Tiezhu Yang 2026-07-06 21:41 ` Eduard Zingerman 1 sibling, 1 reply; 8+ messages in thread From: Tiezhu Yang @ 2026-07-06 4:00 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel When an architecture (such as LoongArch, ARM64, and RISC-V) implements bpf_jit_inlines_helper_call(), the verifier skips rewriting the helper call offset (insn->imm) during the bpf_do_misc_fixups() phase, because the helper is expected to be inlined by the JIT compiler. As a result, insn->imm remains as the raw helper enum ID. However, if JIT is disabled at runtime (net.core.bpf_jit_enable=0) or if the JIT compilation later dynamically fails (e.g., due to OOM), the core BPF subsystem falls back to the BPF interpreter. When the interpreter executes (__bpf_call_base + insn->imm) with the unpatched raw helper ID, it jumps into an unaligned invalid address space, triggering an instruction alignment fault or a memory access panic. Fix this by setting 'jit_required' to 1 when helper call rewriting is skipped for JIT inlining. Loading will be rejected early with -EINVAL if JIT is disabled, or safely rejected with -ENOTSUPP during runtime selection if JIT compilation dynamically fails, effectively preventing the kernel panic. Fixes: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") Suggested-by: Alexei Starovoitov <ast@kernel.org> Suggested-by: KaFai Wan <kafai.wan@linux.dev> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> --- kernel/bpf/fixups.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c index 02246df2f6c3..d3be972714b2 100644 --- a/kernel/bpf/fixups.c +++ b/kernel/bpf/fixups.c @@ -1840,8 +1840,10 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env) } /* Skip inlining the helper call if the JIT does it. */ - if (bpf_jit_inlines_helper_call(insn->imm)) + if (bpf_jit_inlines_helper_call(insn->imm)) { + prog->jit_required = 1; goto next_insn; + } if (insn->imm == BPF_FUNC_get_route_realm) prog->dst_needed = 1; -- 2.42.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available 2026-07-06 4:00 ` [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available Tiezhu Yang @ 2026-07-06 21:41 ` Eduard Zingerman 2026-07-07 1:37 ` Tiezhu Yang 2026-07-07 2:03 ` Leon Hwang 0 siblings, 2 replies; 8+ messages in thread From: Eduard Zingerman @ 2026-07-06 21:41 UTC (permalink / raw) To: Tiezhu Yang, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel On Mon, 2026-07-06 at 12:00 +0800, Tiezhu Yang wrote: > When an architecture (such as LoongArch, ARM64, and RISC-V) implements > bpf_jit_inlines_helper_call(), the verifier skips rewriting the helper > call offset (insn->imm) during the bpf_do_misc_fixups() phase, because > the helper is expected to be inlined by the JIT compiler. As a result, > insn->imm remains as the raw helper enum ID. > > However, if JIT is disabled at runtime (net.core.bpf_jit_enable=0) or > if the JIT compilation later dynamically fails (e.g., due to OOM), the > core BPF subsystem falls back to the BPF interpreter. > > When the interpreter executes (__bpf_call_base + insn->imm) with the > unpatched raw helper ID, it jumps into an unaligned invalid address > space, triggering an instruction alignment fault or a memory access > panic. > > Fix this by setting 'jit_required' to 1 when helper call rewriting is > skipped for JIT inlining. Loading will be rejected early with -EINVAL > if JIT is disabled, or safely rejected with -ENOTSUPP during runtime > selection if JIT compilation dynamically fails, effectively preventing > the kernel panic. > > Fixes: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") > Suggested-by: Alexei Starovoitov <ast@kernel.org> > Suggested-by: KaFai Wan <kafai.wan@linux.dev> > Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> > --- Sorry, I'm late to the party. As far as I understand, the patch #1 doesn't really change anything functionally, it just adds the flag, right? As for the patch #2 and looking at the helpers that jits currently inline: - bpf_get_smp_processor_id (implemented as a function in the helpers.c) - bpf_get_current_task (implemented as a function in the bpf_trace.c) - bpf_get_current_task_btf (implemented as a function in the bpf_trace.c) It is perfectly fine to call these as helper functions even if jit is not available. But this was broken since: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") from May 2024, so I guess nobody really cares? Imo, the simplest and least intrusive fix is to add a wrapper in the verifier.c that would call both bpf_jit_inlines_helper_call() and check if the jit is enabled and use that wrapper instead of direct calls to bpf_jit_inlines_helper_call(). Anyway, since this was broken all-along, might as well land as-is. Thoughts? [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available 2026-07-06 21:41 ` Eduard Zingerman @ 2026-07-07 1:37 ` Tiezhu Yang 2026-07-07 2:03 ` Leon Hwang 1 sibling, 0 replies; 8+ messages in thread From: Tiezhu Yang @ 2026-07-07 1:37 UTC (permalink / raw) To: Eduard Zingerman, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan Cc: bpf, loongarch, Leon Hwang, Puranjay Mohan, Björn Töpel On 2026/7/7 上午5:41, Eduard Zingerman wrote: > On Mon, 2026-07-06 at 12:00 +0800, Tiezhu Yang wrote: >> When an architecture (such as LoongArch, ARM64, and RISC-V) implements >> bpf_jit_inlines_helper_call(), the verifier skips rewriting the helper >> call offset (insn->imm) during the bpf_do_misc_fixups() phase, because >> the helper is expected to be inlined by the JIT compiler. As a result, >> insn->imm remains as the raw helper enum ID. >> >> However, if JIT is disabled at runtime (net.core.bpf_jit_enable=0) or >> if the JIT compilation later dynamically fails (e.g., due to OOM), the >> core BPF subsystem falls back to the BPF interpreter. >> >> When the interpreter executes (__bpf_call_base + insn->imm) with the >> unpatched raw helper ID, it jumps into an unaligned invalid address >> space, triggering an instruction alignment fault or a memory access >> panic. >> >> Fix this by setting 'jit_required' to 1 when helper call rewriting is >> skipped for JIT inlining. Loading will be rejected early with -EINVAL >> if JIT is disabled, or safely rejected with -ENOTSUPP during runtime >> selection if JIT compilation dynamically fails, effectively preventing >> the kernel panic. >> >> Fixes: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") >> Suggested-by: Alexei Starovoitov <ast@kernel.org> >> Suggested-by: KaFai Wan <kafai.wan@linux.dev> >> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> >> --- > > Sorry, I'm late to the party. > As far as I understand, the patch #1 doesn't really change anything functionally, > it just adds the flag, right? > > As for the patch #2 and looking at the helpers that jits currently inline: > - bpf_get_smp_processor_id (implemented as a function in the helpers.c) > - bpf_get_current_task (implemented as a function in the bpf_trace.c) > - bpf_get_current_task_btf (implemented as a function in the bpf_trace.c) > > It is perfectly fine to call these as helper functions even if jit is > not available. But this was broken since: > 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") > from May 2024, so I guess nobody really cares? > > Imo, the simplest and least intrusive fix is to add a wrapper in the > verifier.c that would call both bpf_jit_inlines_helper_call() and > check if the jit is enabled and use that wrapper instead of direct > calls to bpf_jit_inlines_helper_call(). > > Anyway, since this was broken all-along, might as well land as-is. > Thoughts? In the previous v4 [1], there is a similar way to fix unaligned interpreter panic on JIT fallback path, but it was explicitly rejected by the BPF maintainer Alexei [2]. Furthermore, Alexei said "The interpreter has to be removed completely... sooner or later." [3]. So if JIT is not available, rejecting the program load is the intended design. [1] https://lore.kernel.org/bpf/20260615025316.24429-1-yangtiezhu@loongson.cn/ [2] https://lore.kernel.org/bpf/DJMRIZ5PDWP4.12OOZ8H881H6O@gmail.com/ [3] https://lore.kernel.org/bpf/DJN001X0S57Y.18CKUS4NDDQT1@gmail.com/ Thanks, Tiezhu ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available 2026-07-06 21:41 ` Eduard Zingerman 2026-07-07 1:37 ` Tiezhu Yang @ 2026-07-07 2:03 ` Leon Hwang 1 sibling, 0 replies; 8+ messages in thread From: Leon Hwang @ 2026-07-07 2:03 UTC (permalink / raw) To: Eduard Zingerman, Tiezhu Yang, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, KaFai Wan Cc: bpf, loongarch, Puranjay Mohan, Björn Töpel On 7/7/26 05:41, Eduard Zingerman wrote: > On Mon, 2026-07-06 at 12:00 +0800, Tiezhu Yang wrote: >> When an architecture (such as LoongArch, ARM64, and RISC-V) implements >> bpf_jit_inlines_helper_call(), the verifier skips rewriting the helper >> call offset (insn->imm) during the bpf_do_misc_fixups() phase, because >> the helper is expected to be inlined by the JIT compiler. As a result, >> insn->imm remains as the raw helper enum ID. >> >> However, if JIT is disabled at runtime (net.core.bpf_jit_enable=0) or >> if the JIT compilation later dynamically fails (e.g., due to OOM), the >> core BPF subsystem falls back to the BPF interpreter. >> >> When the interpreter executes (__bpf_call_base + insn->imm) with the >> unpatched raw helper ID, it jumps into an unaligned invalid address >> space, triggering an instruction alignment fault or a memory access >> panic. >> >> Fix this by setting 'jit_required' to 1 when helper call rewriting is >> skipped for JIT inlining. Loading will be rejected early with -EINVAL >> if JIT is disabled, or safely rejected with -ENOTSUPP during runtime >> selection if JIT compilation dynamically fails, effectively preventing >> the kernel panic. >> >> Fixes: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") >> Suggested-by: Alexei Starovoitov <ast@kernel.org> >> Suggested-by: KaFai Wan <kafai.wan@linux.dev> >> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> >> --- > > Sorry, I'm late to the party. > As far as I understand, the patch #1 doesn't really change anything functionally, > it just adds the flag, right? > > As for the patch #2 and looking at the helpers that jits currently inline: > - bpf_get_smp_processor_id (implemented as a function in the helpers.c) > - bpf_get_current_task (implemented as a function in the bpf_trace.c) > - bpf_get_current_task_btf (implemented as a function in the bpf_trace.c) > > It is perfectly fine to call these as helper functions even if jit is > not available. But this was broken since: > 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()") > from May 2024, so I guess nobody really cares? Vincent Thiberville reported an interpreter fallback issue for the internal BPF_ADDR_PERCPU insn [1]. And, I was trying to fix assorted interpreter fallback issues [2]. I think it is worth fixing the interpreter fallback issue for the JIT inlineable helper. [1] https://lore.kernel.org/bpf/MR1P264MB331494502C9D13D8A9EAFB99B7E82@MR1P264MB3314.FRAP264.PROD.OUTLOOK.COM/ [2] https://lore.kernel.org/bpf/20260626154330.33619-1-leon.hwang@linux.dev/ Thanks, Leon > > Imo, the simplest and least intrusive fix is to add a wrapper in the > verifier.c that would call both bpf_jit_inlines_helper_call() and > check if the jit is enabled and use that wrapper instead of direct > calls to bpf_jit_inlines_helper_call(). > > Anyway, since this was broken all-along, might as well land as-is. > Thoughts? > > [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-07 2:03 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-06 4:00 [PATCH bpf-next v8 0/2] Introduce jit_required to prevent a kernel panic Tiezhu Yang 2026-07-06 4:00 ` [PATCH bpf-next v8 1/2] bpf: Introduce jit_required flag and remove bpf_prog_has_kfunc_call() Tiezhu Yang 2026-07-06 11:39 ` KaFai Wan 2026-07-07 1:43 ` Tiezhu Yang 2026-07-06 4:00 ` [PATCH bpf-next v8 2/2] bpf: Reject programs with inlined helpers if JIT is not available Tiezhu Yang 2026-07-06 21:41 ` Eduard Zingerman 2026-07-07 1:37 ` Tiezhu Yang 2026-07-07 2:03 ` Leon Hwang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox