]> 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:34:06 +0000 (15:34 -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 fc1324ed597d6b3ebb93387419882110f59291c7..2a510dbbfe623e46ea711640638b0b7997bc778b 100644 (file)
@@ -631,6 +631,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 a0bf39b7359aae3dde3e619fa32c801ad5c2b172..db4739951702e759548e0c9cf2b47a02429f4ebb 100644 (file)
@@ -2455,7 +2455,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 5fc2801ee921ccfbef5e3a7ab8a08c5c00ca5b78..b8cde3d1cb7bc9ea30a7cf7e097cebd6b05a3132 100644 (file)
@@ -6343,15 +6343,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)
@@ -6373,6 +6373,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)) {