From ce52399520e4b97466165737e00c7b528ae8c8f5 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Tue, 25 Aug 2015 12:50:44 +1000 Subject: [PATCH] cgroup: pids: fix invalid get/put usage Fix incorrect usage of css_get and css_put to put a different css in pids_{cancel_,}attach() than the one grabbed in pids_can_attach(). This could lead to quite serious memory leakage (and unsafe operations on the putted css). tj: minor comment update Signed-off-by: Aleksa Sarai Signed-off-by: Tejun Heo --- kernel/cgroup_pids.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/kernel/cgroup_pids.c b/kernel/cgroup_pids.c index d75488824ae2..806cd7693ac8 100644 --- a/kernel/cgroup_pids.c +++ b/kernel/cgroup_pids.c @@ -173,11 +173,11 @@ static int pids_can_attach(struct cgroup_subsys_state *css, struct pids_cgroup *old_pids; /* - * Grab a ref to each task's css. We don't drop the ref until - * we either fail and hit ->cancel_attach() or succeed and hit - * ->attach(). + * No need to pin @old_css between here and cancel_attach() + * because cgroup core protects it from being freed before + * the migration completes or fails. */ - old_css = task_get_css(task, pids_cgrp_id); + old_css = task_css(task, pids_cgrp_id); old_pids = css_pids(old_css); pids_charge(pids, 1); @@ -202,19 +202,9 @@ static void pids_cancel_attach(struct cgroup_subsys_state *css, pids_charge(old_pids, 1); pids_uncharge(pids, 1); - css_put(old_css); } } -static void pids_attach(struct cgroup_subsys_state *css, - struct cgroup_taskset *tset) -{ - struct task_struct *task; - - cgroup_taskset_for_each(task, tset) - css_put(task_css(task, pids_cgrp_id)); -} - static int pids_can_fork(struct task_struct *task, void **priv_p) { struct cgroup_subsys_state *css; @@ -354,7 +344,6 @@ static struct cftype pids_files[] = { struct cgroup_subsys pids_cgrp_subsys = { .css_alloc = pids_css_alloc, .css_free = pids_css_free, - .attach = pids_attach, .can_attach = pids_can_attach, .cancel_attach = pids_cancel_attach, .can_fork = pids_can_fork,