diff options
author | Amit Pundir <amit.pundir@linaro.org> | 2015-07-23 02:40:24 +0530 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2015-07-23 02:46:58 +0530 |
commit | 73fadb7e9b120bc06eca850db692bd3eff44ea19 (patch) | |
tree | 86178d270d8b4cade7674cdd046a0c3080f03fab | |
parent | f30d4e53b77064d2c03d98ab68534dfd8222e8ec (diff) |
cgroup: fix AOSP's cgroup subsys permission checktracking-linaro-android-llct-llct-20150723.1tracking-linaro-android-llct-llct-20150723.0
Mainline commit dedf22e9e66e "cgroup: separate out
cgroup_procs_write_permission() from __cgroup_procs_write()",
moved out task/process migration permission check from
__cgroup_procs_write() into cgroup_procs_write_permission().
Hence reformat the changes from AOSP commit 53b5e2f0b1ce
"cgroup: Add generic cgroup subsystem permission checks"
accordingly.
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
-rw-r--r-- | kernel/cgroup.c | 121 |
1 files changed, 55 insertions, 66 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 3600ad26eb15..3ac877b59e85 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2390,6 +2390,44 @@ static int cgroup_attach_task(struct cgroup *dst_cgrp, return ret; } +int subsys_cgroup_allow_attach(struct cgroup_subsys_state *css, 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, tset) { + tcred = __task_cred(task); + + if (current != task && !uid_eq(cred->euid, tcred->uid) && + !uid_eq(cred->euid, tcred->suid)) + return -EACCES; + } + + return 0; +} + +static int cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) +{ + struct cgroup_subsys_state *css; + int i; + int ret; + + for_each_css(css, i, cgrp) { + if (css->ss->allow_attach) { + ret = css->ss->allow_attach(css, tset); + if (ret) + return ret; + } else { + return -EACCES; + } + } + + return 0; +} + static int cgroup_procs_write_permission(struct task_struct *task, struct cgroup *dst_cgrp, struct kernfs_open_file *of) @@ -2404,8 +2442,23 @@ static int cgroup_procs_write_permission(struct task_struct *task, */ if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && !uid_eq(cred->euid, tcred->uid) && - !uid_eq(cred->euid, tcred->suid)) - ret = -EACCES; + !uid_eq(cred->euid, tcred->suid)) { + /* + * if the default permission check fails, give each + * cgroup a chance to extend the permission check + */ + struct cgroup_taskset tset = { + .src_csets = LIST_HEAD_INIT(tset.src_csets), + .dst_csets = LIST_HEAD_INIT(tset.dst_csets), + .csets = &tset.src_csets, + }; + struct css_set *cset; + cset = task_css_set(task); + list_add(&cset->mg_node, &tset.src_csets); + ret = cgroup_allow_attach(dst_cgrp, &tset); + if (ret) + ret = -EACCES; + } if (!ret && cgroup_on_dfl(dst_cgrp)) { struct super_block *sb = of->file->f_path.dentry->d_sb; @@ -2431,44 +2484,6 @@ static int cgroup_procs_write_permission(struct task_struct *task, return ret; } -int subsys_cgroup_allow_attach(struct cgroup_subsys_state *css, 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, tset) { - tcred = __task_cred(task); - - if (current != task && !uid_eq(cred->euid, tcred->uid) && - !uid_eq(cred->euid, tcred->suid)) - return -EACCES; - } - - return 0; -} - -static int cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) -{ - struct cgroup_subsys_state *css; - int i; - int ret; - - for_each_css(css, i, cgrp) { - if (css->ss->allow_attach) { - ret = css->ss->allow_attach(css, tset); - if (ret) - return ret; - } else { - 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 @@ -2497,32 +2512,6 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, ret = -ESRCH; goto out_unlock_rcu; } - /* - * even if we're attaching all tasks in the thread group, we - * only need to check permissions on one of them. - */ - tcred = __task_cred(tsk); - if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && - !uid_eq(cred->euid, tcred->uid) && - !uid_eq(cred->euid, tcred->suid)) { - /* - * if the default permission check fails, give each - * cgroup a chance to extend the permission check - */ - struct cgroup_taskset tset = { - .src_csets = LIST_HEAD_INIT(tset.src_csets), - .dst_csets = LIST_HEAD_INIT(tset.dst_csets), - .csets = &tset.src_csets, - }; - struct css_set *cset; - cset = task_css_set(tsk); - list_add(&cset->mg_node, &tset.src_csets); - ret = cgroup_allow_attach(cgrp, &tset); - if (ret) { - rcu_read_unlock(); - goto out_unlock_cgroup; - } - } } else { tsk = current; } |