* [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays
@ 2026-06-02 7:35 Lin Ma
2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma
2026-06-02 8:15 ` [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays bot+bpf-ci
0 siblings, 2 replies; 8+ messages in thread
From: Lin Ma @ 2026-06-02 7:35 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, bpf
Cc: Andrii Nakryiko, John Fastabend, Martin KaFai Lau,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
Yonghong Song, Jiri Olsa, YiFei Zhu, Shuah Khan, linux-kselftest,
linux-kernel, Amery Hung, Lin Ma, Rongzhen Cui, Jingguo Tan,
cenxianlong, chenzhe
The recent KCTF-reported cgroup local storage issue assigned
CVE-2025-38502 was fixed by commit abad3d0bad72 ("bpf: Fix oob access
in cgroup local storage").
However, the previous fixes are still incomplete. The current prog-array
compatibility check treats a program with no cgroup storage as
compatible with any stored storage cookie. This allows a storage-less
program to bridge a tail-call chain between an entry program and a
storage-using callee even though runtime cgroup local storage still
follows the caller context.
Require exact per-type storage_cookie equality when checking prog-array
compatibility. This blocks zero-storage bridge programs from joining a
prog-array owned by a storage-using program and closes the residual
A -> B(no storage) -> C(storage) path.
This also aligns with Amery Hung's earlier NULL-storage tail-call fix by
requiring storage use to match consistently across prog-array users.
Cc: stable@vger.kernel.org
Fixes: 7d9c3427894f ("bpf: Make cgroup storages shared between programs on the same cgroup")
Tested-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Lin Ma <malin89@huawei.com>
Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com>
Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>
---
v1: https://lore.kernel.org/bpf/20260601095158.1186318-1-malin89@huawei.com/
v1 -> v2:
- refine the commit message and mention the relation to Amery Hung's
NULL-storage tail-call fix
- add patch 2/2 selftests for tail-call cgroup storage prog-array
checks
kernel/bpf/core.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 6aa2a8b24030..f0b61b10f30e 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2470,8 +2470,12 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
break;
cookie = aux->cgroup_storage[i] ?
aux->cgroup_storage[i]->cookie : 0;
- ret = map->owner->storage_cookie[i] == cookie ||
- !cookie;
+ /*
+ * Tail calls keep using the caller cgroup storage
+ * context, so prog-array members must use the same
+ * storage cookie.
+ */
+ ret = map->owner->storage_cookie[i] == cookie;
}
if (ret &&
map->owner->attach_func_proto != aux->attach_func_proto) {
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks 2026-06-02 7:35 [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays Lin Ma @ 2026-06-02 7:35 ` Lin Ma 2026-06-02 8:15 ` bot+bpf-ci ` (2 more replies) 2026-06-02 8:15 ` [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays bot+bpf-ci 1 sibling, 3 replies; 8+ messages in thread From: Lin Ma @ 2026-06-02 7:35 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann, bpf Cc: Andrii Nakryiko, John Fastabend, Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa, YiFei Zhu, Shuah Khan, linux-kselftest, linux-kernel, Amery Hung, Lin Ma, Rongzhen Cui, Jingguo Tan, cenxianlong, chenzhe Add tail-call selftests for prog-array ownership when cgroup storage is in use. Verify that loading succeeds when callers and callees reuse the owner's cgroup storage map, and that loading fails for a different storage map or for a storage-less bridge program. Signed-off-by: Lin Ma <malin89@huawei.com> Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> --- .../selftests/bpf/prog_tests/tailcalls.c | 103 ++++++++++++++++++ .../bpf/progs/tailcall_cgrp_storage.c | 44 ++++++++ .../progs/tailcall_cgrp_storage_no_storage.c | 20 ++++ .../bpf/progs/tailcall_cgrp_storage_owner.c | 32 ++++++ 4 files changed, 199 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage.c create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_no_storage.c create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_owner.c diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c index 7d534fde0af9..c1403ab20eae 100644 --- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c +++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c @@ -8,6 +8,9 @@ #include "tailcall_freplace.skel.h" #include "tc_bpf2bpf.skel.h" #include "tailcall_fail.skel.h" +#include "tailcall_cgrp_storage_owner.skel.h" +#include "tailcall_cgrp_storage_no_storage.skel.h" +#include "tailcall_cgrp_storage.skel.h" #include "tailcall_sleepable.skel.h" /* test_tailcall_1 checks basic functionality by patching multiple locations @@ -1654,6 +1657,100 @@ static void test_tailcall_failure() RUN_TESTS(tailcall_fail); } +static void test_tailcall_cgrp_storage(void) +{ + struct tailcall_cgrp_storage_owner *owner_skel = NULL; + struct tailcall_cgrp_storage *skel = NULL; + int err, key = 0, prog_array_fd, prog_fd, storage_map_fd; + + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) + return; + + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); + storage_map_fd = bpf_map__fd(owner_skel->maps.storage_map); + + skel = tailcall_cgrp_storage__open(); + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage__open")) + goto out; + + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); + if (!ASSERT_OK(err, "reuse_prog_array")) + goto out; + + err = bpf_map__reuse_fd(skel->maps.storage_map, storage_map_fd); + if (!ASSERT_OK(err, "reuse_storage_map")) + goto out; + + err = bpf_object__load(skel->obj); + if (!ASSERT_OK(err, "tailcall_cgrp_storage__load")) + goto out; + + prog_fd = bpf_program__fd(skel->progs.callee_prog); + err = bpf_map_update_elem(prog_array_fd, &key, &prog_fd, BPF_ANY); + ASSERT_OK(err, "update_prog_array"); + +out: + tailcall_cgrp_storage__destroy(skel); + tailcall_cgrp_storage_owner__destroy(owner_skel); +} + +static void test_tailcall_cgrp_storage_diff_storage(void) +{ + struct tailcall_cgrp_storage_owner *owner_skel = NULL; + struct tailcall_cgrp_storage *skel = NULL; + int err, prog_array_fd; + + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) + return; + + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); + + skel = tailcall_cgrp_storage__open(); + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage__open")) + goto out; + + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); + if (!ASSERT_OK(err, "reuse_prog_array")) + goto out; + + err = bpf_object__load(skel->obj); + ASSERT_ERR(err, "tailcall_cgrp_storage__load"); + +out: + tailcall_cgrp_storage__destroy(skel); + tailcall_cgrp_storage_owner__destroy(owner_skel); +} + +static void test_tailcall_cgrp_storage_no_storage(void) +{ + struct tailcall_cgrp_storage_owner *owner_skel = NULL; + struct tailcall_cgrp_storage_no_storage *skel = NULL; + int err, prog_array_fd; + + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) + return; + + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); + + skel = tailcall_cgrp_storage_no_storage__open(); + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage_no_storage__open")) + goto out; + + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); + if (!ASSERT_OK(err, "reuse_prog_array")) + goto out; + + err = bpf_object__load(skel->obj); + ASSERT_ERR(err, "tailcall_cgrp_storage_no_storage__load"); + +out: + tailcall_cgrp_storage_no_storage__destroy(skel); + tailcall_cgrp_storage_owner__destroy(owner_skel); +} + noinline void uprobe_sleepable_trigger(void) { asm volatile (""); @@ -1777,6 +1874,12 @@ void test_tailcalls(void) test_tailcall_freplace(); if (test__start_subtest("tailcall_bpf2bpf_freplace")) test_tailcall_bpf2bpf_freplace(); + if (test__start_subtest("tailcall_cgrp_storage")) + test_tailcall_cgrp_storage(); + if (test__start_subtest("tailcall_cgrp_storage_diff_storage")) + test_tailcall_cgrp_storage_diff_storage(); + if (test__start_subtest("tailcall_cgrp_storage_no_storage")) + test_tailcall_cgrp_storage_no_storage(); if (test__start_subtest("tailcall_failure")) test_tailcall_failure(); if (test__start_subtest("tailcall_sleepable")) diff --git a/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage.c b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage.c new file mode 100644 index 000000000000..4dd3a0033d75 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <vmlinux.h> +#include <bpf/bpf_helpers.h> + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); + __type(key, struct bpf_cgroup_storage_key); + __type(value, __u64); +} storage_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(max_entries, 1); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); +} prog_array SEC(".maps"); + +SEC("cgroup_skb/egress") +int caller_prog(struct __sk_buff *skb) +{ + __u64 *storage; + + storage = bpf_get_local_storage(&storage_map, 0); + if (storage) + *storage = 1; + + bpf_tail_call(skb, &prog_array, 0); + return 1; +} + +SEC("cgroup_skb/egress") +int callee_prog(struct __sk_buff *skb) +{ + __u64 *storage; + + storage = bpf_get_local_storage(&storage_map, 0); + if (storage) + *storage = 1; + + return 1; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_no_storage.c b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_no_storage.c new file mode 100644 index 000000000000..f95166dad7c5 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_no_storage.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <vmlinux.h> +#include <bpf/bpf_helpers.h> + +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(max_entries, 1); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); +} prog_array SEC(".maps"); + +SEC("cgroup_skb/egress") +int caller_prog(struct __sk_buff *skb) +{ + bpf_tail_call(skb, &prog_array, 0); + return 1; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_owner.c b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_owner.c new file mode 100644 index 000000000000..d7e8ec9855c5 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_owner.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <vmlinux.h> +#include <bpf/bpf_helpers.h> + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); + __type(key, struct bpf_cgroup_storage_key); + __type(value, __u64); +} storage_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(max_entries, 1); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); +} prog_array SEC(".maps"); + +SEC("cgroup_skb/egress") +int prog_array_owner(struct __sk_buff *skb) +{ + __u64 *storage; + + storage = bpf_get_local_storage(&storage_map, 0); + if (storage) + *storage = 1; + + bpf_tail_call(skb, &prog_array, 0); + return 1; +} + +char _license[] SEC("license") = "GPL"; -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks 2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma @ 2026-06-02 8:15 ` bot+bpf-ci 2026-06-02 16:41 ` Yonghong Song 2026-06-03 15:01 ` Leon Hwang 2 siblings, 0 replies; 8+ messages in thread From: bot+bpf-ci @ 2026-06-02 8:15 UTC (permalink / raw) To: malin89, ast, daniel, bpf Cc: andrii, john.fastabend, martin.lau, eddyz87, memxor, song, yonghong.song, jolsa, zhuyifei, shuah, linux-kselftest, linux-kernel, ameryhung, malin89, cuirongzhen, tanjingguo, cenxianlong, chenzhe, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 1408 bytes --] > Add tail-call selftests for prog-array ownership when cgroup storage is > in use. Verify that loading succeeds when callers and callees reuse the > owner's cgroup storage map, and that loading fails for a different > storage map or for a storage-less bridge program. > > Signed-off-by: Lin Ma <malin89@huawei.com> > Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> > Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> bot+bpf-ci@kernel.org raised a concern about the Fixes tag in v1. The bot pointed out that the commit message references commit abad3d0bad72 as the incomplete fix that this patch builds upon, and the current patch removes the '|| !cookie' logic that was introduced in abad3d0bad72, not the original shared storage feature from 7d9c3427894f. The bot suggested the Fixes tag should point to abad3d0bad72 rather than 7d9c3427894f. The author responded explaining both patches target 7d9c3427894f and this is a complement rather than a fix of abad3d0bad72, but did not change the Fixes tag in v2. This remains unaddressed. Reference: https://lore.kernel.org/bpf/d061816d1a9bfa304d8b8a986df4729e3b30028a350d79e7eb981a41d7b5a53c@mail.kernel.org/ --- 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/26806034423 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks 2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma 2026-06-02 8:15 ` bot+bpf-ci @ 2026-06-02 16:41 ` Yonghong Song 2026-06-03 15:01 ` Leon Hwang 2 siblings, 0 replies; 8+ messages in thread From: Yonghong Song @ 2026-06-02 16:41 UTC (permalink / raw) To: Lin Ma, Alexei Starovoitov, Daniel Borkmann, bpf Cc: Andrii Nakryiko, John Fastabend, Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu, Jiri Olsa, YiFei Zhu, Shuah Khan, linux-kselftest, linux-kernel, Amery Hung, Rongzhen Cui, Jingguo Tan, cenxianlong, chenzhe On 6/2/26 12:35 AM, Lin Ma wrote: > Add tail-call selftests for prog-array ownership when cgroup storage is > in use. Verify that loading succeeds when callers and callees reuse the > owner's cgroup storage map, and that loading fails for a different > storage map or for a storage-less bridge program. > > Signed-off-by: Lin Ma <malin89@huawei.com> > Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> > Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> > --- > .../selftests/bpf/prog_tests/tailcalls.c | 103 ++++++++++++++++++ > .../bpf/progs/tailcall_cgrp_storage.c | 44 ++++++++ > .../progs/tailcall_cgrp_storage_no_storage.c | 20 ++++ > .../bpf/progs/tailcall_cgrp_storage_owner.c | 32 ++++++ > 4 files changed, 199 insertions(+) > create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage.c > create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_no_storage.c > create mode 100644 tools/testing/selftests/bpf/progs/tailcall_cgrp_storage_owner.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c > index 7d534fde0af9..c1403ab20eae 100644 > --- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c > +++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c > @@ -8,6 +8,9 @@ > #include "tailcall_freplace.skel.h" > #include "tc_bpf2bpf.skel.h" > #include "tailcall_fail.skel.h" > +#include "tailcall_cgrp_storage_owner.skel.h" > +#include "tailcall_cgrp_storage_no_storage.skel.h" > +#include "tailcall_cgrp_storage.skel.h" > #include "tailcall_sleepable.skel.h" > > /* test_tailcall_1 checks basic functionality by patching multiple locations > @@ -1654,6 +1657,100 @@ static void test_tailcall_failure() > RUN_TESTS(tailcall_fail); > } > > +static void test_tailcall_cgrp_storage(void) > +{ > + struct tailcall_cgrp_storage_owner *owner_skel = NULL; > + struct tailcall_cgrp_storage *skel = NULL; > + int err, key = 0, prog_array_fd, prog_fd, storage_map_fd; > + > + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); > + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) > + return; > + > + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); > + storage_map_fd = bpf_map__fd(owner_skel->maps.storage_map); > + > + skel = tailcall_cgrp_storage__open(); > + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage__open")) > + goto out; > + > + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); > + if (!ASSERT_OK(err, "reuse_prog_array")) > + goto out; > + > + err = bpf_map__reuse_fd(skel->maps.storage_map, storage_map_fd); > + if (!ASSERT_OK(err, "reuse_storage_map")) > + goto out; > + > + err = bpf_object__load(skel->obj); > + if (!ASSERT_OK(err, "tailcall_cgrp_storage__load")) > + goto out; > + > + prog_fd = bpf_program__fd(skel->progs.callee_prog); > + err = bpf_map_update_elem(prog_array_fd, &key, &prog_fd, BPF_ANY); > + ASSERT_OK(err, "update_prog_array"); > + > +out: > + tailcall_cgrp_storage__destroy(skel); > + tailcall_cgrp_storage_owner__destroy(owner_skel); > +} > + > +static void test_tailcall_cgrp_storage_diff_storage(void) > +{ > + struct tailcall_cgrp_storage_owner *owner_skel = NULL; > + struct tailcall_cgrp_storage *skel = NULL; > + int err, prog_array_fd; > + > + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); > + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) > + return; > + > + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); > + > + skel = tailcall_cgrp_storage__open(); > + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage__open")) > + goto out; > + > + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); > + if (!ASSERT_OK(err, "reuse_prog_array")) > + goto out; > + > + err = bpf_object__load(skel->obj); > + ASSERT_ERR(err, "tailcall_cgrp_storage__load"); > + > +out: > + tailcall_cgrp_storage__destroy(skel); > + tailcall_cgrp_storage_owner__destroy(owner_skel); > +} > + > +static void test_tailcall_cgrp_storage_no_storage(void) > +{ > + struct tailcall_cgrp_storage_owner *owner_skel = NULL; > + struct tailcall_cgrp_storage_no_storage *skel = NULL; > + int err, prog_array_fd; > + > + owner_skel = tailcall_cgrp_storage_owner__open_and_load(); > + if (!ASSERT_OK_PTR(owner_skel, "owner_open_and_load")) > + return; > + > + prog_array_fd = bpf_map__fd(owner_skel->maps.prog_array); > + > + skel = tailcall_cgrp_storage_no_storage__open(); > + if (!ASSERT_OK_PTR(skel, "tailcall_cgrp_storage_no_storage__open")) > + goto out; > + > + err = bpf_map__reuse_fd(skel->maps.prog_array, prog_array_fd); > + if (!ASSERT_OK(err, "reuse_prog_array")) > + goto out; > + > + err = bpf_object__load(skel->obj); > + ASSERT_ERR(err, "tailcall_cgrp_storage_no_storage__load"); > + > +out: > + tailcall_cgrp_storage_no_storage__destroy(skel); > + tailcall_cgrp_storage_owner__destroy(owner_skel); > +} > + > noinline void uprobe_sleepable_trigger(void) > { > asm volatile (""); > @@ -1777,6 +1874,12 @@ void test_tailcalls(void) > test_tailcall_freplace(); > if (test__start_subtest("tailcall_bpf2bpf_freplace")) > test_tailcall_bpf2bpf_freplace(); > + if (test__start_subtest("tailcall_cgrp_storage")) > + test_tailcall_cgrp_storage(); > + if (test__start_subtest("tailcall_cgrp_storage_diff_storage")) > + test_tailcall_cgrp_storage_diff_storage(); > + if (test__start_subtest("tailcall_cgrp_storage_no_storage")) > + test_tailcall_cgrp_storage_no_storage(); Since the failure is due to 'A -> B(no storage) -> C(storage)' in your commit message, you should create a selftest for that. Current selftests are good but not addressing the issue in patch 1. > if (test__start_subtest("tailcall_failure")) > test_tailcall_failure(); > if (test__start_subtest("tailcall_sleepable")) > [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks 2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma 2026-06-02 8:15 ` bot+bpf-ci 2026-06-02 16:41 ` Yonghong Song @ 2026-06-03 15:01 ` Leon Hwang 2 siblings, 0 replies; 8+ messages in thread From: Leon Hwang @ 2026-06-03 15:01 UTC (permalink / raw) To: Lin Ma Cc: Leon Hwang, Alexei Starovoitov, Daniel Borkmann, bpf, Andrii Nakryiko, John Fastabend, Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa, YiFei Zhu, Shuah Khan, linux-kselftest, linux-kernel, Amery Hung, Rongzhen Cui, Jingguo Tan, cenxianlong, chenzhe On Tue, 2 Jun 2026 15:35:39 +0800, Lin Ma <malin89@huawei.com> wrote: > Add tail-call selftests for prog-array ownership when cgroup storage is > in use. Verify that loading succeeds when callers and callees reuse the > owner's cgroup storage map, and that loading fails for a different > storage map or for a storage-less bridge program. > > Signed-off-by: Lin Ma <malin89@huawei.com> > Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> > Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> > --- [...] > @@ -1777,6 +1874,12 @@ void test_tailcalls(void) > test_tailcall_freplace(); > if (test__start_subtest("tailcall_bpf2bpf_freplace")) > test_tailcall_bpf2bpf_freplace(); > + if (test__start_subtest("tailcall_cgrp_storage")) > + test_tailcall_cgrp_storage(); > + if (test__start_subtest("tailcall_cgrp_storage_diff_storage")) > + test_tailcall_cgrp_storage_diff_storage(); > + if (test__start_subtest("tailcall_cgrp_storage_no_storage")) > + test_tailcall_cgrp_storage_no_storage(); > These new ones should stay at the tail of test_tailcalls(). Thanks, Leon > if (test__start_subtest("tailcall_failure")) > test_tailcall_failure(); > if (test__start_subtest("tailcall_sleepable")) [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays 2026-06-02 7:35 [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays Lin Ma 2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma @ 2026-06-02 8:15 ` bot+bpf-ci 2026-06-02 15:14 ` Yonghong Song 1 sibling, 1 reply; 8+ messages in thread From: bot+bpf-ci @ 2026-06-02 8:15 UTC (permalink / raw) To: malin89, ast, daniel, bpf Cc: andrii, john.fastabend, martin.lau, eddyz87, memxor, song, yonghong.song, jolsa, zhuyifei, shuah, linux-kselftest, linux-kernel, ameryhung, malin89, cuirongzhen, tanjingguo, cenxianlong, chenzhe, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 2814 bytes --] > bpf: Tighten cgroup storage cookie checks for prog arrays > > The recent KCTF-reported cgroup local storage issue assigned > CVE-2025-38502 was fixed by commit abad3d0bad72 ("bpf: Fix oob access > in cgroup local storage"). > > However, the previous fixes are still incomplete. The current prog-array > compatibility check treats a program with no cgroup storage as > compatible with any stored storage cookie. This allows a storage-less > program to bridge a tail-call chain between an entry program and a > storage-using callee even though runtime cgroup local storage still > follows the caller context. > > Require exact per-type storage_cookie equality when checking prog-array > compatibility. This blocks zero-storage bridge programs from joining a > prog-array owned by a storage-using program and closes the residual > A -> B(no storage) -> C(storage) path. > > This also aligns with Amery Hung's earlier NULL-storage tail-call fix by > requiring storage use to match consistently across prog-array users. > > Cc: stable@vger.kernel.org > Fixes: 7d9c3427894f ("bpf: Make cgroup storages shared between programs on the same cgroup") > Tested-by: Amery Hung <ameryhung@gmail.com> > Signed-off-by: Lin Ma <malin89@huawei.com> > Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> > Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> Should the Fixes: tag point to abad3d0bad72 instead of 7d9c3427894f? The code this patch removes is the '|| !cookie' clause in __bpf_prog_map_compatible(): ret = map->owner->storage_cookie[i] == cookie || !cookie; That permissive '|| !cookie' clause, which treats a storage-less program as compatible with any stored cookie, was introduced by abad3d0bad72 ("bpf: Fix oob access in cgroup local storage"). The commit referenced by the current tag, 7d9c3427894f ("bpf: Make cgroup storages shared between programs on the same cgroup"), only added the shared cgroup-storage feature and does not touch __bpf_prog_map_compatible() or add the storage_cookie[] check. Would this be more accurate? Fixes: abad3d0bad72 ("bpf: Fix oob access in cgroup local storage") This same question was raised on the v1 thread by the bpf-ci review bot (https://lore.kernel.org/bpf/20260601095158.1186318-1-malin89@huawei.com/), noting that the patch removes the '|| !cookie' logic introduced in abad3d0bad72 rather than the original shared storage feature. The reply disagreed and kept the tag pointing at 7d9c3427894f in v2, but the reviewer did not acknowledge that explanation, so it may be worth settling before this is applied. --- 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/26806034423 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays 2026-06-02 8:15 ` [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays bot+bpf-ci @ 2026-06-02 15:14 ` Yonghong Song 0 siblings, 0 replies; 8+ messages in thread From: Yonghong Song @ 2026-06-02 15:14 UTC (permalink / raw) To: bot+bpf-ci, malin89, ast, daniel, bpf Cc: andrii, john.fastabend, martin.lau, eddyz87, memxor, song, jolsa, zhuyifei, shuah, linux-kselftest, linux-kernel, ameryhung, cuirongzhen, tanjingguo, cenxianlong, chenzhe, martin.lau, clm, ihor.solodrai On 6/2/26 1:15 AM, bot+bpf-ci@kernel.org wrote: >> bpf: Tighten cgroup storage cookie checks for prog arrays >> >> The recent KCTF-reported cgroup local storage issue assigned >> CVE-2025-38502 was fixed by commit abad3d0bad72 ("bpf: Fix oob access >> in cgroup local storage"). >> >> However, the previous fixes are still incomplete. The current prog-array >> compatibility check treats a program with no cgroup storage as >> compatible with any stored storage cookie. This allows a storage-less >> program to bridge a tail-call chain between an entry program and a >> storage-using callee even though runtime cgroup local storage still >> follows the caller context. >> >> Require exact per-type storage_cookie equality when checking prog-array >> compatibility. This blocks zero-storage bridge programs from joining a >> prog-array owned by a storage-using program and closes the residual >> A -> B(no storage) -> C(storage) path. >> >> This also aligns with Amery Hung's earlier NULL-storage tail-call fix by >> requiring storage use to match consistently across prog-array users. >> >> Cc: stable@vger.kernel.org >> Fixes: 7d9c3427894f ("bpf: Make cgroup storages shared between programs on the same cgroup") >> Tested-by: Amery Hung <ameryhung@gmail.com> >> Signed-off-by: Lin Ma <malin89@huawei.com> >> Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> >> Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> > Should the Fixes: tag point to abad3d0bad72 instead of 7d9c3427894f? > > The code this patch removes is the '|| !cookie' clause in > __bpf_prog_map_compatible(): > > ret = map->owner->storage_cookie[i] == cookie || > !cookie; > > That permissive '|| !cookie' clause, which treats a storage-less program > as compatible with any stored cookie, was introduced by abad3d0bad72 > ("bpf: Fix oob access in cgroup local storage"). > > The commit referenced by the current tag, 7d9c3427894f ("bpf: Make > cgroup storages shared between programs on the same cgroup"), only added > the shared cgroup-storage feature and does not touch > __bpf_prog_map_compatible() or add the storage_cookie[] check. > > Would this be more accurate? > > Fixes: abad3d0bad72 ("bpf: Fix oob access in cgroup local storage") Agree. The above fix tag seems better. > > This same question was raised on the v1 thread by the bpf-ci review bot > (https://lore.kernel.org/bpf/20260601095158.1186318-1-malin89@huawei.com/), > noting that the patch removes the '|| !cookie' logic introduced in > abad3d0bad72 rather than the original shared storage feature. The reply > disagreed and kept the tag pointing at 7d9c3427894f in v2, but the > reviewer did not acknowledge that explanation, so it may be worth > settling before this is applied. > > --- > 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/26806034423 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks
@ 2026-06-04 1:52 malin (R)
0 siblings, 0 replies; 8+ messages in thread
From: malin (R) @ 2026-06-04 1:52 UTC (permalink / raw)
To: Leon Hwang
Cc: Alexei Starovoitov, Daniel Borkmann, bpf@vger.kernel.org,
Andrii Nakryiko, John Fastabend, Martin KaFai Lau,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
Yonghong Song, Jiri Olsa, YiFei Zhu, Shuah Khan,
linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
Amery Hung, cuirongzhen, tanjingguo, cenxianlong, Chenzhe
Hello Leon,
> These new ones should stay at the tail of test_tailcalls().
My bad, just found this reply.
Will fix that in the next version.
Thanks
Lin
^ permalink raw reply [flat|nested] 8+ messages in threadend of thread, other threads:[~2026-06-04 1:52 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-02 7:35 [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays Lin Ma 2026-06-02 7:35 ` [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks Lin Ma 2026-06-02 8:15 ` bot+bpf-ci 2026-06-02 16:41 ` Yonghong Song 2026-06-03 15:01 ` Leon Hwang 2026-06-02 8:15 ` [PATCH v2 1/2] bpf: Tighten cgroup storage cookie checks for prog arrays bot+bpf-ci 2026-06-02 15:14 ` Yonghong Song -- strict thread matches above, loose matches on Subject: below -- 2026-06-04 1:52 [PATCH v2 2/2] selftests/bpf: Cover tail-call cgroup storage prog-array checks malin (R)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox