From: sashiko-bot@kernel.org
To: "Martin KaFai Lau" <martin.lau@linux.dev>
Cc: bpf@vger.kernel.org
Subject: Re: [RFC PATCH bpf-next 09/12] bpf: Add infrastructure to support attaching struct_ops to cgroups
Date: Tue, 19 May 2026 22:50:02 +0000 [thread overview]
Message-ID: <20260519225002.986EB1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260519215841.2984970-10-martin.lau@linux.dev>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] bpf_cgroup_struct_ops_foreach does not skip dummy items, leading to unintended execution of cfi_stubs.
- [High] Using a loadable module's cfi_stubs as a dummy sentinel causes a Use-After-Free when the module is unloaded and reloaded.
- [Medium] The macro bpf_cgroup_struct_ops_foreach uses rcu_dereference(), which is incompatible with sleepable struct_ops programs.
- [Medium] cgroup_bpf_struct_ops_register() lacks concurrency protection and global uniqueness enforcement.
--
commit bad29e4e0d1357905491993ee45063766d0f7705
Author: Martin KaFai Lau <martin.lau@kernel.org>
bpf: Add infrastructure to support attaching struct_ops to cgroups
This patch adds necessary infrastructure to attach a struct_ops
map to a cgroup. The initial need was to support migrating
the legacy BPF_PROG_TYPE_SOCK_OPS to a struct_ops.
> diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
> index b2e79c2b41d51..8080f4a5c14b6 100644
> --- a/include/linux/bpf-cgroup.h
> +++ b/include/linux/bpf-cgroup.h
[ ... ]
> @@ -110,6 +112,18 @@ struct bpf_prog_list {
> u32 flags;
> };
>
> +#define bpf_cgroup_struct_ops_foreach(var, item, cgrp, atype) \
> + for (item = rcu_dereference((cgrp)->bpf.effective[atype])->items;\
> + ((var) = READ_ONCE(item->kdata)); \
> + item++)
[Severity: High]
Does this macro need to skip dummy sentinel items?
In cgroups with BPF_F_ALLOW_MULTI, compute_effective_progs() inserts dummy
sentinel items at the boundaries between cgroup levels. For struct_ops, this
dummy is the cfi_stubs pointer.
This macro appears to iterate over all non-NULL items and fails to skip the
dummy sentinel, which could cause the subsystem to repeatedly yield the
cfi_stubs pointer as a valid attached struct_ops instance.
[Severity: Medium]
Will this rcu_dereference() trigger Lockdep warnings for sleepable struct_ops
programs?
The commit message mentions adding free_after_mult_rcu_gp to support a mix of
sleepable and non-sleepable struct_ops, but plain rcu_dereference() enforces
rcu_read_lock_held().
If a subsystem iterates the array while holding rcu_read_lock_trace()
(required for sleepable execution), this might trigger a 'suspicious
rcu_dereference_check() usage' warning. Conversely, if it holds
rcu_read_lock(), the struct_ops program cannot sleep without causing a panic.
> +
> +static inline bool cgroup_bpf_is_struct_ops_atype(enum cgroup_bpf_attach_type atype)
> +{
[ ... ]
> diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> index a033aa479ab6e..d496db48d2b86 100644
> --- a/kernel/bpf/cgroup.c
> +++ b/kernel/bpf/cgroup.c
> @@ -24,6 +24,29 @@
> DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE);
> EXPORT_SYMBOL(cgroup_bpf_enabled_key);
>
> +static u32 struct_ops_type_id[MAX_CGROUP_BPF_ATTACH_TYPE];
> +static void *struct_ops_cfi_stubs[MAX_CGROUP_BPF_ATTACH_TYPE];
> +static bool struct_ops_mult_rcu[MAX_CGROUP_BPF_ATTACH_TYPE];
> +
> +void cgroup_bpf_struct_ops_register(int atype, u32 type_id, void *cfi_stubs, bool mult_rcu)
> +{
> + struct_ops_type_id[atype] = type_id;
> + struct_ops_cfi_stubs[atype] = cfi_stubs;
> + struct_ops_mult_rcu[atype] = mult_rcu;
> +}
[Severity: Medium]
Does this registration function need concurrency protection to prevent global
array corruption?
If two modules are loaded concurrently and declare the same cgroup_atype, it
seems this could cause a data race or silently overwrite the registered type_id
and cfi_stubs of a legitimate module.
> +
> +static enum cgroup_bpf_attach_type find_atype_by_struct_ops_id(u32 type_id)
[ ... ]
> static void *bpf_cgroup_array_dummy(enum cgroup_bpf_attach_type atype)
> {
> + if (cgroup_bpf_is_struct_ops_atype(atype))
> + return struct_ops_cfi_stubs[atype];
> return bpf_prog_dummy();
> }
[Severity: High]
Can using a loadable module's cfi_stubs as a dummy sentinel cause a
use-after-free when the module is unloaded and reloaded?
If all maps are detached, the module providing the struct_ops can be unloaded,
and its cfi_stubs memory freed. However, the cgroup's effective array might
still retain the dangling pointer to the freed cfi_stubs if BPF_F_ALLOW_MULTI
was set.
If the module is reloaded, cgroup_bpf_struct_ops_register() updates
struct_ops_cfi_stubs[atype] with a new pointer. If a user then queries the
cgroup via BPF_PROG_QUERY, the loop checks
item->prog == bpf_cgroup_array_dummy(atype) to skip the dummy. Since the
array contains the old freed pointer, it won't match the new cfi_stubs
pointer, and the query loop might mistakenly treat the old dummy as a valid
map, causing a use-after-free when calling bpf_struct_ops_kdata_map_id().
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260519215841.2984970-1-martin.lau@linux.dev?part=9
next prev parent reply other threads:[~2026-05-19 22:50 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-19 21:58 [RFC PATCH bpf-next 00/12] bpf: A common way to attach struct_ops to a cgroup Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 01/12] bpf: Remove __rcu tagging in st_link->map Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 02/12] bpf: Make struct_ops tasks_rcu grace period optional Martin KaFai Lau
2026-05-19 22:54 ` sashiko-bot
2026-05-20 0:25 ` Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 03/12] bpf: Add bpf_struct_ops accessor helpers Martin KaFai Lau
2026-05-19 22:25 ` sashiko-bot
2026-05-19 21:58 ` [RFC PATCH bpf-next 04/12] bpf: Remove unnecessary prog_list_prog() check Martin KaFai Lau
2026-05-19 22:49 ` sashiko-bot
2026-05-19 21:58 ` [RFC PATCH bpf-next 05/12] bpf: Replace prog_list_prog() check with direct pl->prog and pl->link check Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 06/12] bpf: Add prog_list_init_item(), prog_list_replace_item(), and prog_list_id() Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 07/12] bpf: Move LSM trampoline unlink into bpf_cgroup_link_auto_detach() Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 08/12] bpf: Add a few bpf_cgroup_array_* helper functions Martin KaFai Lau
2026-05-19 22:45 ` sashiko-bot
2026-05-19 22:50 ` Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 09/12] bpf: Add infrastructure to support attaching struct_ops to cgroups Martin KaFai Lau
2026-05-19 22:50 ` sashiko-bot [this message]
2026-05-19 23:56 ` Martin KaFai Lau
2026-05-26 17:54 ` Amery Hung
2026-05-26 21:37 ` Martin KaFai Lau
2026-05-26 22:23 ` Amery Hung
2026-05-19 21:58 ` [RFC PATCH bpf-next 10/12] bpf: tcp: Support selected sock_ops callbacks as struct_ops Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 11/12] libbpf: Support attaching struct_ops to a cgroup Martin KaFai Lau
2026-05-19 21:58 ` [RFC PATCH bpf-next 12/12] selftests/bpf: Test " Martin KaFai Lau
2026-05-19 23:03 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260519225002.986EB1F00893@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.