Re: [PATCH v2 02/23] bpf: initial support for attaching struct ops to cgroups
From: Roman Gushchin
Date: Tue Oct 28 2025 - 11:57:57 EST
bot+bpf-ci@xxxxxxxxxx writes:
> ```
> commit 31d238f36a0a6a56efa48c847cb776e67ba2f079
> Author: Roman Gushchin <roman.gushchin@xxxxxxxxx>
>
> bpf: initial support for attaching struct ops to cgroups
>
> When a struct ops is being attached and a bpf link is created, allow to
> pass a cgroup fd using bpf attr, so that struct ops can be attached to a
> cgroup instead of globally. Attached struct ops doesn't hold a reference
> to the cgroup, only preserves cgroup id.
>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index eae907218..7205b813e 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -1849,6 +1849,7 @@ struct bpf_struct_ops_link {
>> struct bpf_link link;
>> struct bpf_map __rcu *map;
>> wait_queue_head_t wait_hup;
>> + u64 cgroup_id;
>> };
>>
>> struct bpf_link_primer {
>> diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
>> index 45cc5ee19..58664779a 100644
>> --- a/kernel/bpf/bpf_struct_ops.c
>> +++ b/kernel/bpf/bpf_struct_ops.c
>> @@ -13,6 +13,7 @@
>> #include <linux/btf_ids.h>
>> #include <linux/rcupdate_wait.h>
>> #include <linux/poll.h>
>> +#include <linux/cgroup.h>
>>
>> struct bpf_struct_ops_value {
>> struct bpf_struct_ops_common_value common;
>
> [ ... ]
>
>> @@ -1359,6 +1360,18 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
>> }
>> bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_map_lops, NULL,
>> attr->link_create.attach_type);
>> +#ifdef CONFIG_CGROUPS
>> + if (attr->link_create.cgroup.relative_fd) {
>> + struct cgroup *cgrp;
>> +
>> + cgrp = cgroup_get_from_fd(attr->link_create.cgroup.relative_fd);
>> + if (IS_ERR(cgrp))
>> + return PTR_ERR(cgrp);
> ^^^^^^^^^^^^^^^^^^^^^^
>
> Can this leak the link and map? In bpf_struct_ops_link_create(), the link
> is allocated with kzalloc(GFP_USER) and map is obtained with bpf_map_get()
> before this point. If cgroup_get_from_fd() fails, the early return skips
> the err_out label which does kfree(link) and bpf_map_put(map).
>
> All other error paths in this function use "err = <error>; goto err_out;"
> but this one returns directly.
Ok, this is indeed wrong, will fix in the next version.
Thanks!