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