]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
pam: chown cgroup.procs file on unified hierarchy
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 15 May 2017 23:08:10 +0000 (01:08 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 18 May 2017 17:51:00 +0000 (19:51 +0200)
On the unified hierarchy cgroup.procs must be owned by the user in order for him
to be able to move processes into other cgroups.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
pam/pam_cgfs.c

index b99edff2998d765695b8dcdb04088a25ac795c5e..b4c9e9b1bdbc737136fdb24074849b66fdd15c2a 100644 (file)
@@ -2250,7 +2250,7 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
        char *clean_base_cgroup;
        char *path;
        struct cgv2_hierarchy *v2;
-       bool created = false;
+       bool our_cg = false, created = false;
 
        *existed = false;
 
@@ -2262,10 +2262,9 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
        /* We can't be placed under init's cgroup for the v2 hierarchy. We need
         * to be placed under our current cgroup.
         */
-       if (cg_systemd_chown_existing_cgroup(v2->mountpoint,
-                               v2->base_cgroup, uid, gid,
-                               v2->systemd_user_slice))
-               return true;
+       if (cg_systemd_chown_existing_cgroup(v2->mountpoint, v2->base_cgroup,
+                                            uid, gid, v2->systemd_user_slice))
+               goto chown_cgroup_procs_file;
 
        /* We need to make sure that we do not create an endless chain of
         * sub-cgroups. So we check if we have already logged in somehow (sudo
@@ -2284,14 +2283,18 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
        path = must_make_path(v2->mountpoint, v2->base_cgroup, cgroup, NULL);
        lxcfs_debug("Constructing path \"%s\".\n", path);
        if (file_exists(path)) {
-               bool our_cg = cg_belongs_to_uid_gid(path, uid, gid);
-               lxcfs_debug("%s existed and does %shave our uid: %d and gid: %d.\n", path, our_cg ? "" : "not ", uid, gid);
+               our_cg = cg_belongs_to_uid_gid(path, uid, gid);
+               lxcfs_debug(
+                   "%s existed and does %shave our uid: %d and gid: %d.\n",
+                   path, our_cg ? "" : "not ", uid, gid);
                free(path);
-               if (our_cg)
+               if (our_cg) {
                        *existed = false;
-               else
+                       goto chown_cgroup_procs_file;
+               } else {
                        *existed = true;
-               return our_cg;
+                       return false;
+               }
        }
 
        created = mkdir_p(v2->mountpoint, path);
@@ -2300,10 +2303,27 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
                return false;
        }
 
+       /* chown cgroup to user */
        if (chown(path, uid, gid) < 0)
                mysyslog(LOG_WARNING, "Failed to chown %s to %d:%d: %s.\n",
                         path, (int)uid, (int)gid, strerror(errno), NULL);
-       lxcfs_debug("Chowned %s to %d:%d.\n", path, (int)uid, (int)gid);
+       else
+               lxcfs_debug("Chowned %s to %d:%d.\n", path, (int)uid, (int)gid);
+       free(path);
+
+chown_cgroup_procs_file:
+       /* chown cgroup.procs to user */
+       if (v2->systemd_user_slice)
+               path = must_make_path(v2->mountpoint, v2->base_cgroup,
+                                     "/cgroup.procs", NULL);
+       else
+               path = must_make_path(v2->mountpoint, v2->base_cgroup, cgroup,
+                                     "/cgroup.procs", NULL);
+       if (chown(path, uid, gid) < 0)
+               mysyslog(LOG_WARNING, "Failed to chown %s to %d:%d: %s.\n",
+                        path, (int)uid, (int)gid, strerror(errno), NULL);
+       else
+               lxcfs_debug("Chowned %s to %d:%d.\n", path, (int)uid, (int)gid);
        free(path);
 
        return true;