BPF List
 help / color / mirror / Atom feed
* [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