]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Do not limit bpf_cgroup_from_id to current's namespace
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Mon, 15 Sep 2025 03:26:17 +0000 (03:26 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:36:51 +0000 (15:36 -0500)
[ Upstream commit 2c895133950646f45e5cf3900b168c952c8dbee8 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/cgroup.h
kernel/bpf/helpers.c
kernel/cgroup/cgroup.c

index b18fb5fcb38e239347c1be4b5af9f74f14c767c4..b08c8e62881cd9ecde62927590f565dbae220ddb 100644 (file)
@@ -650,6 +650,7 @@ static inline void cgroup_kthread_ready(void)
 }
 
 void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen);
+struct cgroup *__cgroup_get_from_id(u64 id);
 struct cgroup *cgroup_get_from_id(u64 id);
 #else /* !CONFIG_CGROUPS */
 
index a12f4fa444086e23f6d4ce2d9a992c705f92e8a8..3eb02ce0dba3bc3d4ccc464c758d53f80eb7e1e2 100644 (file)
@@ -2537,7 +2537,7 @@ __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid)
 {
        struct cgroup *cgrp;
 
-       cgrp = cgroup_get_from_id(cgid);
+       cgrp = __cgroup_get_from_id(cgid);
        if (IS_ERR(cgrp))
                return NULL;
        return cgrp;
index 77d02f87f3f121a5d0bc47e4d9d5c1a8d53c7192..c62b98f027f994fef97c29698cc8acab16d3bbae 100644 (file)
@@ -6373,15 +6373,15 @@ void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
 }
 
 /*
- * cgroup_get_from_id : get the cgroup associated with cgroup id
+ * __cgroup_get_from_id : get the cgroup associated with cgroup id
  * @id: cgroup id
  * On success return the cgrp or ERR_PTR on failure
- * Only cgroups within current task's cgroup NS are valid.
+ * There are no cgroup NS restrictions.
  */
-struct cgroup *cgroup_get_from_id(u64 id)
+struct cgroup *__cgroup_get_from_id(u64 id)
 {
        struct kernfs_node *kn;
-       struct cgroup *cgrp, *root_cgrp;
+       struct cgroup *cgrp;
 
        kn = kernfs_find_and_get_node_by_id(cgrp_dfl_root.kf_root, id);
        if (!kn)
@@ -6403,6 +6403,22 @@ struct cgroup *cgroup_get_from_id(u64 id)
 
        if (!cgrp)
                return ERR_PTR(-ENOENT);
+       return cgrp;
+}
+
+/*
+ * cgroup_get_from_id : get the cgroup associated with cgroup id
+ * @id: cgroup id
+ * On success return the cgrp or ERR_PTR on failure
+ * Only cgroups within current task's cgroup NS are valid.
+ */
+struct cgroup *cgroup_get_from_id(u64 id)
+{
+       struct cgroup *cgrp, *root_cgrp;
+
+       cgrp = __cgroup_get_from_id(id);
+       if (IS_ERR(cgrp))
+               return cgrp;
 
        root_cgrp = current_cgns_cgroup_dfl();
        if (!cgroup_is_descendant(cgrp, root_cgrp)) {