Skip to content

Commit 2c89513

Browse files
kkdwvdAlexei Starovoitov
authored andcommitted
bpf: Do not limit bpf_cgroup_from_id to current's namespace
The bpf_cgroup_from_id kfunc relies on cgroup_get_from_id to obtain the cgroup corresponding to a given cgroup ID. This helper can be called in a lot of contexts where the current thread can be random. A recent example was its use in sched_ext's ops.tick(), to obtain the root cgroup pointer. Since the current task can be whatever random user space task preempted by the timer tick, this makes the behavior of the helper unreliable. Refactor out __cgroup_get_from_id as the non-namespace aware version of cgroup_get_from_id, and change bpf_cgroup_from_id to make use of it. There is no compatibility breakage here, since changing the namespace against which the lookup is being done to the root cgroup namespace only permits a wider set of lookups to succeed now. The cgroup IDs across namespaces are globally unique, and thus don't need to be retranslated. Reported-by: Dan Schatzberg <dschatzberg@meta.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/r/20250915032618.1551762-2-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent a9d4e9f commit 2c89513

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

include/linux/cgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ static inline void cgroup_kthread_ready(void)
650650
}
651651

652652
void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen);
653+
struct cgroup *__cgroup_get_from_id(u64 id);
653654
struct cgroup *cgroup_get_from_id(u64 id);
654655
#else /* !CONFIG_CGROUPS */
655656

kernel/bpf/helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2546,7 +2546,7 @@ __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid)
25462546
{
25472547
struct cgroup *cgrp;
25482548

2549-
cgrp = cgroup_get_from_id(cgid);
2549+
cgrp = __cgroup_get_from_id(cgid);
25502550
if (IS_ERR(cgrp))
25512551
return NULL;
25522552
return cgrp;

kernel/cgroup/cgroup.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6343,15 +6343,15 @@ void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
63436343
}
63446344

63456345
/*
6346-
* cgroup_get_from_id : get the cgroup associated with cgroup id
6346+
* __cgroup_get_from_id : get the cgroup associated with cgroup id
63476347
* @id: cgroup id
63486348
* On success return the cgrp or ERR_PTR on failure
6349-
* Only cgroups within current task's cgroup NS are valid.
6349+
* There are no cgroup NS restrictions.
63506350
*/
6351-
struct cgroup *cgroup_get_from_id(u64 id)
6351+
struct cgroup *__cgroup_get_from_id(u64 id)
63526352
{
63536353
struct kernfs_node *kn;
6354-
struct cgroup *cgrp, *root_cgrp;
6354+
struct cgroup *cgrp;
63556355

63566356
kn = kernfs_find_and_get_node_by_id(cgrp_dfl_root.kf_root, id);
63576357
if (!kn)
@@ -6373,6 +6373,22 @@ struct cgroup *cgroup_get_from_id(u64 id)
63736373

63746374
if (!cgrp)
63756375
return ERR_PTR(-ENOENT);
6376+
return cgrp;
6377+
}
6378+
6379+
/*
6380+
* cgroup_get_from_id : get the cgroup associated with cgroup id
6381+
* @id: cgroup id
6382+
* On success return the cgrp or ERR_PTR on failure
6383+
* Only cgroups within current task's cgroup NS are valid.
6384+
*/
6385+
struct cgroup *cgroup_get_from_id(u64 id)
6386+
{
6387+
struct cgroup *cgrp, *root_cgrp;
6388+
6389+
cgrp = __cgroup_get_from_id(id);
6390+
if (IS_ERR(cgrp))
6391+
return cgrp;
63766392

63776393
root_cgrp = current_cgns_cgroup_dfl();
63786394
if (!cgroup_is_descendant(cgrp, root_cgrp)) {

0 commit comments

Comments
 (0)