* [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup
@ 2026-06-05 18:35 Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call Amery Hung
` (4 more replies)
0 siblings, 5 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
Hi,
The main patchset refactoring object relationship tracking in the
verifier has landed and this is a followup that addresses the remaining
feedback in v6 [0].
[0]
https://lore.kernel.org/bpf/20260529014936.2811085-1-ameryhung@gmail.com/
Amery Hung (5):
bpf: Fix dead error check on acquire_reference() in check_kfunc_call
bpf: Check acquire_reference() error for "__ref" struct_ops arguments
bpf: Compare parent_id in refsafe() for REF_TYPE_PTR
bpf: Remove WARN_ON_ONCE in check_ids()
selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test
kernel/bpf/states.c | 11 +++++++++--
kernel/bpf/verifier.c | 15 +++++++++++----
.../selftests/bpf/progs/file_reader_fail.c | 8 ++++----
3 files changed, 24 insertions(+), 10 deletions(-)
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
@ 2026-06-05 18:35 ` Amery Hung
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 18:35 ` [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments Amery Hung
` (3 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
acquire_reference() returns a signed int that may be a negative errno
but was converted to unsigned, which makes the subsequent error check
deadcode. Fix it by declaring 'id' as int so the error path is taken
correctly.
Fixes: 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
kernel/bpf/verifier.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8ed484cb1a8a..6446db9628ae 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12817,9 +12817,10 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
struct bpf_kfunc_call_arg_meta meta;
struct bpf_insn_aux_data *insn_aux;
int err, insn_idx = *insn_idx_p;
- u32 i, nargs, ptr_type_id, id;
const struct btf_param *args;
+ u32 i, nargs, ptr_type_id;
struct btf *desc_btf;
+ int id;
/* skip for now, but return error when we find this in fixup_kfunc_call */
if (!insn->imm)
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call Amery Hung
@ 2026-06-05 18:35 ` Amery Hung
2026-06-05 18:46 ` sashiko-bot
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 18:35 ` [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR Amery Hung
` (2 subsequent siblings)
4 siblings, 2 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
When acquiring references for struct_ops program arguments tagged with
"__ref", the return value of acquire_reference() was stored directly
into u32 ctx_arg_info[i].ref_id without checking for failure.
acquire_reference() returns -ENOMEM when acquire_reference_state() fails
to allocate, so the error was silently stored as a ref_id instead of
aborting verification. Fix it by checking the return.
Fixes: a687df2008f6 ("bpf: Support getting referenced kptr from struct_ops argument")
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
kernel/bpf/verifier.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6446db9628ae..2a18b8aba14d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -18362,9 +18362,15 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
/* Acquire references for struct_ops program arguments tagged with "__ref" */
if (!subprog && env->prog->type == BPF_PROG_TYPE_STRUCT_OPS) {
- for (i = 0; i < aux->ctx_arg_info_size; i++)
- aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
- acquire_reference(env, 0, 0) : 0;
+ for (i = 0; i < aux->ctx_arg_info_size; i++) {
+ int id;
+
+ id = aux->ctx_arg_info[i].refcounted ? acquire_reference(env, 0, 0) : 0;
+ if (id < 0)
+ return id;
+
+ aux->ctx_arg_info[i].ref_id = id;
+ }
}
ret = do_check(env);
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments Amery Hung
@ 2026-06-05 18:35 ` Amery Hung
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 18:35 ` [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids() Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test Amery Hung
4 siblings, 1 reply; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
refsafe() compared each reference's id and type but not its parent_id,
so two states whose PTR references differ only in the parent object they
were derived from could be wrongly treated as equivalent and pruned. Fix
it by checking parent_id too.
Fixes: 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
kernel/bpf/states.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c
index 5945956a7573..06d9ae24f006 100644
--- a/kernel/bpf/states.c
+++ b/kernel/bpf/states.c
@@ -890,6 +890,9 @@ static bool refsafe(struct bpf_verifier_state *old, struct bpf_verifier_state *c
return false;
switch (old->refs[i].type) {
case REF_TYPE_PTR:
+ if (!check_ids(old->refs[i].parent_id, cur->refs[i].parent_id, idmap))
+ return false;
+ break;
case REF_TYPE_IRQ:
break;
case REF_TYPE_LOCK:
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids()
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
` (2 preceding siblings ...)
2026-06-05 18:35 ` [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR Amery Hung
@ 2026-06-05 18:35 ` Amery Hung
2026-06-05 19:08 ` bot+bpf-ci
2026-06-05 18:35 ` [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test Amery Hung
4 siblings, 1 reply; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
check_ids() warned when it ran out of idmap slots, assuming this was
impossible because the slots are bounded by the number of registers and
stack slots. That assumption no longer holds: referenced dynptrs acquire
an intermediate reference that lives in refs[] but is not backed by any
register or stack slot [0], so a program can accumulate more reference
ids than the idmap can hold and exhaust it.
Exhaustion is fine for verification correctness. check_ids() already
returns false, which makes the states compare as not equivalent and
prevents unsound pruning. The only effect of the WARN_ON_ONCE() is log
noise, or a panic under panic_on_warn. Drop the warning and keep
returning false.
[0] 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
kernel/bpf/states.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c
index 06d9ae24f006..32f346ce3ffc 100644
--- a/kernel/bpf/states.c
+++ b/kernel/bpf/states.c
@@ -343,8 +343,12 @@ static bool check_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
return true;
}
- /* We ran out of idmap slots, which should be impossible */
- WARN_ON_ONCE(1);
+ /*
+ * idmap slots are bounded by the number of registers and stack slots.
+ * Since referenced dynptrs acquire intermediate references that do
+ * not live in either, so the map can be exhausted. Since it is unlikely,
+ * fail the verification by treating the states as not equivalent.
+ */
return false;
}
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
` (3 preceding siblings ...)
2026-06-05 18:35 ` [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids() Amery Hung
@ 2026-06-05 18:35 ` Amery Hung
2026-06-05 19:08 ` bot+bpf-ci
4 siblings, 1 reply; 16+ messages in thread
From: Amery Hung @ 2026-06-05 18:35 UTC (permalink / raw)
To: bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team
use_file_dynptr_slice_after_put_file() reads the dynptr via
bpf_dynptr_data(), which always returns NULL for a read-only file
dynptr, making the example confusing. Switch to bpf_dynptr_slice(), the
correct read API for file dynptrs, and read (rather than write) the slice
since it is read-only. The test still fails as expected.
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
tools/testing/selftests/bpf/progs/file_reader_fail.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/file_reader_fail.c b/tools/testing/selftests/bpf/progs/file_reader_fail.c
index d5fae5e4cf9a..3bb9e2612f8f 100644
--- a/tools/testing/selftests/bpf/progs/file_reader_fail.c
+++ b/tools/testing/selftests/bpf/progs/file_reader_fail.c
@@ -87,7 +87,8 @@ int use_file_dynptr_slice_after_put_file(void *ctx)
struct task_struct *task = bpf_get_current_task_btf();
struct file *file = bpf_get_task_exe_file(task);
struct bpf_dynptr dynptr;
- char *data;
+ char buf[1];
+ const char *data;
if (!file)
return 0;
@@ -95,15 +96,14 @@ int use_file_dynptr_slice_after_put_file(void *ctx)
if (bpf_dynptr_from_file(file, 0, &dynptr))
goto out;
- data = bpf_dynptr_data(&dynptr, 0, 1);
+ data = bpf_dynptr_slice(&dynptr, 0, buf, sizeof(buf));
if (!data)
goto out;
/* this should fail - file dynptr should be discarded first to prevent resource leak */
bpf_put_file(file);
- *data = 'x';
- return 0;
+ return data[0];
out:
bpf_dynptr_file_discard(&dynptr);
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments
2026-06-05 18:35 ` [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments Amery Hung
@ 2026-06-05 18:46 ` sashiko-bot
2026-06-05 19:27 ` bot+bpf-ci
1 sibling, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-06-05 18:46 UTC (permalink / raw)
To: Amery Hung; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Direct return on `acquire_reference()` failure in `do_check_common()` bypasses cleanup and leaks `env->cur_state`.
--
commit 255de8a669b1a40ba719e137d38c8f3f04ff00ca
Author: Amery Hung <ameryhung@gmail.com>
bpf: Check acquire_reference() error for "__ref" struct_ops arguments
This commit adds an error check for acquire_reference() when handling
struct_ops program arguments tagged with "__ref". It stores the error
return value and aborts verification if acquire_reference_state() fails to
allocate memory.
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a741bf4479318..5a69af5690891 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -18363,9 +18363,15 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
>
> /* Acquire references for struct_ops program arguments tagged with "__ref" */
> if (!subprog && env->prog->type == BPF_PROG_TYPE_STRUCT_OPS) {
> - for (i = 0; i < aux->ctx_arg_info_size; i++)
> - aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
> - acquire_reference(env, 0, 0) : 0;
> + for (i = 0; i < aux->ctx_arg_info_size; i++) {
> + int id;
> +
> + id = aux->ctx_arg_info[i].refcounted ? acquire_reference(env, 0, 0) : 0;
> + if (id < 0)
> + return id;
[Severity: High]
Does this direct return bypass the cleanup path and leak env->cur_state?
Earlier in do_check_common(), env->cur_state is allocated via kzalloc_obj().
Other error paths in this function set the return variable and jump to the
out label to call free_states(env) for proper cleanup.
Should this be updated to set ret = id and goto out instead of returning
directly?
> +
> + aux->ctx_arg_info[i].ref_id = id;
> + }
> }
>
> ret = do_check(env);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260605183551.969144-1-ameryhung@gmail.com?part=2
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test
2026-06-05 18:35 ` [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test Amery Hung
@ 2026-06-05 19:08 ` bot+bpf-ci
0 siblings, 0 replies; 16+ messages in thread
From: bot+bpf-ci @ 2026-06-05 19:08 UTC (permalink / raw)
To: ameryhung, bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1786 bytes --]
> diff --git a/tools/testing/selftests/bpf/progs/file_reader_fail.c b/tools/testing/selftests/bpf/progs/file_reader_fail.c
> index d5fae5e4cf9a..3bb9e2612f8f 100644
> --- a/tools/testing/selftests/bpf/progs/file_reader_fail.c
> +++ b/tools/testing/selftests/bpf/progs/file_reader_fail.c
> @@ -87,7 +87,8 @@ int use_file_dynptr_slice_after_put_file(void *ctx)
> struct task_struct *task = bpf_get_current_task_btf();
> struct file *file = bpf_get_task_exe_file(task);
> struct bpf_dynptr dynptr;
> - char *data;
> + char buf[1];
> + const char *data;
>
> if (!file)
> return 0;
> @@ -95,15 +96,14 @@ int use_file_dynptr_slice_after_put_file(void *ctx)
> if (bpf_dynptr_from_file(file, 0, &dynptr))
> goto out;
>
> - data = bpf_dynptr_data(&dynptr, 0, 1);
> + data = bpf_dynptr_slice(&dynptr, 0, buf, sizeof(buf));
A note from the earlier review on v1: an automated review bot suggested
initializing the stack buffer here, e.g.
char buf[1] = {0};
worrying that the uninitialized 'buf' passed to bpf_dynptr_slice() could
make the verifier reject the program early with an invalid stack read,
which would bypass the intended reference-leak check.
This looks like a false positive, since the buf argument to
bpf_dynptr_slice() is a destination the helper writes into, so
uninitialized stack memory should be valid there, and the v1 patch
already carried an Acked-by from Eduard Zingerman.
Was this comment considered, and is the test still failing for the
intended reference-leak reason rather than an early verifier rejection?
---
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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids()
2026-06-05 18:35 ` [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids() Amery Hung
@ 2026-06-05 19:08 ` bot+bpf-ci
2026-06-05 20:01 ` Amery Hung
0 siblings, 1 reply; 16+ messages in thread
From: bot+bpf-ci @ 2026-06-05 19:08 UTC (permalink / raw)
To: ameryhung, bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1621 bytes --]
> bpf: Remove WARN_ON_ONCE in check_ids()
>
> check_ids() warned when it ran out of idmap slots, assuming this was
> impossible because the slots are bounded by the number of registers and
> stack slots. That assumption no longer holds: referenced dynptrs acquire
> an intermediate reference that lives in refs[] but is not backed by any
> register or stack slot [0], so a program can accumulate more reference
> ids than the idmap can hold and exhaust it.
>
> Exhaustion is fine for verification correctness. check_ids() already
> returns false, which makes the states compare as not equivalent and
> prevents unsound pruning. The only effect of the WARN_ON_ONCE() is log
> noise, or a panic under panic_on_warn. Drop the warning and keep
> returning false.
>
> [0] 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
>
> Signed-off-by: Amery Hung <ameryhung@gmail.com>
This removes a WARN_ON_ONCE() that can panic under panic_on_warn, and
the commit body explains the idmap exhaustion only became reachable once
referenced dynptrs began acquiring an intermediate reference in refs[]
that is not backed by a register or stack slot.
Should this carry a Fixes: tag pointing at the commit that introduced
that behavior, which the body already cites as [0]?
Fixes: 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
---
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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments
2026-06-05 18:35 ` [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments Amery Hung
2026-06-05 18:46 ` sashiko-bot
@ 2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 19:59 ` Amery Hung
1 sibling, 1 reply; 16+ messages in thread
From: bot+bpf-ci @ 2026-06-05 19:27 UTC (permalink / raw)
To: ameryhung, bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1457 bytes --]
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a741bf447931..5a69af569089 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -18363,9 +18363,15 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
>
> /* Acquire references for struct_ops program arguments tagged with "__ref" */
> if (!subprog && env->prog->type == BPF_PROG_TYPE_STRUCT_OPS) {
> - for (i = 0; i < aux->ctx_arg_info_size; i++)
> - aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
> - acquire_reference(env, 0, 0) : 0;
> + for (i = 0; i < aux->ctx_arg_info_size; i++) {
> + int id;
> +
> + id = aux->ctx_arg_info[i].refcounted ? acquire_reference(env, 0, 0) : 0;
> + if (id < 0)
> + return id;
Does this direct return bypass the cleanup path and leak env->cur_state?
Earlier in do_check_common(), env->cur_state is allocated via kzalloc_obj().
Other error paths in this function set the return variable and jump to the
out label to call free_states(env) for proper cleanup.
Should this be updated to set ret = id and goto out instead of returning
directly?
> +
> + aux->ctx_arg_info[i].ref_id = id;
> + }
> }
>
> ret = do_check(env);
---
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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR
2026-06-05 18:35 ` [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR Amery Hung
@ 2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 20:00 ` Amery Hung
0 siblings, 1 reply; 16+ messages in thread
From: bot+bpf-ci @ 2026-06-05 19:27 UTC (permalink / raw)
To: ameryhung, bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2030 bytes --]
> diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c
> index 5945956a7573..06d9ae24f006 100644
> --- a/kernel/bpf/states.c
> +++ b/kernel/bpf/states.c
> @@ -890,6 +890,9 @@ static bool refsafe(struct bpf_verifier_state *old, struct bpf_verifier_state *c
> return false;
> switch (old->refs[i].type) {
> case REF_TYPE_PTR:
> + if (!check_ids(old->refs[i].parent_id, cur->refs[i].parent_id, idmap))
> + return false;
> + break;
> case REF_TYPE_IRQ:
> break;
> case REF_TYPE_LOCK:
This change now feeds parent_id values through check_ids() in addition to
register and stack slot ids.
In the v1 discussion, Eduard Zingerman noted that since not all ids
correspond to register or stack slots anymore, the WARN_ON_ONCE(1) in
check_ids() on idmap exhaustion should be removed:
kernel/bpf/states.c:check_ids() {
...
/* Reached the end of known mappings; haven't seen this id before */
if (idmap->cnt < BPF_ID_MAP_SIZE) {
map[idmap->cnt].old = old_id;
map[idmap->cnt].cur = cur_id;
idmap->cnt++;
return true;
}
/* We ran out of idmap slots, which should be impossible */
WARN_ON_ONCE(1);
return false;
}
The concern raised by the CI and Sashiko bots was that a BPF program
leaking many references could exhaust BPF_ID_MAP_SIZE and trigger this
warning, which under panic_on_warn becomes a denial of service. Returning
false on exhaustion was agreed to be acceptable; only the warning was
questioned.
The reply on the thread acknowledged this ("Ack. I will drop
WARN_ON_ONCE(1)."), but the WARN_ON_ONCE(1) is still present in this commit.
Was the WARN_ON_ONCE(1) removal intended for a separate patch in the
series, or should it be folded in here?
Reference:
https://lore.kernel.org/bpf/6d86c2fae9be63eb110ebd5b3fc19bc4cf1de2dc.camel@gmail.com/
---
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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call
2026-06-05 18:35 ` [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call Amery Hung
@ 2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 19:57 ` Amery Hung
0 siblings, 1 reply; 16+ messages in thread
From: bot+bpf-ci @ 2026-06-05 19:27 UTC (permalink / raw)
To: ameryhung, bpf
Cc: netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, ameryhung, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1771 bytes --]
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 7d27ba396d32..a741bf447931 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -12817,9 +12817,10 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
> struct bpf_kfunc_call_arg_meta meta;
> struct bpf_insn_aux_data *insn_aux;
> int err, insn_idx = *insn_idx_p;
> - u32 i, nargs, ptr_type_id, id;
> const struct btf_param *args;
> + u32 i, nargs, ptr_type_id;
> struct btf *desc_btf;
> + int id;
>
> /* skip for now, but return error when we find this in fixup_kfunc_call */
> if (!insn->imm)
This patch fixes the missing error check in check_kfunc_call(), but
could a similar issue exist in do_check_common() when initializing
struct_ops program arguments?
Looking at do_check_common(), there's a similar pattern where
acquire_reference() is called:
kernel/bpf/verifier.c:do_check_common() {
...
for (i = 0; i < aux->ctx_arg_info_size; i++)
aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
acquire_reference(env, 0, 0) : 0;
...
}
Since acquire_reference() can return a negative error like -ENOMEM,
assigning it directly to aux->ctx_arg_info[i].ref_id (which is a u32)
without checking for errors would swallow the error code.
Does this allow the verifier to successfully accept a BPF program without
tracking the reference, potentially leading to a kernel resource leak when
the reference isn't released at runtime?
---
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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call
2026-06-05 19:27 ` bot+bpf-ci
@ 2026-06-05 19:57 ` Amery Hung
0 siblings, 0 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 19:57 UTC (permalink / raw)
To: bot+bpf-ci
Cc: bpf, netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, kernel-team, ast, yonghong.song,
clm, ihor.solodrai
On Fri, Jun 5, 2026 at 12:27 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index 7d27ba396d32..a741bf447931 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -12817,9 +12817,10 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
> > struct bpf_kfunc_call_arg_meta meta;
> > struct bpf_insn_aux_data *insn_aux;
> > int err, insn_idx = *insn_idx_p;
> > - u32 i, nargs, ptr_type_id, id;
> > const struct btf_param *args;
> > + u32 i, nargs, ptr_type_id;
> > struct btf *desc_btf;
> > + int id;
> >
> > /* skip for now, but return error when we find this in fixup_kfunc_call */
> > if (!insn->imm)
>
> This patch fixes the missing error check in check_kfunc_call(), but
> could a similar issue exist in do_check_common() when initializing
> struct_ops program arguments?
>
> Looking at do_check_common(), there's a similar pattern where
> acquire_reference() is called:
>
> kernel/bpf/verifier.c:do_check_common() {
> ...
> for (i = 0; i < aux->ctx_arg_info_size; i++)
> aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
> acquire_reference(env, 0, 0) : 0;
> ...
> }
>
> Since acquire_reference() can return a negative error like -ENOMEM,
> assigning it directly to aux->ctx_arg_info[i].ref_id (which is a u32)
> without checking for errors would swallow the error code.
>
> Does this allow the verifier to successfully accept a BPF program without
> tracking the reference, potentially leading to a kernel resource leak when
> the reference isn't released at runtime?
This is fixed in the next patch
>
>
> ---
> 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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments
2026-06-05 19:27 ` bot+bpf-ci
@ 2026-06-05 19:59 ` Amery Hung
0 siblings, 0 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 19:59 UTC (permalink / raw)
To: bot+bpf-ci
Cc: bpf, netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, kernel-team, ast, yonghong.song,
clm, ihor.solodrai
On Fri, Jun 5, 2026 at 12:27 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index a741bf447931..5a69af569089 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -18363,9 +18363,15 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
> >
> > /* Acquire references for struct_ops program arguments tagged with "__ref" */
> > if (!subprog && env->prog->type == BPF_PROG_TYPE_STRUCT_OPS) {
> > - for (i = 0; i < aux->ctx_arg_info_size; i++)
> > - aux->ctx_arg_info[i].ref_id = aux->ctx_arg_info[i].refcounted ?
> > - acquire_reference(env, 0, 0) : 0;
> > + for (i = 0; i < aux->ctx_arg_info_size; i++) {
> > + int id;
> > +
> > + id = aux->ctx_arg_info[i].refcounted ? acquire_reference(env, 0, 0) : 0;
> > + if (id < 0)
> > + return id;
>
> Does this direct return bypass the cleanup path and leak env->cur_state?
>
> Earlier in do_check_common(), env->cur_state is allocated via kzalloc_obj().
> Other error paths in this function set the return variable and jump to the
> out label to call free_states(env) for proper cleanup.
>
> Should this be updated to set ret = id and goto out instead of returning
> directly?
>
Yes. Will fix it and resend.
> > +
> > + aux->ctx_arg_info[i].ref_id = id;
> > + }
> > }
> >
> > ret = do_check(env);
>
>
> ---
> 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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR
2026-06-05 19:27 ` bot+bpf-ci
@ 2026-06-05 20:00 ` Amery Hung
0 siblings, 0 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 20:00 UTC (permalink / raw)
To: bot+bpf-ci
Cc: bpf, netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, kernel-team, ast, yonghong.song,
clm, ihor.solodrai
On Fri, Jun 5, 2026 at 12:27 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c
> > index 5945956a7573..06d9ae24f006 100644
> > --- a/kernel/bpf/states.c
> > +++ b/kernel/bpf/states.c
> > @@ -890,6 +890,9 @@ static bool refsafe(struct bpf_verifier_state *old, struct bpf_verifier_state *c
> > return false;
> > switch (old->refs[i].type) {
> > case REF_TYPE_PTR:
> > + if (!check_ids(old->refs[i].parent_id, cur->refs[i].parent_id, idmap))
> > + return false;
> > + break;
> > case REF_TYPE_IRQ:
> > break;
> > case REF_TYPE_LOCK:
>
> This change now feeds parent_id values through check_ids() in addition to
> register and stack slot ids.
>
> In the v1 discussion, Eduard Zingerman noted that since not all ids
> correspond to register or stack slots anymore, the WARN_ON_ONCE(1) in
> check_ids() on idmap exhaustion should be removed:
>
> kernel/bpf/states.c:check_ids() {
> ...
> /* Reached the end of known mappings; haven't seen this id before */
> if (idmap->cnt < BPF_ID_MAP_SIZE) {
> map[idmap->cnt].old = old_id;
> map[idmap->cnt].cur = cur_id;
> idmap->cnt++;
> return true;
> }
>
> /* We ran out of idmap slots, which should be impossible */
> WARN_ON_ONCE(1);
> return false;
> }
>
> The concern raised by the CI and Sashiko bots was that a BPF program
> leaking many references could exhaust BPF_ID_MAP_SIZE and trigger this
> warning, which under panic_on_warn becomes a denial of service. Returning
> false on exhaustion was agreed to be acceptable; only the warning was
> questioned.
>
> The reply on the thread acknowledged this ("Ack. I will drop
> WARN_ON_ONCE(1)."), but the WARN_ON_ONCE(1) is still present in this commit.
>
> Was the WARN_ON_ONCE(1) removal intended for a separate patch in the
> series, or should it be folded in here?
This is dropped in patch 4
>
> Reference:
> https://lore.kernel.org/bpf/6d86c2fae9be63eb110ebd5b3fc19bc4cf1de2dc.camel@gmail.com/
>
>
> ---
> 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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids()
2026-06-05 19:08 ` bot+bpf-ci
@ 2026-06-05 20:01 ` Amery Hung
0 siblings, 0 replies; 16+ messages in thread
From: Amery Hung @ 2026-06-05 20:01 UTC (permalink / raw)
To: bot+bpf-ci
Cc: bpf, netdev, alexei.starovoitov, andrii, daniel, eddyz87, memxor,
martin.lau, mykyta.yatsenko5, kernel-team, ast, yonghong.song,
clm, ihor.solodrai
On Fri, Jun 5, 2026 at 12:08 PM <bot+bpf-ci@kernel.org> wrote:
>
> > bpf: Remove WARN_ON_ONCE in check_ids()
> >
> > check_ids() warned when it ran out of idmap slots, assuming this was
> > impossible because the slots are bounded by the number of registers and
> > stack slots. That assumption no longer holds: referenced dynptrs acquire
> > an intermediate reference that lives in refs[] but is not backed by any
> > register or stack slot [0], so a program can accumulate more reference
> > ids than the idmap can hold and exhaust it.
> >
> > Exhaustion is fine for verification correctness. check_ids() already
> > returns false, which makes the states compare as not equivalent and
> > prevents unsound pruning. The only effect of the WARN_ON_ONCE() is log
> > noise, or a panic under panic_on_warn. Drop the warning and keep
> > returning false.
> >
> > [0] 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
> >
> > Signed-off-by: Amery Hung <ameryhung@gmail.com>
>
> This removes a WARN_ON_ONCE() that can panic under panic_on_warn, and
> the commit body explains the idmap exhaustion only became reachable once
> referenced dynptrs began acquiring an intermediate reference in refs[]
> that is not backed by a register or stack slot.
>
> Should this carry a Fixes: tag pointing at the commit that introduced
> that behavior, which the body already cites as [0]?
I don't think a fix tag is needed, This is just to reduce noise. Not a bug.
>
> Fixes: 308c7a0ae885 ("bpf: Refactor object relationship tracking and fix dynptr UAF bug")
>
> ---
> 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/27034008594
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-06-05 20:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-05 18:35 [PATCH bpf-next v2 0/5] Object relationship tracking refactor followup Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 1/5] bpf: Fix dead error check on acquire_reference() in check_kfunc_call Amery Hung
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 19:57 ` Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 2/5] bpf: Check acquire_reference() error for "__ref" struct_ops arguments Amery Hung
2026-06-05 18:46 ` sashiko-bot
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 19:59 ` Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 3/5] bpf: Compare parent_id in refsafe() for REF_TYPE_PTR Amery Hung
2026-06-05 19:27 ` bot+bpf-ci
2026-06-05 20:00 ` Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 4/5] bpf: Remove WARN_ON_ONCE in check_ids() Amery Hung
2026-06-05 19:08 ` bot+bpf-ci
2026-06-05 20:01 ` Amery Hung
2026-06-05 18:35 ` [PATCH bpf-next v2 5/5] selftests/bpf: Use bpf_dynptr_slice() to read file dynptr in leak test Amery Hung
2026-06-05 19:08 ` bot+bpf-ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox