aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/memcontrol.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6bcb096fd..b843aeeb3 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -7000,6 +7000,23 @@ static void mem_cgroup_move_task(struct cgroup *cont,
}
#endif
+static int mem_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_ADMIN) &&
+ cred->euid != tcred->uid && cred->euid != tcred->suid)
+ return -EACCES;
+ }
+
+ return 0;
+}
+
/*
* Cgroup retains root cgroups across [un]mount cycles making it necessary
* to verify sane_behavior flag on each mount attempt.
@@ -7025,6 +7042,7 @@ struct cgroup_subsys mem_cgroup_subsys = {
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
+ .allow_attach = mem_cgroup_allow_attach,
.bind = mem_cgroup_bind,
.base_cftypes = mem_cgroup_files,
.disabled = 1, /* Disable it for performance workaround */