[systemd-devel] [PATCH 2/7] Give the user permissions to their session's cgroup

Hristo Venev hristo at venev.name
Sun Dec 1 11:25:53 PST 2013


User is given permissions to their user@*.service cgroup so that user mode
systemd can run. session-*.scope cgroup permissions are required for
session mode.
---
 src/core/dbus-scope.c      |  6 ++++++
 src/core/scope.c           | 16 ++++++++++++++++
 src/core/scope.h           |  2 ++
 src/login/logind-dbus.c    |  5 +++++
 src/login/logind-session.c |  2 +-
 src/login/logind.h         |  2 +-
 6 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
index 13ff49d..fd110e7 100644
--- a/src/core/dbus-scope.c
+++ b/src/core/dbus-scope.c
@@ -106,6 +106,12 @@ static int bus_scope_set_transient_property(
                 }
 
                 return 1;
+        } else if (streq(name, "ChownCgroup")) {
+                r = sd_bus_message_read(message, "(uu)", &s->chown_cgroup_uid, &s->chown_cgroup_gid);
+                if (r < 0)
+                        return r;
+
+                return 1;
         }
 
         return 0;
diff --git a/src/core/scope.c b/src/core/scope.c
index a3c9479..870ea59 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -55,6 +55,9 @@ static void scope_init(Unit *u) {
 
         UNIT(s)->ignore_on_isolate = true;
         UNIT(s)->ignore_on_snapshot = true;
+
+        s->chown_cgroup_uid = getuid();
+        s->chown_cgroup_gid = getgid();
 }
 
 static void scope_done(Unit *u) {
@@ -274,6 +277,19 @@ static int scope_start(Unit *u) {
                 return r;
         }
 
+        if (s->chown_cgroup_uid != getuid() || s->chown_cgroup_gid != getgid()) {
+                r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0644, s->chown_cgroup_uid, s->chown_cgroup_gid);
+                if (r < 0) {
+                        return r;
+                }
+
+
+                r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0755, s->chown_cgroup_uid, s->chown_cgroup_gid);
+                if (r < 0) {
+                        return r;
+                }
+        }
+
         r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, s->pids);
         if (r < 0)
                 return r;
diff --git a/src/core/scope.h b/src/core/scope.h
index 4d8a171..199bf29 100644
--- a/src/core/scope.h
+++ b/src/core/scope.h
@@ -57,6 +57,8 @@ struct Scope {
 
         Set *pids;
 
+        uint32_t chown_cgroup_uid, chown_cgroup_gid;
+
         sd_event_source *timer_event_source;
 };
 
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0461d18..c3518f6 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2181,6 +2181,7 @@ int manager_start_scope(
                 const char *description,
                 const char *after,
                 const char *kill_mode,
+                User *u,
                 sd_bus_error *error,
                 char **job) {
 
@@ -2252,6 +2253,10 @@ int manager_start_scope(
         if (r < 0)
                 return r;
 
+        r = sd_bus_message_append(m, "(sv)", "ChownCgroup", "(uu)", u->uid, u->gid);
+        if (r < 0)
+                return r;
+
         r = sd_bus_message_close_container(m);
         if (r < 0)
                 return r;
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index beaa601..66292ef 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -533,7 +533,7 @@ static int session_start_scope(Session *s) {
 
                 kill_mode = manager_shall_kill(s->manager, s->user->name) ? "control-group" : "none";
 
-                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job);
+                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, s->user, &error, &job);
                 if (r < 0) {
                         log_error("Failed to start session scope %s: %s %s",
                                   scope, bus_error_message(&error, r), error.name);
diff --git a/src/login/logind.h b/src/login/logind.h
index b84137c..cd267ff 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -162,7 +162,7 @@ int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_
 
 int manager_dispatch_delayed(Manager *manager);
 
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *kill_mode, sd_bus_error *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *kill_mode, User *u, sd_bus_error *error, char **job);
 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
-- 
1.8.4.4



More information about the systemd-devel mailing list