Merge remote-tracking branch 'linux-2.6.32.y/master' into develop
[firefly-linux-kernel-4.4.55.git] / kernel / cgroup.c
index 0249f4be9b5cf8fefe9885b6093911746d7a9cdd..29500c8fe8e61faed037b659ce8b08d3b074a934 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/idr.h>
 #include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
+#include <linux/capability.h>
 
 #include <asm/atomic.h>
 
@@ -1555,6 +1556,15 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
                        retval = ss->can_attach(ss, cgrp, tsk, false);
                        if (retval)
                                return retval;
+               } else if (!capable(CAP_SYS_ADMIN)) {
+                       const struct cred *cred = current_cred(), *tcred;
+
+                       /* No can_attach() - check perms generically */
+                       tcred = __task_cred(tsk);
+                       if (cred->euid != tcred->uid &&
+                           cred->euid != tcred->suid) {
+                               return -EACCES;
+                       }
                }
        }
 
@@ -1611,7 +1621,6 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
 {
        struct task_struct *tsk;
-       const struct cred *cred = current_cred(), *tcred;
        int ret;
 
        if (pid) {
@@ -1621,14 +1630,6 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
                        rcu_read_unlock();
                        return -ESRCH;
                }
-
-               tcred = __task_cred(tsk);
-               if (cred->euid &&
-                   cred->euid != tcred->uid &&
-                   cred->euid != tcred->suid) {
-                       rcu_read_unlock();
-                       return -EACCES;
-               }
                get_task_struct(tsk);
                rcu_read_unlock();
        } else {
@@ -2468,7 +2469,6 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
                        /* make sure l doesn't vanish out from under us */
                        down_write(&l->mutex);
                        mutex_unlock(&cgrp->pidlist_mutex);
-                       l->use_count++;
                        return l;
                }
        }