printk: Fix log_buf_copy termination.
[linux-2.6.git] / kernel / cgroup.c
index 5ae71d6..e06035a 100644 (file)
  */
 
 #include <linux/cgroup.h>
+#include <linux/cred.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/init_task.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/mm.h>
@@ -58,8 +60,9 @@
 #include <linux/eventfd.h>
 #include <linux/poll.h>
 #include <linux/flex_array.h> /* used in cgroup_attach_proc */
+#include <linux/capability.h>
 
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 
 static DEFINE_MUTEX(cgroup_mutex);
 
@@ -1514,6 +1517,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                struct cgroup *root_cgrp = &root->top_cgroup;
                struct inode *inode;
                struct cgroupfs_root *existing_root;
+               const struct cred *cred;
                int i;
 
                BUG_ON(sb->s_root != NULL);
@@ -1593,7 +1597,9 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                BUG_ON(!list_empty(&root_cgrp->children));
                BUG_ON(root->number_of_cgroups != 1);
 
+               cred = override_creds(&init_cred);
                cgroup_populate_dir(root_cgrp);
+               revert_creds(cred);
                mutex_unlock(&cgroup_mutex);
                mutex_unlock(&inode->i_mutex);
        } else {
@@ -1837,6 +1843,15 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
                                failed_ss = ss;
                                goto out;
                        }
+               } 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;
+                       }
                }
                if (ss->can_attach_task) {
                        retval = ss->can_attach_task(cgrp, tsk);
@@ -3540,7 +3555,8 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
        }
 
        /* the process need read permission on control file */
-       ret = file_permission(cfile, MAY_READ);
+       /* AV: shouldn't we check that it's been opened for read instead? */
+       ret = inode_permission(cfile->f_path.dentry->d_inode, MAY_READ);
        if (ret < 0)
                goto fail;