mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] cgroup: prevent use-after-free during namespace root replacement
@ 2026-09-23 20:49 Jérémy Jean
  2026-09-23 21:05 ` Bradley Morgan
  2026-09-23 23:56 ` Tejun Heo
  0 siblings, 2 replies; 3+ messages in thread
From: Jérémy Jean @ 2026-09-23 20:49 UTC (permalink / raw)
  To: Tejun Heo, Johannes Weiner, Michal Koutný 
  Cc: brads, cgroups, linux-kernel, Jérémy Jean

copy_cgroup_ns() pins the creator's css_set, but cgroup_post_fork()
replaces root_cset and releases the namespace's reference to that css_set
after the child is visible to pid and pidfd lookups. A task joining the
new namespace can race with this replacement and access the original
css_set or its cgroup after they are freed.

KASAN reports:

  BUG: KASAN: slab-use-after-free in kernfs_get.part.0+0x47/0x60
  Write of size 4 at addr ff1100000379f320 by task ns-path-probe/69
   kernfs_walk_and_get_ns+0x1cc/0x280
   cgroup_get_from_path+0xfb/0x340
   nft_socket_cgroup_subtree_level+0x14/0x1a0

Keep the initial root pinned until namespace destruction, taking a
separate reference to the final root only when the roots differ.

Fixes: ef2c41cf38a7 ("clone3: allow spawning processes into cgroups")
Assisted-by: LLM
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
---
 include/linux/cgroup_namespace.h | 2 ++
 kernel/cgroup/cgroup.c           | 9 ++++++---
 kernel/cgroup/namespace.c        | 3 +++
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/linux/cgroup_namespace.h b/include/linux/cgroup_namespace.h
index 78a8418..f36ec1a 100644
--- a/include/linux/cgroup_namespace.h
+++ b/include/linux/cgroup_namespace.h
@@ -9,6 +9,8 @@ struct cgroup_namespace {
 	struct user_namespace	*user_ns;
 	struct ucounts		*ucounts;
 	struct css_set          *root_cset;
+	/* Preserve the root observed before cgroup_post_fork() updates it. */
+	struct css_set		*initial_root_cset;
 };
 
 extern struct cgroup_namespace init_cgroup_ns;
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 227d097..c3cb258 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -247,6 +247,7 @@ struct cgroup_namespace init_cgroup_ns = {
 	.ns		= NS_COMMON_INIT(init_cgroup_ns),
 	.user_ns	= &init_user_ns,
 	.root_cset	= &init_css_set,
+	.initial_root_cset = &init_css_set,
 };
 
 static struct file_system_type cgroup2_fs_type;
@@ -7131,9 +7132,11 @@ void cgroup_post_fork(struct task_struct *child,
 	if (kargs->flags & CLONE_NEWCGROUP) {
 		struct css_set *rcset = child->nsproxy->cgroup_ns->root_cset;
 
-		get_css_set(cset);
-		child->nsproxy->cgroup_ns->root_cset = cset;
-		put_css_set(rcset);
+		/* Both possible roots must remain pinned for namespace readers. */
+		if (rcset != cset) {
+			get_css_set(cset);
+			WRITE_ONCE(child->nsproxy->cgroup_ns->root_cset, cset);
+		}
 	}
 
 	/* Cgroup has to be killed so take down child immediately. */
diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c
index ea4ee13..1153ea4 100644
--- a/kernel/cgroup/namespace.c
+++ b/kernel/cgroup/namespace.c
@@ -37,6 +37,8 @@ void free_cgroup_ns(struct cgroup_namespace *ns)
 {
 	ns_tree_remove(ns);
 	put_css_set(ns->root_cset);
+	if (ns->initial_root_cset != ns->root_cset)
+		put_css_set(ns->initial_root_cset);
 	dec_cgroup_namespaces(ns->ucounts);
 	put_user_ns(ns->user_ns);
 	ns_common_free(ns);
@@ -84,6 +86,7 @@ struct cgroup_namespace *copy_cgroup_ns(u64 flags,
 	new_ns->user_ns = get_user_ns(user_ns);
 	new_ns->ucounts = ucounts;
 	new_ns->root_cset = cset;
+	new_ns->initial_root_cset = cset;
 
 	ns_tree_add(new_ns);
 	return new_ns;
-- 
2.47.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-23 23:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 20:49 [PATCH] cgroup: prevent use-after-free during namespace root replacement Jérémy Jean
2026-09-23 21:05 ` Bradley Morgan
2026-09-23 23:56 ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®