Skip to content

Commit 988f1d5

Browse files
kkdwivediKernel Patches Daemon
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. Resolve this by refactoring cgroup_get_from_id to take a parameter to elide the cgroup_is_descendant check when root_cgns parameter is set to true. 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 <[email protected]> Acked-by: Tejun Heo <[email protected]> Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>
1 parent 2a0e5cd commit 988f1d5

File tree

4 files changed

+9
-4
lines changed

4 files changed

+9
-4
lines changed

include/linux/cgroup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +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);
653+
struct cgroup *cgroup_get_from_id(u64 id, bool root_cgns);
654654
#else /* !CONFIG_CGROUPS */
655655

656656
struct cgroup_subsys_state;

kernel/bpf/cgroup_iter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static int bpf_iter_attach_cgroup(struct bpf_prog *prog,
212212
if (fd)
213213
cgrp = cgroup_v1v2_get_from_fd(fd);
214214
else if (id)
215-
cgrp = cgroup_get_from_id(id);
215+
cgrp = cgroup_get_from_id(id, false);
216216
else /* walk the entire hierarchy by default. */
217217
cgrp = cgroup_get_from_path("/");
218218

kernel/bpf/helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,7 @@ __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid)
25372537
{
25382538
struct cgroup *cgrp;
25392539

2540-
cgrp = cgroup_get_from_id(cgid);
2540+
cgrp = cgroup_get_from_id(cgid, true);
25412541
if (IS_ERR(cgrp))
25422542
return NULL;
25432543
return cgrp;

kernel/cgroup/cgroup.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6345,10 +6345,11 @@ void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
63456345
/*
63466346
* cgroup_get_from_id : get the cgroup associated with cgroup id
63476347
* @id: cgroup id
6348+
* @root_cgns: Select root cgroup namespace instead of current's.
63486349
* On success return the cgrp or ERR_PTR on failure
63496350
* Only cgroups within current task's cgroup NS are valid.
63506351
*/
6351-
struct cgroup *cgroup_get_from_id(u64 id)
6352+
struct cgroup *cgroup_get_from_id(u64 id, bool root_cgns)
63526353
{
63536354
struct kernfs_node *kn;
63546355
struct cgroup *cgrp, *root_cgrp;
@@ -6374,6 +6375,10 @@ struct cgroup *cgroup_get_from_id(u64 id)
63746375
if (!cgrp)
63756376
return ERR_PTR(-ENOENT);
63766377

6378+
/* We don't need to namespace this operation against current. */
6379+
if (root_cgns)
6380+
return cgrp;
6381+
63776382
root_cgrp = current_cgns_cgroup_dfl();
63786383
if (!cgroup_is_descendant(cgrp, root_cgrp)) {
63796384
cgroup_put(cgrp);

0 commit comments

Comments
 (0)