]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - kernel/cgroup/cgroup-v1.c
cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv
[mirror_ubuntu-focal-kernel.git] / kernel / cgroup / cgroup-v1.c
index 5e465c4b1e64c2bb9c812c270db7bf7ad79f164a..117d70098cd49aa3d5d0ea9fafc3681b61c97ace 100644 (file)
@@ -398,6 +398,7 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
         * next pid to display, if any
         */
        struct kernfs_open_file *of = s->private;
+       struct cgroup_file_ctx *ctx = of->priv;
        struct cgroup *cgrp = seq_css(s)->cgroup;
        struct cgroup_pidlist *l;
        enum cgroup_filetype type = seq_cft(s)->private;
@@ -407,25 +408,24 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
        mutex_lock(&cgrp->pidlist_mutex);
 
        /*
-        * !NULL @of->priv indicates that this isn't the first start()
-        * after open.  If the matching pidlist is around, we can use that.
-        * Look for it.  Note that @of->priv can't be used directly.  It
-        * could already have been destroyed.
+        * !NULL @ctx->procs1.pidlist indicates that this isn't the first
+        * start() after open. If the matching pidlist is around, we can use
+        * that. Look for it. Note that @ctx->procs1.pidlist can't be used
+        * directly. It could already have been destroyed.
         */
-       if (of->priv)
-               of->priv = cgroup_pidlist_find(cgrp, type);
+       if (ctx->procs1.pidlist)
+               ctx->procs1.pidlist = cgroup_pidlist_find(cgrp, type);
 
        /*
         * Either this is the first start() after open or the matching
         * pidlist has been destroyed inbetween.  Create a new one.
         */
-       if (!of->priv) {
-               ret = pidlist_array_load(cgrp, type,
-                                        (struct cgroup_pidlist **)&of->priv);
+       if (!ctx->procs1.pidlist) {
+               ret = pidlist_array_load(cgrp, type, &ctx->procs1.pidlist);
                if (ret)
                        return ERR_PTR(ret);
        }
-       l = of->priv;
+       l = ctx->procs1.pidlist;
 
        if (pid) {
                int end = l->length;
@@ -453,7 +453,8 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
 static void cgroup_pidlist_stop(struct seq_file *s, void *v)
 {
        struct kernfs_open_file *of = s->private;
-       struct cgroup_pidlist *l = of->priv;
+       struct cgroup_file_ctx *ctx = of->priv;
+       struct cgroup_pidlist *l = ctx->procs1.pidlist;
 
        if (l)
                mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork,
@@ -464,7 +465,8 @@ static void cgroup_pidlist_stop(struct seq_file *s, void *v)
 static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct kernfs_open_file *of = s->private;
-       struct cgroup_pidlist *l = of->priv;
+       struct cgroup_file_ctx *ctx = of->priv;
+       struct cgroup_pidlist *l = ctx->procs1.pidlist;
        pid_t *p = v;
        pid_t *end = l->list + l->length;
        /*
@@ -507,10 +509,11 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of,
                goto out_unlock;
 
        /*
-        * Even if we're attaching all tasks in the thread group, we only
-        * need to check permissions on one of them.
+        * Even if we're attaching all tasks in the thread group, we only need
+        * to check permissions on one of them. Check permissions using the
+        * credentials from file open to protect against inherited fd attacks.
         */
-       cred = current_cred();
+       cred = of->file->f_cred;
        tcred = get_task_cred(task);
        if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) &&
            !uid_eq(cred->euid, tcred->uid) &&