mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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