BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling
@ 2026-07-08  0:44 Eduard Zingerman
  2026-07-08  0:44 ` [PATCH bpf-next 1/2] " Eduard Zingerman
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Eduard Zingerman @ 2026-07-08  0:44 UTC (permalink / raw)
  To: bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87, memxor

Track spills for the following register types precisely:
- PTR_TO_TP_BUFFER
- PTR_TO_INSN
- CONST_PTR_TO_DYNPTR

---
Eduard Zingerman (2):
      bpf: remove artificial limitations on pointer types eligable for spilling
      selftests/bpf: test cases for missing spill types

 kernel/bpf/verifier.c                              | 39 +++++---------------
 tools/testing/selftests/bpf/progs/verifier_gotox.c | 25 +++++++++++++
 .../selftests/bpf/progs/verifier_spill_fill.c      | 42 ++++++++++++++++++++++
 3 files changed, 75 insertions(+), 31 deletions(-)
---
base-commit: 602701718649936eb287bf6c7ecf870ec54c6f71
change-id: 20260707-missing-spillable-types-4cd9350dc3d7

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH bpf-next 1/2] bpf: remove artificial limitations on pointer types eligable for spilling
  2026-07-08  0:44 [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling Eduard Zingerman
@ 2026-07-08  0:44 ` Eduard Zingerman
  2026-07-08  1:31   ` bot+bpf-ci
  2026-07-08  0:44 ` [PATCH bpf-next 2/2] selftests/bpf: test cases for missing spill types Eduard Zingerman
  2026-07-08  1:40 ` [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Eduard Zingerman @ 2026-07-08  0:44 UTC (permalink / raw)
  To: bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87, memxor,
	Andrii Nakryiko

The verifier loses precision when simulating stack spills for the
following register types:
- PTR_TO_TP_BUFFER
- PTR_TO_INSN
- CONST_PTR_TO_DYNPTR

These types are not allow-listed in the is_spillable_regtype(),
because of that check_stack_write_fixed_off() takes the branch
that marks the slots STACK_MISC.

There are no technical reasons for this limititation.
This commit replaces an explicit list of pointer types in
is_spillable_regtype() with explicit list of non-pointer types.
The function is renamed to is_pointer_regtype() for clarity.

Reported-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Suggested-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 kernel/bpf/verifier.c | 39 ++++++++-------------------------------
 1 file changed, 8 insertions(+), 31 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 3193b473762b..51f7965d42e3 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3304,34 +3304,6 @@ static int mark_chain_precision_batch(struct bpf_verifier_env *env,
 	return bpf_mark_chain_precision(env, starting_state, -1, NULL);
 }
 
-static bool is_spillable_regtype(enum bpf_reg_type type)
-{
-	switch (base_type(type)) {
-	case PTR_TO_MAP_VALUE:
-	case PTR_TO_STACK:
-	case PTR_TO_CTX:
-	case PTR_TO_PACKET:
-	case PTR_TO_PACKET_META:
-	case PTR_TO_PACKET_END:
-	case PTR_TO_FLOW_KEYS:
-	case CONST_PTR_TO_MAP:
-	case PTR_TO_SOCKET:
-	case PTR_TO_SOCK_COMMON:
-	case PTR_TO_TCP_SOCK:
-	case PTR_TO_XDP_SOCK:
-	case PTR_TO_BTF_ID:
-	case PTR_TO_BUF:
-	case PTR_TO_MEM:
-	case PTR_TO_FUNC:
-	case PTR_TO_MAP_KEY:
-	case PTR_TO_ARENA:
-		return true;
-	default:
-		return false;
-	}
-}
-
-
 /* check if register is a constant scalar value */
 static bool is_reg_const(struct bpf_reg_state *reg, bool subreg32)
 {
@@ -3345,13 +3317,18 @@ static u64 reg_const_value(struct bpf_reg_state *reg, bool subreg32)
 	return subreg32 ? tnum_subreg(reg->var_off).value : reg->var_off.value;
 }
 
+static bool is_pointer_regtype(enum bpf_reg_type type)
+{
+	return type != SCALAR_VALUE && type != NOT_INIT;
+}
+
 static bool __is_pointer_value(bool allow_ptr_leaks,
 			       const struct bpf_reg_state *reg)
 {
 	if (allow_ptr_leaks)
 		return false;
 
-	return reg->type != SCALAR_VALUE;
+	return is_pointer_regtype(reg->type);
 }
 
 static void clear_scalar_id(struct bpf_reg_state *reg)
@@ -3476,7 +3453,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
 	if (value_regno >= 0)
 		reg = &cur->regs[value_regno];
 	if (!env->bypass_spec_v4) {
-		bool sanitize = reg && is_spillable_regtype(reg->type);
+		bool sanitize = reg && is_pointer_regtype(reg->type);
 
 		for (i = 0; i < size; i++) {
 			u8 type = state->stack[spi].slot_type[(slot - i) %
@@ -3517,7 +3494,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
 		__mark_reg_known(tmp_reg, insn->imm);
 		tmp_reg->type = SCALAR_VALUE;
 		save_register_state(env, state, spi, tmp_reg, size);
-	} else if (reg && is_spillable_regtype(reg->type)) {
+	} else if (reg && is_pointer_regtype(reg->type)) {
 		/* register containing pointer is being spilled into stack */
 		if (size != BPF_REG_SIZE) {
 			verbose_linfo(env, insn_idx, "; ");

-- 
2.55.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH bpf-next 2/2] selftests/bpf: test cases for missing spill types
  2026-07-08  0:44 [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling Eduard Zingerman
  2026-07-08  0:44 ` [PATCH bpf-next 1/2] " Eduard Zingerman
@ 2026-07-08  0:44 ` Eduard Zingerman
  2026-07-08  1:40 ` [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: Eduard Zingerman @ 2026-07-08  0:44 UTC (permalink / raw)
  To: bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87, memxor

A few selftests checking that the verifier represents spills for the
following pointer types w/o losing precision:
- PTR_TO_INSN
- PTR_TO_TP_BUFFER
- CONST_PTR_TO_DYNPTR

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 tools/testing/selftests/bpf/progs/verifier_gotox.c | 25 +++++++++++++
 .../selftests/bpf/progs/verifier_spill_fill.c      | 42 ++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/verifier_gotox.c b/tools/testing/selftests/bpf/progs/verifier_gotox.c
index f88aa4cdb279..5b18c9a27717 100644
--- a/tools/testing/selftests/bpf/progs/verifier_gotox.c
+++ b/tools/testing/selftests/bpf/progs/verifier_gotox.c
@@ -384,6 +384,31 @@ jt0_%=:								\
 	: __clobber_all);
 }
 
+/* check valid spill/fill, ptr to insn */
+SEC("socket")
+__success
+__naked void spill_fill_ptr_to_insn(void)
+{
+	asm volatile (
+	".pushsection .jumptables,\"\",@progbits;"
+	"jt0_%=:"
+	".quad ret0_%= - socket;"
+	".size jt0_%=, 8;"
+	".global jt0_%=;"
+	".popsection;"
+	"r0 = jt0_%= ll;"
+	"r0 = *(u64 *)(r0 + 0);"
+	"*(u64 *)(r10 - 8) = r0;"
+	"r0 = *(u64 *)(r10 - 8);"
+	".8byte %[gotox_r0];"
+	"ret0_%=:"
+	"r0 = 0;"
+	"exit;"
+	:
+	: __imm_insn(gotox_r0, BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, BPF_REG_0, 0, 0, 0))
+	: __clobber_all);
+}
+
 #endif /* __TARGET_ARCH_x86 || __TARGET_ARCH_arm64 || __TARGET_ARCH_powerpc*/
 
 char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
index 72c691333703..8b166c42c4e0 100644
--- a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
+++ b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
@@ -1403,4 +1403,46 @@ __naked void partial_fill_from_cleaned_pointer_spill(void)
 		      ::: __clobber_all);
 }
 
