summaryrefslogtreecommitdiff
path: root/src/basic/cgroup-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-09-22 19:58:24 +0200
committerSven Eden <yamakuzure@gmx.net>2017-09-22 19:58:24 +0200
commit346e1907ca4800b8998c40138f9f2c1fcd53891b (patch)
tree576450aba0ea58b3988ff6940c85dba1833c4fab /src/basic/cgroup-util.c
parent4db9ee58f14bba794286d1c9926c18815b02b585 (diff)
cgroup: rework which files we chown() on delegation
On cgroupsv2 we should also chown()/chmod() the subtree_control file, so that children can use controllers the way they like. On cgroupsv1 we should also chown()/chmod() cgroups.clone_children, as not setting this for new cgroups makes little sense, and hence delegated clients should be able to write to it. Note that error handling for both cases is different. subtree_control matters so we check for errors, but the clone_children/tasks stuff doesn't really, as it's legacy stuff. Hence we only log errors and proceed. Fixes: #6216
Diffstat (limited to 'src/basic/cgroup-util.c')
-rw-r--r--src/basic/cgroup-util.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 5fc59d2ef..7d64c6a2b 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -922,7 +922,7 @@ int cg_set_task_access(
uid_t uid,
gid_t gid) {
- _cleanup_free_ char *fs = NULL, *procs = NULL;
+ _cleanup_free_ char *fs = NULL;
int r;
assert(path);
@@ -933,6 +933,7 @@ int cg_set_task_access(
if (mode != MODE_INVALID)
mode &= 0666;
+ /* For both the legacy and unified hierarchies, "cgroup.procs" is the main entry point for PIDs */
r = cg_get_path(controller, path, "cgroup.procs", &fs);
if (r < 0)
return r;
@@ -945,10 +946,37 @@ int cg_set_task_access(
if (r < 0)
return r;
if (r == 0) {
- /* Compatibility, Always keep values for "tasks" in sync with
- * "cgroup.procs" */
- if (cg_get_path(controller, path, "tasks", &procs) >= 0)
- (void) chmod_and_chown(procs, mode, uid, gid);
+ const char *fn;
+
+ /* Compatibility: on cgroupsv1 always keep values for the legacy files "tasks" and
+ * "cgroup.clone_children" in sync with "cgroup.procs". Since this is legacy stuff, we don't care if
+ * this fails. */
+
+ FOREACH_STRING(fn,
+ "tasks",
+ "cgroup.clone_children") {
+
+ fs = mfree(fs);
+
+ r = cg_get_path(controller, path, fn, &fs);
+ if (r < 0)
+ log_debug_errno(r, "Failed to get path for %s of %s, ignoring: %m", fn, path);
+
+ r = chmod_and_chown(fs, mode, uid, gid);
+ if (r < 0)
+ log_debug_errno(r, "Failed to to change ownership/access mode for %s of %s, ignoring: %m", fn, path);
+ }
+ } else {
+ /* On the unified controller, we want to permit subtree controllers too. */
+
+ fs = mfree(fs);
+ r = cg_get_path(controller, path, "cgroup.subtree_control", &fs);
+ if (r < 0)
+ return r;
+
+ r = chmod_and_chown(fs, mode, uid, gid);
+ if (r < 0)
+ return r;
}
r = cg_hybrid_unified();