* [PATCH bpf-next v2 0/5] Fix unique field logic in BTF
@ 2026-07-19 15:36 Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Fix constraint of certain fields that have to be unique when nested
structs are present, BPF_REFCOUNT which should be marked as unique.
See commit logs for details. While at it, fix improper offset check.
Changelog:
----------
v1 -> v2
v1: https://lore.kernel.org/bpf/20260719142401.2420111-1-memxor@gmail.com
* Add fix for BPF_REFCOUNT not being unique. (Sashiko)
* Roll improper offset warning check into series. (Sashiko)
Kumar Kartikeya Dwivedi (5):
bpf: Fix offset warn check for bpf_res_spin_lock
bpf: Preserve unique-field state across nested structs
bpf: Mark bpf_refcount field as unique
selftests/bpf: Test duplicate unique fields in nested structs
selftests/bpf: Test duplicate bpf_refcount fields
kernel/bpf/btf.c | 30 ++++++------
tools/testing/selftests/bpf/prog_tests/btf.c | 48 ++++++++++++++++++++
2 files changed, 64 insertions(+), 14 deletions(-)
base-commit: ecf11bc5f56abb3a2219a8c75e8a5b54467d1781
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
@ 2026-07-19 15:36 ` Kumar Kartikeya Dwivedi
2026-07-19 15:48 ` sashiko-bot
2026-07-19 16:17 ` bot+bpf-ci
2026-07-19 15:36 ` [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs Kumar Kartikeya Dwivedi
` (3 subsequent siblings)
4 siblings, 2 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Sashiko pointed out correctly that the case statement for
BPF_RES_SPIN_LOCK incorrectly checks offset for BPF_SPIN_LOCK.
Fix it by checking res_spin_lock_off instead.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
kernel/bpf/btf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index cbb1e49b9bcb..e7d4e9ba24e2 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -4168,7 +4168,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
rec->spin_lock_off = rec->fields[i].offset;
break;
case BPF_RES_SPIN_LOCK:
- WARN_ON_ONCE(rec->spin_lock_off >= 0);
+ WARN_ON_ONCE(rec->res_spin_lock_off >= 0);
/* Cache offset for faster lookup at runtime */
rec->res_spin_lock_off = rec->fields[i].offset;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
@ 2026-07-19 15:36 ` Kumar Kartikeya Dwivedi
2026-07-19 15:49 ` sashiko-bot
2026-07-19 15:36 ` [PATCH bpf-next v2 3/5] bpf: Mark bpf_refcount field as unique Kumar Kartikeya Dwivedi
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
btf_find_struct_field() initializes a fresh seen mask for every recursive
descent. Unique special fields in different levels of the same aggregate
therefore do not see one another. The duplicate fields can reach
btf_parse_fields(), where they trigger an invariant WARN_ON_ONCE(). A
crafted user BTF can consequently trigger the warning before map creation
checks capabilities.
Initialize the seen mask once in btf_find_field() and pass the same pointer
through struct, datasec, and nested-struct walks. This gives the entire field
traversal one shared uniqueness state.
Fixes: 64e8ee814819 ("bpf: look into the types of the fields of a struct type recursively.")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
kernel/bpf/btf.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index e7d4e9ba24e2..c577f00e9d88 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3751,7 +3751,7 @@ static int btf_repeat_fields(struct btf_field_info *info, int info_cnt,
static int btf_find_struct_field(const struct btf *btf,
const struct btf_type *t, u32 field_mask,
struct btf_field_info *info, int info_cnt,
- u32 level);
+ u32 level, u32 *seen_mask);
/* Find special fields in the struct type of a field.
*
@@ -3762,7 +3762,7 @@ static int btf_find_struct_field(const struct btf *btf,
static int btf_find_nested_struct(const struct btf *btf, const struct btf_type *t,
u32 off, u32 nelems,
u32 field_mask, struct btf_field_info *info,
- int info_cnt, u32 level)
+ int info_cnt, u32 level, u32 *seen_mask)
{
int ret, err, i;
@@ -3770,7 +3770,7 @@ static int btf_find_nested_struct(const struct btf *btf, const struct btf_type *
if (level >= MAX_RESOLVE_DEPTH)
return -E2BIG;
- ret = btf_find_struct_field(btf, t, field_mask, info, info_cnt, level);
+ ret = btf_find_struct_field(btf, t, field_mask, info, info_cnt, level, seen_mask);
if (ret <= 0)
return ret;
@@ -3827,7 +3827,7 @@ static int btf_find_field_one(const struct btf *btf,
if (expected_size && expected_size != sz * nelems)
return 0;
ret = btf_find_nested_struct(btf, var_type, off, nelems, field_mask,
- &info[0], info_cnt, level);
+ &info[0], info_cnt, level, seen_mask);
return ret;
}
@@ -3892,11 +3892,11 @@ static int btf_find_field_one(const struct btf *btf,
static int btf_find_struct_field(const struct btf *btf,
const struct btf_type *t, u32 field_mask,
struct btf_field_info *info, int info_cnt,
- u32 level)
+ u32 level, u32 *seen_mask)
{
int ret, idx = 0;
const struct btf_member *member;
- u32 i, off, seen_mask = 0;
+ u32 i, off;
for_each_member(i, t, member) {
const struct btf_type *member_type = btf_type_by_id(btf,
@@ -3910,7 +3910,7 @@ static int btf_find_struct_field(const struct btf *btf,
ret = btf_find_field_one(btf, t, member_type, i,
off, 0,
- field_mask, &seen_mask,
+ field_mask, seen_mask,
&info[idx], info_cnt - idx, level);
if (ret < 0)
return ret;
@@ -3921,11 +3921,11 @@ static int btf_find_struct_field(const struct btf *btf,
static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
u32 field_mask, struct btf_field_info *info,
- int info_cnt, u32 level)
+ int info_cnt, u32 level, u32 *seen_mask)
{
int ret, idx = 0;
const struct btf_var_secinfo *vsi;
- u32 i, off, seen_mask = 0;
+ u32 i, off;
for_each_vsi(i, t, vsi) {
const struct btf_type *var = btf_type_by_id(btf, vsi->type);
@@ -3933,7 +3933,7 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
off = vsi->offset;
ret = btf_find_field_one(btf, var, var_type, -1, off, vsi->size,
- field_mask, &seen_mask,
+ field_mask, seen_mask,
&info[idx], info_cnt - idx,
level);
if (ret < 0)
@@ -3947,10 +3947,12 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
u32 field_mask, struct btf_field_info *info,
int info_cnt)
{
+ u32 seen_mask = 0;
+
if (__btf_type_is_struct(t))
- return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0);
+ return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0, &seen_mask);
else if (btf_type_is_datasec(t))
- return btf_find_datasec_var(btf, t, field_mask, info, info_cnt, 0);
+ return btf_find_datasec_var(btf, t, field_mask, info, info_cnt, 0, &seen_mask);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH bpf-next v2 3/5] bpf: Mark bpf_refcount field as unique
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs Kumar Kartikeya Dwivedi
@ 2026-07-19 15:36 ` Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 4/5] selftests/bpf: Test duplicate unique fields in nested structs Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 5/5] selftests/bpf: Test duplicate bpf_refcount fields Kumar Kartikeya Dwivedi
4 siblings, 0 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
BPF_REFCOUNT is not marked as a unique field, while it should be. Fix
this oversight.
Fixes: d54730b50bae ("bpf: Introduce opaque bpf_refcount struct and add btf_record plumbing")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
kernel/bpf/btf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index c577f00e9d88..4eeeaeb69790 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3669,7 +3669,7 @@ static int btf_get_field_type(const struct btf *btf, const struct btf_type *var_
{ BPF_LIST_NODE, "bpf_list_node", false },
{ BPF_RB_ROOT, "bpf_rb_root", false },
{ BPF_RB_NODE, "bpf_rb_node", false },
- { BPF_REFCOUNT, "bpf_refcount", false },
+ { BPF_REFCOUNT, "bpf_refcount", true },
};
int type = 0, i;
const char *name = __btf_name_by_offset(btf, var_type->name_off);
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH bpf-next v2 4/5] selftests/bpf: Test duplicate unique fields in nested structs
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
` (2 preceding siblings ...)
2026-07-19 15:36 ` [PATCH bpf-next v2 3/5] bpf: Mark bpf_refcount field as unique Kumar Kartikeya Dwivedi
@ 2026-07-19 15:36 ` Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 5/5] selftests/bpf: Test duplicate bpf_refcount fields Kumar Kartikeya Dwivedi
4 siblings, 0 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Add a raw BTF test with a spin lock directly in a struct and another in a
nested struct. The duplicate must now be rejected during BTF loading.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
tools/testing/selftests/bpf/prog_tests/btf.c | 27 ++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c
index 66855cbd6b73..2100400d896b 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf.c
@@ -4250,6 +4250,33 @@ static struct btf_raw_test raw_tests[] = {
.max_entries = 1,
},
+/*
+ * struct inner {
+ * struct bpf_spin_lock lock;
+ * };
+ *
+ * struct value {
+ * struct bpf_spin_lock lock;
+ * struct inner nested;
+ * };
+ */
+{
+ .descr = "struct test duplicate nested unique fields",
+ .raw_types = {
+ BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
+ BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [2] */
+ BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+ BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [3] */
+ BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+ BTF_STRUCT_ENC(NAME_TBD, 2, 8), /* [4] */
+ BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+ BTF_MEMBER_ENC(NAME_TBD, 3, 32),
+ BTF_END_RAW,
+ },
+ BTF_STR_SEC("\0int\0bpf_spin_lock\0val\0inner\0lock\0value\0lock\0nested"),
+ .btf_load_err = true,
+},
+
{
.descr = "struct test repeated fields count overflow",
.raw_types = {
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH bpf-next v2 5/5] selftests/bpf: Test duplicate bpf_refcount fields
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
` (3 preceding siblings ...)
2026-07-19 15:36 ` [PATCH bpf-next v2 4/5] selftests/bpf: Test duplicate unique fields in nested structs Kumar Kartikeya Dwivedi
@ 2026-07-19 15:36 ` Kumar Kartikeya Dwivedi
4 siblings, 0 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:36 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Emil Tsalapatis, kkd, kernel-team
Add a raw BTF test with two bpf_refcount fields. The duplicate must be
rejected during BTF loading instead of reaching the duplicate-field
invariant in btf_parse_fields().
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
tools/testing/selftests/bpf/prog_tests/btf.c | 21 ++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c
index 2100400d896b..67b9015cbd98 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf.c
@@ -4277,6 +4277,27 @@ static struct btf_raw_test raw_tests[] = {
.btf_load_err = true,
},
+/*
+ * struct value {
+ * struct bpf_refcount a;
+ * struct bpf_refcount b;
+ * };
+ */
+{
+ .descr = "struct test duplicate bpf_refcount fields",
+ .raw_types = {
+ BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
+ BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [2] */
+ BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+ BTF_STRUCT_ENC(NAME_TBD, 2, 8), /* [3] */
+ BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+ BTF_MEMBER_ENC(NAME_TBD, 2, 32),
+ BTF_END_RAW,
+ },
+ BTF_STR_SEC("\0int\0bpf_refcount\0refs\0value\0a\0b"),
+ .btf_load_err = true,
+},
+
{
.descr = "struct test repeated fields count overflow",
.raw_types = {
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
@ 2026-07-19 15:48 ` sashiko-bot
2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
2026-07-19 16:17 ` bot+bpf-ci
1 sibling, 1 reply; 11+ messages in thread
From: sashiko-bot @ 2026-07-19 15:48 UTC (permalink / raw)
To: Kumar Kartikeya Dwivedi; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Userspace-triggerable kernel warning (WARN_ON_ONCE) due to nested struct bypassing `seen_mask` uniqueness check, potentially leading to kernel panic.
--
--- Patch [1]: [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock ---
commit f617fbd9a79f403f8e8be07c38922dcd0eedd840
Author: Kumar Kartikeya Dwivedi <memxor@gmail.com>
bpf: Fix offset warn check for bpf_res_spin_lock
This commit fixes an incorrect offset check for BPF_RES_SPIN_LOCK in
btf_parse_fields(). It now correctly checks res_spin_lock_off instead of
spin_lock_off.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index cbb1e49b9bcbf..e7d4e9ba24e26 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -4168,7 +4168,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
> rec->spin_lock_off = rec->fields[i].offset;
> break;
> case BPF_RES_SPIN_LOCK:
> - WARN_ON_ONCE(rec->spin_lock_off >= 0);
> + WARN_ON_ONCE(rec->res_spin_lock_off >= 0);
[Severity: High]
This is a pre-existing issue, but could this WARN_ON_ONCE() be triggered
from userspace and cause a kernel panic on systems with panic_on_warn
enabled?
If a crafted BTF with multiple identical unique fields (like
BPF_RES_SPIN_LOCK) is provided in different nested structures, it appears
btf_find_struct_field() resets seen_mask to 0 for each nested level:
kernel/bpf/btf.c:btf_find_struct_field() {
u32 i, off, seen_mask = 0;
...
}
This could allow duplicate unique fields to bypass the seen_mask check and
be returned to btf_parse_fields(). When iterating over these duplicates
here, would it hit this WARN_ON_ONCE() and panic the system? Should we
return an error instead of warning, or pass seen_mask down during the
recursive struct traversal to prevent this?
> /* Cache offset for faster lookup at runtime */
> rec->res_spin_lock_off = rec->fields[i].offset;
> break;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260719153634.2908692-1-memxor@gmail.com?part=1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs
2026-07-19 15:36 ` [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs Kumar Kartikeya Dwivedi
@ 2026-07-19 15:49 ` sashiko-bot
2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
0 siblings, 1 reply; 11+ messages in thread
From: sashiko-bot @ 2026-07-19 15:49 UTC (permalink / raw)
To: Kumar Kartikeya Dwivedi; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Multiple BPF_REFCOUNT fields in a BTF struct bypass the seen_mask uniqueness check because is_unique = false, allowing them to trigger a reachable WARN_ON_ONCE() in btf_parse_fields().
--
--- Patch [2]: [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs ---
commit f8de1a7879c048283531a81778eac42891723a9d
Author: Kumar Kartikeya Dwivedi <memxor@gmail.com>
bpf: Preserve unique-field state across nested structs
btf_find_struct_field() initializes a fresh seen mask for every recursive
descent. This commit passes a shared seen mask pointer through the entire
field traversal to ensure unique special fields in different levels of the
same aggregate properly see one another.
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index e7d4e9ba24e26..c577f00e9d885 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
[ ... ]
> @@ -3947,10 +3947,12 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
> u32 field_mask, struct btf_field_info *info,
> int info_cnt)
> {
> + u32 seen_mask = 0;
> +
> if (__btf_type_is_struct(t))
> - return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0);
> + return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0, &seen_mask);
[Severity: High]
This is a pre-existing issue, but since this patch improves the uniqueness
tracking via seen_mask, should BPF_REFCOUNT also be treated as a unique field?
In btf_get_field_type(), BPF_REFCOUNT is currently defined with
is_unique = false:
{ BPF_REFCOUNT, "bpf_refcount", false },
Because it bypasses the uniqueness validation, a user could load a BTF struct
containing multiple bpf_refcount fields. If this happens, does it eventually
reach btf_parse_fields() and intentionally trigger the WARN_ON_ONCE there?
case BPF_REFCOUNT:
WARN_ON_ONCE(rec->refcount_off >= 0);
/* Cache offset for faster lookup at runtime */
rec->refcount_off = rec->fields[i].offset;
break;
Could a crafted user BTF cause a kernel panic here if panic_on_warn is
enabled?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260719153634.2908692-1-memxor@gmail.com?part=2
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs
2026-07-19 15:49 ` sashiko-bot
@ 2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
0 siblings, 0 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:50 UTC (permalink / raw)
To: sashiko-reviews, Kumar Kartikeya Dwivedi; +Cc: bpf
On Sun Jul 19, 2026 at 5:49 PM CEST, sashiko-bot wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Multiple BPF_REFCOUNT fields in a BTF struct bypass the seen_mask uniqueness check because is_unique = false, allowing them to trigger a reachable WARN_ON_ONCE() in btf_parse_fields().
> --
>
> --- Patch [2]: [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs ---
> commit f8de1a7879c048283531a81778eac42891723a9d
> Author: Kumar Kartikeya Dwivedi <memxor@gmail.com>
>
> bpf: Preserve unique-field state across nested structs
>
> btf_find_struct_field() initializes a fresh seen mask for every recursive
> descent. This commit passes a shared seen mask pointer through the entire
> field traversal to ensure unique special fields in different levels of the
> same aggregate properly see one another.
>
>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>> index e7d4e9ba24e26..c577f00e9d885 100644
>> --- a/kernel/bpf/btf.c
>> +++ b/kernel/bpf/btf.c
>
> [ ... ]
>
>> @@ -3947,10 +3947,12 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
>> u32 field_mask, struct btf_field_info *info,
>> int info_cnt)
>> {
>> + u32 seen_mask = 0;
>> +
>> if (__btf_type_is_struct(t))
>> - return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0);
>> + return btf_find_struct_field(btf, t, field_mask, info, info_cnt, 0, &seen_mask);
>
> [Severity: High]
> This is a pre-existing issue, but since this patch improves the uniqueness
> tracking via seen_mask, should BPF_REFCOUNT also be treated as a unique field?
>
> In btf_get_field_type(), BPF_REFCOUNT is currently defined with
> is_unique = false:
>
> { BPF_REFCOUNT, "bpf_refcount", false },
>
> Because it bypasses the uniqueness validation, a user could load a BTF struct
> containing multiple bpf_refcount fields. If this happens, does it eventually
> reach btf_parse_fields() and intentionally trigger the WARN_ON_ONCE there?
>
> case BPF_REFCOUNT:
> WARN_ON_ONCE(rec->refcount_off >= 0);
> /* Cache offset for faster lookup at runtime */
> rec->refcount_off = rec->fields[i].offset;
> break;
>
> Could a crafted user BTF cause a kernel panic here if panic_on_warn is
> enabled?
Yes, but exactly what next commit fixes.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock
2026-07-19 15:48 ` sashiko-bot
@ 2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
0 siblings, 0 replies; 11+ messages in thread
From: Kumar Kartikeya Dwivedi @ 2026-07-19 15:50 UTC (permalink / raw)
To: sashiko-reviews, Kumar Kartikeya Dwivedi; +Cc: bpf
On Sun Jul 19, 2026 at 5:48 PM CEST, sashiko-bot wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Userspace-triggerable kernel warning (WARN_ON_ONCE) due to nested struct bypassing `seen_mask` uniqueness check, potentially leading to kernel panic.
> --
>
> --- Patch [1]: [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock ---
> commit f617fbd9a79f403f8e8be07c38922dcd0eedd840
> Author: Kumar Kartikeya Dwivedi <memxor@gmail.com>
>
> bpf: Fix offset warn check for bpf_res_spin_lock
>
> This commit fixes an incorrect offset check for BPF_RES_SPIN_LOCK in
> btf_parse_fields(). It now correctly checks res_spin_lock_off instead of
> spin_lock_off.
>
>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>> index cbb1e49b9bcbf..e7d4e9ba24e26 100644
>> --- a/kernel/bpf/btf.c
>> +++ b/kernel/bpf/btf.c
>> @@ -4168,7 +4168,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
>> rec->spin_lock_off = rec->fields[i].offset;
>> break;
>> case BPF_RES_SPIN_LOCK:
>> - WARN_ON_ONCE(rec->spin_lock_off >= 0);
>> + WARN_ON_ONCE(rec->res_spin_lock_off >= 0);
>
> [Severity: High]
> This is a pre-existing issue, but could this WARN_ON_ONCE() be triggered
> from userspace and cause a kernel panic on systems with panic_on_warn
> enabled?
>
> If a crafted BTF with multiple identical unique fields (like
> BPF_RES_SPIN_LOCK) is provided in different nested structures, it appears
> btf_find_struct_field() resets seen_mask to 0 for each nested level:
>
> kernel/bpf/btf.c:btf_find_struct_field() {
> u32 i, off, seen_mask = 0;
> ...
> }
>
> This could allow duplicate unique fields to bypass the seen_mask check and
> be returned to btf_parse_fields(). When iterating over these duplicates
> here, would it hit this WARN_ON_ONCE() and panic the system? Should we
> return an error instead of warning, or pass seen_mask down during the
> recursive struct traversal to prevent this?
>
>> /* Cache offset for faster lookup at runtime */
>> rec->res_spin_lock_off = rec->fields[i].offset;
>> break;
Fixed by next commit.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
2026-07-19 15:48 ` sashiko-bot
@ 2026-07-19 16:17 ` bot+bpf-ci
1 sibling, 0 replies; 11+ messages in thread
From: bot+bpf-ci @ 2026-07-19 16:17 UTC (permalink / raw)
To: memxor, bpf
Cc: ast, andrii, daniel, eddyz87, emil, kkd, kernel-team, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 834 bytes --]
> bpf: Fix offset warn check for bpf_res_spin_lock
>
> Sashiko pointed out correctly that the case statement for
> BPF_RES_SPIN_LOCK incorrectly checks offset for BPF_SPIN_LOCK.
> Fix it by checking res_spin_lock_off instead.
>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This looks like a bug fix. The incorrect check
"WARN_ON_ONCE(rec->spin_lock_off >= 0);" in the BPF_RES_SPIN_LOCK case of
btf_parse_fields() was introduced when that case was first added. Should
this include:
Fixes: 0de2046137f9 ("bpf: Implement verifier support for rqspinlock")
---
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/29693647189
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-07-19 16:17 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-19 15:36 [PATCH bpf-next v2 0/5] Fix unique field logic in BTF Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 1/5] bpf: Fix offset warn check for bpf_res_spin_lock Kumar Kartikeya Dwivedi
2026-07-19 15:48 ` sashiko-bot
2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
2026-07-19 16:17 ` bot+bpf-ci
2026-07-19 15:36 ` [PATCH bpf-next v2 2/5] bpf: Preserve unique-field state across nested structs Kumar Kartikeya Dwivedi
2026-07-19 15:49 ` sashiko-bot
2026-07-19 15:50 ` Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 3/5] bpf: Mark bpf_refcount field as unique Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 4/5] selftests/bpf: Test duplicate unique fields in nested structs Kumar Kartikeya Dwivedi
2026-07-19 15:36 ` [PATCH bpf-next v2 5/5] selftests/bpf: Test duplicate bpf_refcount fields Kumar Kartikeya Dwivedi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.