* [PATCH bpf-next v2 0/2] bpf: Reject MEM_ALLOC BTF accesses past bounds
@ 2026-06-23 17:34 Yiyang Chen
2026-06-23 17:34 ` [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds Yiyang Chen
2026-06-23 17:34 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover MEM_ALLOC access " Yiyang Chen
0 siblings, 2 replies; 4+ messages in thread
From: Yiyang Chen @ 2026-06-23 17:34 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Yiyang Chen, John Fastabend, Martin KaFai Lau, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan, bpf,
linux-kselftest, linux-kernel
BTF struct walks can relax the top-level struct-size check for trailing
flexible arrays. That relaxation must not let a PTR_TO_BTF_ID | MEM_ALLOC
access escape the bytes allocated by bpf_obj_new() or bpf_percpu_obj_new().
Patch 1 rejects MEM_ALLOC BTF walks whose access range reaches past the
current struct size before applying the flexible-array relaxation. Patch 2
adds a linked_list negative loader case for this path.
Changes in v2:
- Move the check from bpf_obj_new() type validation to BTF struct walking.
- Reject MEM_ALLOC accesses that reach past the allocated object bounds.
- Update the selftest expected verifier error and carry Eduard's Acked-by.
v1:
https://lore.kernel.org/bpf/cover.1782100805.git.chenyy23@mails.tsinghua.edu.cn/
Yiyang Chen (2):
bpf: Reject MEM_ALLOC BTF accesses past object bounds
selftests/bpf: Cover MEM_ALLOC access past object bounds
kernel/bpf/btf.c | 14 +++++++----
.../selftests/bpf/prog_tests/linked_list.c | 1 +
.../selftests/bpf/progs/linked_list_fail.c | 23 +++++++++++++++++++
3 files changed, 33 insertions(+), 5 deletions(-)
base-commit: a975094bf98ca97be9146f9d3b5681a6f9cf5ce3
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds
2026-06-23 17:34 [PATCH bpf-next v2 0/2] bpf: Reject MEM_ALLOC BTF accesses past bounds Yiyang Chen
@ 2026-06-23 17:34 ` Yiyang Chen
2026-06-25 20:34 ` Eduard Zingerman
2026-06-23 17:34 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover MEM_ALLOC access " Yiyang Chen
1 sibling, 1 reply; 4+ messages in thread
From: Yiyang Chen @ 2026-06-23 17:34 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Yiyang Chen, John Fastabend, Martin KaFai Lau, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan, bpf,
linux-kselftest, linux-kernel
BTF struct walks relax the struct-size check for accesses through a
trailing flexible array. That is valid for ordinary BTF type walking, but
PTR_TO_BTF_ID | MEM_ALLOC values point to objects allocated with the static
BTF type size.
When walking a MEM_ALLOC object, reject the access before applying the
flexible-array relaxation if the access range extends past the struct size.
This keeps verifier-approved BTF accesses within the bytes provided by the
allocation kfunc.
Fixes: 958cf2e273f0 ("bpf: Introduce bpf_obj_new")
Fixes: 36d8bdf75a93 ("bpf: Add alloc/xchg/direct_access support for local percpu kptr")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
kernel/bpf/btf.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 15ae7c43f..3e68af9c1 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -7069,7 +7069,7 @@ enum bpf_struct_walk_result {
static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, int off, int size,
u32 *next_btf_id, enum bpf_type_flag *flag,
- const char **field_name)
+ const char **field_name, bool is_alloc)
{
u32 i, moff, mtrue_end, msize = 0, total_nelems = 0;
const struct btf_type *mtype, *elem_type = NULL;
@@ -7096,11 +7096,14 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
*flag |= PTR_UNTRUSTED;
if (off + size > t->size) {
+ struct btf_array *array_elem;
+
+ if (is_alloc)
+ goto error;
+
/* If the last element is a variable size array, we may
* need to relax the rule.
*/
- struct btf_array *array_elem;
-
if (vlen == 0)
goto error;
@@ -7363,7 +7366,8 @@ int btf_struct_access(struct bpf_verifier_log *log,
t = btf_type_by_id(btf, id);
do {
- err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag, field_name);
+ err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag,
+ field_name, type_is_alloc(reg->type));
switch (err) {
case WALK_PTR:
@@ -7441,7 +7445,7 @@ bool btf_struct_ids_match(struct bpf_verifier_log *log,
type = btf_type_by_id(btf, id);
if (!type)
return false;
- err = btf_struct_walk(log, btf, type, off, 1, &id, &flag, NULL);
+ err = btf_struct_walk(log, btf, type, off, 1, &id, &flag, NULL, false);
if (err != WALK_STRUCT)
return false;
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Cover MEM_ALLOC access past object bounds
2026-06-23 17:34 [PATCH bpf-next v2 0/2] bpf: Reject MEM_ALLOC BTF accesses past bounds Yiyang Chen
2026-06-23 17:34 ` [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds Yiyang Chen
@ 2026-06-23 17:34 ` Yiyang Chen
1 sibling, 0 replies; 4+ messages in thread
From: Yiyang Chen @ 2026-06-23 17:34 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Yiyang Chen, John Fastabend, Martin KaFai Lau, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan, bpf,
linux-kselftest, linux-kernel
Add a linked_list negative loader case for a program-BTF type whose last
member is a zero-length flexible array. The program writes through the
first flexible-array element of an object allocated by bpf_obj_new().
The verifier should reject the access when the BTF walk reaches beyond the
static size of the allocated object.
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
.../selftests/bpf/prog_tests/linked_list.c | 1 +
.../selftests/bpf/progs/linked_list_fail.c | 23 +++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c
index 8defea025..c3d133c6a 100644
--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
@@ -68,6 +68,7 @@ static struct {
{ "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" },
{ "obj_new_no_composite", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
{ "obj_new_no_struct", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" },
+ { "obj_new_flex_array", "access beyond struct obj_new_flex" },
{ "obj_drop_non_zero_off", "R1 must have zero offset when passed to release func" },
{ "new_null_ret", "R0 invalid mem access 'ptr_or_null_'" },
{ "obj_new_acq", "Unreleased reference id=" },
diff --git a/tools/testing/selftests/bpf/progs/linked_list_fail.c b/tools/testing/selftests/bpf/progs/linked_list_fail.c
index ddd26d1a0..031e77a28 100644
--- a/tools/testing/selftests/bpf/progs/linked_list_fail.c
+++ b/tools/testing/selftests/bpf/progs/linked_list_fail.c
@@ -167,6 +167,16 @@ CHECK_OP(push_back);
#undef CHECK_OP
#undef INIT
+struct obj_new_flex_elem {
+ int lo;
+ int hi;
+};
+
+struct obj_new_flex {
+ int hdr;
+ struct obj_new_flex_elem cells[];
+};
+
SEC("?kprobe/xyz")
int map_compat_kprobe(void *ctx)
{
@@ -230,6 +240,19 @@ int obj_new_no_struct(void *ctx)
return 0;
}
+SEC("?tc")
+int obj_new_flex_array(void *ctx)
+{
+ struct obj_new_flex *p;
+
+ p = bpf_obj_new_impl(bpf_core_type_id_local(struct obj_new_flex), NULL);
+ if (!p)
+ return 0;
+ p->cells[0].hi = 42;
+ bpf_obj_drop_impl(p, NULL);
+ return 0;
+}
+
SEC("?tc")
int obj_drop_non_zero_off(void *ctx)
{
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds
2026-06-23 17:34 ` [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds Yiyang Chen
@ 2026-06-25 20:34 ` Eduard Zingerman
0 siblings, 0 replies; 4+ messages in thread
From: Eduard Zingerman @ 2026-06-25 20:34 UTC (permalink / raw)
To: Yiyang Chen, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Kumar Kartikeya Dwivedi
Cc: John Fastabend, Martin KaFai Lau, Song Liu, Yonghong Song,
Jiri Olsa, Emil Tsalapatis, Shuah Khan, bpf, linux-kselftest,
linux-kernel
On Tue, 2026-06-23 at 17:34 +0000, Yiyang Chen wrote:
> BTF struct walks relax the struct-size check for accesses through a
> trailing flexible array. That is valid for ordinary BTF type walking, but
> PTR_TO_BTF_ID | MEM_ALLOC values point to objects allocated with the static
> BTF type size.
>
> When walking a MEM_ALLOC object, reject the access before applying the
> flexible-array relaxation if the access range extends past the struct size.
> This keeps verifier-approved BTF accesses within the bytes provided by the
> allocation kfunc.
>
> Fixes: 958cf2e273f0 ("bpf: Introduce bpf_obj_new")
> Fixes: 36d8bdf75a93 ("bpf: Add alloc/xchg/direct_access support for local percpu kptr")
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
> kernel/bpf/btf.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 15ae7c43f..3e68af9c1 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -7069,7 +7069,7 @@ enum bpf_struct_walk_result {
> static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
> const struct btf_type *t, int off, int size,
> u32 *next_btf_id, enum bpf_type_flag *flag,
> - const char **field_name)
> + const char **field_name, bool is_alloc)
Nit: 'walk_flex_arrays' would be a better name.
> {
> u32 i, moff, mtrue_end, msize = 0, total_nelems = 0;
> const struct btf_type *mtype, *elem_type = NULL;
[...]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-25 20:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-23 17:34 [PATCH bpf-next v2 0/2] bpf: Reject MEM_ALLOC BTF accesses past bounds Yiyang Chen
2026-06-23 17:34 ` [PATCH bpf-next v2 1/2] bpf: Reject MEM_ALLOC BTF accesses past object bounds Yiyang Chen
2026-06-25 20:34 ` Eduard Zingerman
2026-06-23 17:34 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover MEM_ALLOC access " Yiyang Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome