* [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
* [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 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 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 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
* 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