+/* check valid spill/fill, ptr to tp buffer */
+SEC("raw_tracepoint.w")
+__success
+__naked void spill_fill_ptr_to_tp_buffer(void)
+{
+	asm volatile (
+	"r6 = *(u64*)(r1 + 0);"	/* r6 is the writable tracepoint buffer */
+	"*(u64*)(r10 - 8) = r6;"
+	"r7 = *(u64*)(r10 - 8);"
+	"r0 = 0;"
+	"*(u64*)(r7 + 0) = r0;"	/* should be able to write through the buffer */
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+__noinline int spill_fill_dynptr_subprog(struct bpf_dynptr *dptr)
+{
+	long *p;
+
+	asm volatile ("*(u64 *)(r10 - 8) = %[dptr];" /* spill the CONST_PTR_TO_DYNPTR argument */
+		      "%[dptr] = *(u64 *)(r10 - 8);"
+		      : [dptr] "+r"(dptr) :: "memory");
+	p = bpf_dynptr_data(dptr, 0, sizeof(*p));
+	if (!p)
+		return 0;
+	return 0;
+}
+
+static char dptr_mem_buf[16];
+
+/* check valid spill/fill, const ptr to dynptr */
+SEC("socket")
+__success
+int spill_fill_const_ptr_to_dynptr(void)
+{
+	struct bpf_dynptr ptr;
+
+	bpf_dynptr_from_mem(dptr_mem_buf, sizeof(dptr_mem_buf), 0, &ptr);
+	return spill_fill_dynptr_subprog(&ptr);
+}
+
 char _license[] SEC("license") = "GPL";

-- 
2.55.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH bpf-next 1/2] bpf: remove artificial limitations on pointer types eligable for spilling
  2026-07-08  0:44 ` [PATCH bpf-next 1/2] " Eduard Zingerman
@ 2026-07-08  1:31   ` bot+bpf-ci
  2026-07-08  1:39     ` Kumar Kartikeya Dwivedi
  0 siblings, 1 reply; 6+ messages in thread
From: bot+bpf-ci @ 2026-07-08  1:31 UTC (permalink / raw)
  To: eddyz87, bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, eddyz87, memxor,
	andrii.nakryiko, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

> bpf: remove artificial limitations on pointer types eligable for spilling

This isn't a bug, but could "eligable" be "eligible" here?

> There are no technical reasons for this limititation.

And could "limititation" be "limitation"?


---
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/28909712027

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH bpf-next 1/2] bpf: remove artificial limitations on pointer types eligable for spilling
  2026-07-08  1:31   ` bot+bpf-ci
@ 2026-07-08  1:39     ` Kumar Kartikeya Dwivedi
  0 siblings, 0 replies; 6+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-08  1:39 UTC (permalink / raw)
  To: bot+bpf-ci, eddyz87, bpf, ast, andrii
  Cc: daniel, martin.lau, kernel-team, yonghong.song, memxor,
	andrii.nakryiko, martin.lau, clm, ihor.solodrai

On Wed Jul 8, 2026 at 3:31 AM CEST, bot+bpf-ci wrote:
>> bpf: remove artificial limitations on pointer types eligable for spilling
>
> This isn't a bug, but could "eligable" be "eligible" here?
>
>> There are no technical reasons for this limititation.
>
> And could "limititation" be "limitation"?
>

Fixed while applying.

>
> ---
> 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/28909712027


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling
  2026-07-08  0:44 [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling Eduard Zingerman
  2026-07-08  0:44 ` [PATCH bpf-next 1/2] " Eduard Zingerman
  2026-07-08  0:44 ` [PATCH bpf-next 2/2] selftests/bpf: test cases for missing spill types Eduard Zingerman
@ 2026-07-08  1:40 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-07-08  1:40 UTC (permalink / raw)
  To: Eduard Zingerman
  Cc: bpf, ast, andrii, daniel, martin.lau, kernel-team, yonghong.song,
	memxor

Hello:

This series was applied to bpf/bpf-next.git (master)
by Kumar Kartikeya Dwivedi <memxor@gmail.com>:

On Tue,  7 Jul 2026 17:44:27 -0700 you wrote:
> Track spills for the following register types precisely:
> - PTR_TO_TP_BUFFER
> - PTR_TO_INSN
> - CONST_PTR_TO_DYNPTR
> 
> ---
> Eduard Zingerman (2):
>       bpf: remove artificial limitations on pointer types eligable for spilling
>       selftests/bpf: test cases for missing spill types
> 
> [...]

Here is the summary with links:
  - [bpf-next,1/2] bpf: remove artificial limitations on pointer types eligable for spilling
    https://git.kernel.org/bpf/bpf-next/c/1f737e46ca6a
  - [bpf-next,2/2] selftests/bpf: test cases for missing spill types
    https://git.kernel.org/bpf/bpf-next/c/b6d29b9ba9d6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-07-08  1:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08  0:44 [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling Eduard Zingerman
2026-07-08  0:44 ` [PATCH bpf-next 1/2] " Eduard Zingerman
2026-07-08  1:31   ` bot+bpf-ci
2026-07-08  1:39     ` Kumar Kartikeya Dwivedi
2026-07-08  0:44 ` [PATCH bpf-next 2/2] selftests/bpf: test cases for missing spill types Eduard Zingerman
2026-07-08  1:40 ` [PATCH bpf-next 0/2] bpf: remove artificial limitations on pointer types eligable for spilling patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox