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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel