[PATCH] cgroups: call find_css_set() safely in cgroup_attach_task()

Lai Jiangshan laijs at cn.fujitsu.com
Fri Nov 21 00:49:59 PST 2008


in cgroup_attach_task(), tsk maybe exit when we call find_css_set().
and find_css_set() will access to invalid css_set.

this patch increase the count before get_css_set(), and decrease it
after find_css_set().

NOTICE:
css_set's refcount is also taskcount, after this patch applied, taskcount
may be off-by-one WHEN cgroup_lock() is not held.
but I reviewed other code which use taskcount, they are still correct.
No regression found by reviewing and simply testing.

So I do not use two counters in css_set.
(one counter for taskcount, the other for refcount. like struct mm_struct)
If this fix cause regression, we will use two counters in css_set.

Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
---
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 358e775..ddc10ac 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1217,7 +1222,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 	int retval = 0;
 	struct cgroup_subsys *ss;
 	struct cgroup *oldcgrp;
-	struct css_set *cg = tsk->cgroups;
+	struct css_set *cg;
 	struct css_set *newcg;
 	struct cgroupfs_root *root = cgrp->root;
 	int subsys_id;
@@ -1237,11 +1242,16 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 		}
 	}
 
+	task_lock(tsk);
+	cg = tsk->cgroups;
+	get_css_set(cg);
+	task_unlock(tsk);
 	/*
 	 * Locate or allocate a new css_set for this task,
 	 * based on its final set of cgroups
 	 */
 	newcg = find_css_set(cg, cgrp);
+	put_css_set(cg);
 	if (!newcg)
 		return -ENOMEM;
 





More information about the Containers mailing list