From 57114e95e8c4f5035c993fc74bbe94cd9573f1bb Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Fri, 7 Nov 2014 12:48:17 -0800 Subject: [PATCH] cgroup: refactor allow_attach function into common code move cpu_cgroup_allow_attach to a common subsys_cgroup_allow_attach. This allows any process with CAP_SYS_NICE to move tasks across cgroups if they use this function as their allow_attach handler. Bug: 18260435 Change-Id: I6bb4933d07e889d0dc39e33b4e71320c34a2c90f Signed-off-by: Rom Lemarchand --- include/linux/cgroup.h | 16 ++++++++++++++++ kernel/cgroup.c | 19 +++++++++++++++++++ kernel/sched/core.c | 19 +------------------ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 8f73d835d4d5..a2bcbd2e0f9a 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -831,6 +831,17 @@ unsigned short css_id(struct cgroup_subsys_state *css); unsigned short css_depth(struct cgroup_subsys_state *css); struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id); +/* + * Default Android check for whether the current process is allowed to move a + * task across cgroups, either because CAP_SYS_NICE is set or because the uid + * of the calling process is the same as the moved task or because we are + * running as root. + * Returns 0 if this is allowed, or -EACCES otherwise. + */ +int subsys_cgroup_allow_attach(struct cgroup *cgrp, + struct cgroup_taskset *tset); + + #else /* !CONFIG_CGROUPS */ static inline int cgroup_init_early(void) { return 0; } @@ -854,6 +865,11 @@ static inline int cgroup_attach_task_all(struct task_struct *from, return 0; } +static inline int subsys_cgroup_allow_attach(struct cgroup *cgrp, + struct cgroup_taskset *tset) +{ + return 0; +} #endif /* !CONFIG_CGROUPS */ #endif /* _LINUX_CGROUP_H */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 1f5338773862..8dc7ec1de429 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2116,6 +2116,25 @@ static int cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) return 0; } +int subsys_cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) +{ + const struct cred *cred = current_cred(), *tcred; + struct task_struct *task; + + if (capable(CAP_SYS_NICE)) + return 0; + + cgroup_taskset_for_each(task, cgrp, tset) { + tcred = __task_cred(task); + + if (current != task && cred->euid != tcred->uid && + cred->euid != tcred->suid) + return -EACCES; + } + + return 0; +} + /* * Find the task_struct of the task to attach by vpid and pass it along to the * function to attach either it or all tasks in its threadgroup. Will lock diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 014040fa3d21..d5c5c9824511 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7716,23 +7716,6 @@ static void cpu_cgroup_css_offline(struct cgroup *cgrp) sched_offline_group(tg); } -static int -cpu_cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) -{ - const struct cred *cred = current_cred(), *tcred; - struct task_struct *task; - - cgroup_taskset_for_each(task, cgrp, tset) { - tcred = __task_cred(task); - - if ((current != task) && !capable(CAP_SYS_NICE) && - cred->euid != tcred->uid && cred->euid != tcred->suid) - return -EACCES; - } - - return 0; -} - static int cpu_cgroup_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) { @@ -8092,7 +8075,7 @@ struct cgroup_subsys cpu_cgroup_subsys = { .css_offline = cpu_cgroup_css_offline, .can_attach = cpu_cgroup_can_attach, .attach = cpu_cgroup_attach, - .allow_attach = cpu_cgroup_allow_attach, + .allow_attach = subsys_cgroup_allow_attach, .exit = cpu_cgroup_exit, .subsys_id = cpu_cgroup_subsys_id, .base_cftypes = cpu_files, -- 2.34.1