* [PATCH bpf-next 0/2] bpf: Reject flexible-array allocation types
@ 2026-06-22 4:56 Yiyang Chen
2026-06-22 4:56 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-22 4:56 ` [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection Yiyang Chen
0 siblings, 2 replies; 6+ messages in thread
From: Yiyang Chen @ 2026-06-22 4:56 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
bpf_obj_new() and bpf_percpu_obj_new() allocate only the static BTF size
for the selected program-BTF type.
A program-BTF struct can nevertheless end with a zero-length flexible array.
Generic BTF struct walks have special handling for such trailing arrays, and
can validate field accesses beyond the allocated static object size.
Patch 1 rejects allocation kfunc types with trailing flexible arrays.
Patch 2 adds a linked_list negative loader case for the rejection.
Yiyang Chen (2):
bpf: Reject flexible-array allocation types
selftests/bpf: Cover flexible-array allocation rejection
kernel/bpf/verifier.c | 28 +++++++++++++++++++
.../selftests/bpf/prog_tests/linked_list.c | 2 ++
.../selftests/bpf/progs/linked_list_fail.c | 23 +++++++++++++++
3 files changed, 53 insertions(+)
base-commit: a975094bf98ca97be9146f9d3b5681a6f9cf5ce3
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf-next 1/2] bpf: Reject flexible-array allocation types
2026-06-22 4:56 [PATCH bpf-next 0/2] bpf: Reject flexible-array allocation types Yiyang Chen
@ 2026-06-22 4:56 ` Yiyang Chen
2026-06-22 5:45 ` bot+bpf-ci
2026-06-22 18:50 ` Eduard Zingerman
2026-06-22 4:56 ` [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection Yiyang Chen
1 sibling, 2 replies; 6+ messages in thread
From: Yiyang Chen @ 2026-06-22 4:56 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
bpf_obj_new() and bpf_percpu_obj_new() allocate the static BTF size for
the selected program-BTF type. A struct type can still end with a
zero-length flexible array, and generic BTF struct walks have special
handling that can accept accesses beyond the static struct size through
such a member.
Reject allocation kfunc types with trailing flexible arrays before marking
the return value as PTR_TO_BTF_ID | MEM_ALLOC. This keeps the
verifier-visible BTF access shape aligned with the object size allocated by
the runtime 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/verifier.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2abc79dbf..c3a574cc0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -10955,6 +10955,30 @@ static bool __btf_type_is_scalar_struct(struct bpf_verifier_env *env,
return true;
}
+static bool btf_type_has_trailing_flex_array(const struct btf *btf,
+ const struct btf_type *t)
+{
+ const struct btf_type *member_type;
+ const struct btf_member *member;
+ const struct btf_array *array;
+ u32 vlen;
+
+ if (!btf_type_is_struct(t))
+ return false;
+
+ vlen = btf_type_vlen(t);
+ if (!vlen)
+ return false;
+
+ member = btf_type_member(t) + vlen - 1;
+ member_type = btf_type_skip_modifiers(btf, member->type, NULL);
+ if (!btf_type_is_array(member_type))
+ return false;
+
+ array = btf_array(member_type);
+ return !array->nelems;
+}
+
enum kfunc_ptr_arg_type {
KF_ARG_PTR_TO_CTX,
KF_ARG_PTR_TO_ALLOC_BTF_ID, /* Allocated object */
@@ -12749,6 +12773,10 @@ static int check_special_kfunc(struct bpf_verifier_env *env, struct bpf_kfunc_ca
verbose(env, "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct\n");
return -EINVAL;
}
+ if (btf_type_has_trailing_flex_array(ret_btf, ret_t)) {
+ verbose(env, "bpf_obj_new type must not contain a flexible array\n");
+ return -EINVAL;
+ }
if (is_bpf_percpu_obj_new_kfunc(meta->func_id)) {
if (ret_t->size > BPF_GLOBAL_PERCPU_MA_MAX_SIZE) {
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection
2026-06-22 4:56 [PATCH bpf-next 0/2] bpf: Reject flexible-array allocation types Yiyang Chen
2026-06-22 4:56 ` [PATCH bpf-next 1/2] " Yiyang Chen
@ 2026-06-22 4:56 ` Yiyang Chen
2026-06-22 18:51 ` Eduard Zingerman
1 sibling, 1 reply; 6+ messages in thread
From: Yiyang Chen @ 2026-06-22 4:56 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 so an incorrect allocation-time acceptance
would leave the verifier to approve an access outside the allocated object.
Use the explicit _impl kfunc forms in this negative test so the case is
scoped to the allocation type check and not to implicit kfunc wrapper
resolution.
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
.../selftests/bpf/prog_tests/linked_list.c | 2 ++
.../selftests/bpf/progs/linked_list_fail.c | 23 +++++++++++++++++++
2 files changed, 25 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..49c250132 100644
--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
@@ -68,6 +68,8 @@ 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",
+ "bpf_obj_new type must not contain a flexible array" },
{ "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] 6+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Reject flexible-array allocation types
2026-06-22 4:56 ` [PATCH bpf-next 1/2] " Yiyang Chen
@ 2026-06-22 5:45 ` bot+bpf-ci
2026-06-22 18:50 ` Eduard Zingerman
1 sibling, 0 replies; 6+ messages in thread
From: bot+bpf-ci @ 2026-06-22 5:45 UTC (permalink / raw)
To: chenyy23, ast, daniel, andrii, eddyz87, memxor
Cc: chenyy23, john.fastabend, martin.lau, song, yonghong.song, jolsa,
emil, shuah, bpf, linux-kselftest, linux-kernel, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 2abc79dbf281..c3a574cc0d09 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -12749,6 +12773,10 @@ static int check_special_kfunc(struct bpf_verifier_env *env, struct bpf_kfunc_ca
> verbose(env, "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct\n");
> return -EINVAL;
> }
> + if (btf_type_has_trailing_flex_array(ret_btf, ret_t)) {
> + verbose(env, "bpf_obj_new type must not contain a flexible array\n");
> + return -EINVAL;
> + }
This isn't a bug, but this branch handles both is_bpf_obj_new_kfunc and
is_bpf_percpu_obj_new_kfunc, and the message just above uses the dual form
"bpf_obj_new/bpf_percpu_obj_new".
Should this new message also say "bpf_obj_new/bpf_percpu_obj_new" so it
reads correctly when it fires for a bpf_percpu_obj_new() call?
>
> if (is_bpf_percpu_obj_new_kfunc(meta->func_id)) {
> if (ret_t->size > BPF_GLOBAL_PERCPU_MA_MAX_SIZE) {
---
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/27931273498
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Reject flexible-array allocation types
2026-06-22 4:56 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-22 5:45 ` bot+bpf-ci
@ 2026-06-22 18:50 ` Eduard Zingerman
1 sibling, 0 replies; 6+ messages in thread
From: Eduard Zingerman @ 2026-06-22 18:50 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 Mon, 2026-06-22 at 04:56 +0000, Yiyang Chen wrote:
> bpf_obj_new() and bpf_percpu_obj_new() allocate the static BTF size for
> the selected program-BTF type. A struct type can still end with a
> zero-length flexible array, and generic BTF struct walks have special
> handling that can accept accesses beyond the static struct size through
> such a member.
>
> Reject allocation kfunc types with trailing flexible arrays before marking
> the return value as PTR_TO_BTF_ID | MEM_ALLOC. This keeps the
> verifier-visible BTF access shape aligned with the object size allocated by
> the runtime 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>
> ---
Hi Yiyang, thank you for the report.
I think this should be handled at the btf_struct_walk() level by
checking MEM_ALLOC flag. And there is no need to check if the array is
flex or not, checking if the final offset reaches past the allocated
object boundary should be sufficient.
pw-bot: cr.
[...]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection
2026-06-22 4:56 ` [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection Yiyang Chen
@ 2026-06-22 18:51 ` Eduard Zingerman
0 siblings, 0 replies; 6+ messages in thread
From: Eduard Zingerman @ 2026-06-22 18:51 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 Mon, 2026-06-22 at 04:56 +0000, Yiyang Chen wrote:
> 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 so an incorrect allocation-time acceptance
> would leave the verifier to approve an access outside the allocated object.
>
> Use the explicit _impl kfunc forms in this negative test so the case is
> scoped to the allocation type check and not to implicit kfunc wrapper
> resolution.
>
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
[...]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-22 18:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-22 4:56 [PATCH bpf-next 0/2] bpf: Reject flexible-array allocation types Yiyang Chen
2026-06-22 4:56 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-22 5:45 ` bot+bpf-ci
2026-06-22 18:50 ` Eduard Zingerman
2026-06-22 4:56 ` [PATCH bpf-next 2/2] selftests/bpf: Cover flexible-array allocation rejection Yiyang Chen
2026-06-22 18:51 ` Eduard Zingerman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox