diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-06-18 20:15:34 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-06-18 20:15:34 +0200 |
commit | 33be102a214e7010949496549f4c737b0f8269a3 (patch) | |
tree | b44c8395dbcb7737e275de0500e17481b4baf0ee /src | |
parent | 2cb1a60d14f869023652482a380ca7b659dcf78f (diff) |
cgroup: make sure the user cannot accidentaly unmount our cgroup filesystem
Diffstat (limited to 'src')
-rw-r--r-- | src/cgroup.c | 20 | ||||
-rw-r--r-- | src/manager.c | 14 | ||||
-rw-r--r-- | src/manager.h | 5 |
3 files changed, 27 insertions, 12 deletions
diff --git a/src/cgroup.c b/src/cgroup.c index 108c4fcf5e..291db4e6c9 100644 --- a/src/cgroup.c +++ b/src/cgroup.c @@ -407,7 +407,7 @@ finish: } int manager_setup_cgroup(Manager *m) { - char *mp, *cp; + char *cp; int r; pid_t pid; char suffix[32]; @@ -423,15 +423,15 @@ int manager_setup_cgroup(Manager *m) { if (!(m->cgroup_controller = strdup("name=systemd"))) return -ENOMEM; - if ((r = cgroup_get_subsys_mount_point(m->cgroup_controller, &mp))) + free(m->cgroup_mount_point); + m->cgroup_mount_point = NULL; + if ((r = cgroup_get_subsys_mount_point(m->cgroup_controller, &m->cgroup_mount_point))) return translate_error(r, errno); pid = getpid(); - if ((r = cgroup_get_current_controller_path(pid, m->cgroup_controller, &cp))) { - free(mp); + if ((r = cgroup_get_current_controller_path(pid, m->cgroup_controller, &cp))) return translate_error(r, errno); - } snprintf(suffix, sizeof(suffix), "/systemd-%u", (unsigned) pid); char_array_0(suffix); @@ -448,24 +448,20 @@ int manager_setup_cgroup(Manager *m) { r = asprintf(&m->cgroup_hierarchy, "%s%s", streq(cp, "/") ? "" : cp, suffix); free(cp); - if (r < 0) { - free(mp); + if (r < 0) return -ENOMEM; - } } log_debug("Using cgroup controller <%s>, hierarchy mounted at <%s>, using root group <%s>.", m->cgroup_controller, - mp, + m->cgroup_mount_point, m->cgroup_hierarchy); - if ((r = install_release_agent(m, mp)) < 0) + if ((r = install_release_agent(m, m->cgroup_mount_point)) < 0) log_warning("Failed to install release agent, ignoring: %s", strerror(-r)); else log_debug("Installed release agent, or already installed."); - free(mp); - if ((r = create_hierarchy_cgroup(m)) < 0) log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); else diff --git a/src/manager.c b/src/manager.c index c93b7912eb..5e627ba9c6 100644 --- a/src/manager.c +++ b/src/manager.c @@ -197,6 +197,7 @@ static int manager_setup_signals(Manager *m) { int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) { Manager *m; int r = -ENOMEM; + char *p; assert(_m); assert(running_as >= 0); @@ -211,6 +212,7 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) { m->confirm_spawn = confirm_spawn; m->name_data_slot = -1; m->exit_code = _MANAGER_EXIT_CODE_INVALID; + m->pin_cgroupfs_fd = -1; m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1; m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ @@ -256,6 +258,14 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) { (r = bus_init_api(m)) < 0) goto fail; + if (asprintf(&p, "%s/%s", m->cgroup_mount_point, m->cgroup_hierarchy) < 0) { + r = -ENOMEM; + goto fail; + } + + m->pin_cgroupfs_fd = open(p, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); + free(p); + *_m = m; return 0; @@ -446,9 +456,13 @@ void manager_free(Manager *m) { free(m->cgroup_controller); free(m->cgroup_hierarchy); + free(m->cgroup_mount_point); hashmap_free(m->cgroup_bondings); + if (m->pin_cgroupfs_fd >= 0) + close_nointr_nofail(m->pin_cgroupfs_fd); + free(m); } diff --git a/src/manager.h b/src/manager.h index 405f143566..762a891ca6 100644 --- a/src/manager.h +++ b/src/manager.h @@ -167,12 +167,17 @@ struct Manager { /* Data specific to the cgroup subsystem */ Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ char *cgroup_controller; + char *cgroup_mount_point; char *cgroup_hierarchy; usec_t gc_queue_timestamp; int gc_marker; unsigned n_in_gc_queue; + /* Make sure the user cannot accidentaly unmount our cgroup + * file system */ + int pin_cgroupfs_fd; + /* Flags */ ManagerRunningAs running_as; ManagerExitCode exit_code:4; |