[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