From 64747e2d4b6feb61e9f9e70d36ffcf5a972e168a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Jun 2011 00:11:25 +0200 Subject: [PATCH] exec: add ControlGroupModify= switch to allow changing access mode to cgroups fs --- man/systemd.exec.xml | 12 ++++++++++++ src/cgroup.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/cgroup.h | 6 ++++++ src/dbus-execute.h | 6 ++++-- src/execute.c | 13 +++++++++++-- src/execute.h | 2 ++ src/load-fragment.c | 3 ++- 7 files changed, 81 insertions(+), 5 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index ffc257383..b9a37da38 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -629,6 +629,18 @@ for details. + + ControlGroupModify= + Takes a boolean + argument. If true, the control groups + created for this unit will be owned by + ther user specified with + User= (and the + configured group), and he can create + subgroups as well as add processes to + the group. + + CapabilityBoundingSet= diff --git a/src/cgroup.c b/src/cgroup.c index 0c6f20d4b..a3491582b 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -140,6 +140,50 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) { return 0; } +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_group_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_group_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_task_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_task_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { assert(b); assert(sig >= 0); diff --git a/src/cgroup.h b/src/cgroup.h index c6dff4313..f33d8440e 100644 --- a/src/cgroup.h +++ b/src/cgroup.h @@ -59,6 +59,12 @@ void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim); int cgroup_bonding_install(CGroupBonding *b, pid_t pid); int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid); +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s); int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s); diff --git a/src/dbus-execute.h b/src/dbus-execute.h index 56c5bcd4f..49ad6cb82 100644 --- a/src/dbus-execute.h +++ b/src/dbus-execute.h @@ -91,7 +91,8 @@ " \n" \ " \n" \ " \n" \ - " \n" + " \n" \ + " \n" #define BUS_EXEC_COMMAND_INTERFACE(name) \ " \n" @@ -153,7 +154,8 @@ { interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }, \ { interface, "KillMode", bus_execute_append_kill_mode, "s", &(context).kill_mode }, \ { interface, "KillSignal", bus_property_append_int, "i", &(context).kill_signal }, \ - { interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id } + { interface, "UtmpIdentifier", bus_property_append_string, "s", (context).utmp_id }, \ + { interface, "ControlGroupModify", bus_property_append_bool, "b", &(context).control_group_modify } #define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \ { interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \ diff --git a/src/execute.c b/src/execute.c index b00ccde4d..6f0f5d09d 100644 --- a/src/execute.c +++ b/src/execute.c @@ -1246,6 +1246,13 @@ int exec_spawn(ExecCommand *command, r = EXIT_STDIN; goto fail_child; } + + if (cgroup_bondings && context->control_group_modify) + if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 || + cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) { + r = EXIT_CGROUP; + goto fail_child; + } } #ifdef HAVE_PAM @@ -1649,12 +1656,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sWorkingDirectory: %s\n" "%sRootDirectory: %s\n" "%sNonBlocking: %s\n" - "%sPrivateTmp: %s\n", + "%sPrivateTmp: %s\n" + "%sControlGroupModify: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", prefix, c->root_directory ? c->root_directory : "/", prefix, yes_no(c->non_blocking), - prefix, yes_no(c->private_tmp)); + prefix, yes_no(c->private_tmp), + prefix, yes_no(c->control_group_modify)); STRV_FOREACH(e, c->environment) fprintf(f, "%sEnvironment: %s\n", prefix, *e); diff --git a/src/execute.h b/src/execute.h index 55bae24a2..a2d907235 100644 --- a/src/execute.h +++ b/src/execute.h @@ -160,6 +160,8 @@ struct ExecContext { bool non_blocking; bool private_tmp; + bool control_group_modify; + /* This is not exposed to the user but available * internally. We need it to make sure that whenever we spawn * /bin/mount it is run in the same process group as us so diff --git a/src/load-fragment.c b/src/load-fragment.c index 352db6b38..0c2ef9165 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1911,7 +1911,8 @@ static int load_from_path(Unit *u, const char *path) { { "KillMode", config_parse_kill_mode, 0, &(context).kill_mode, section }, \ { "KillSignal", config_parse_kill_signal, 0, &(context).kill_signal, section }, \ { "SendSIGKILL", config_parse_bool, 0, &(context).send_sigkill, section }, \ - { "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section } + { "UtmpIdentifier", config_parse_string_printf, 0, &(context).utmp_id, section }, \ + { "ControlGroupModify", config_parse_bool, 0, &(context).control_group_modify, section } const ConfigItem items[] = { { "Names", config_parse_names, 0, u, "Unit" }, -- 2.30.2