summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-06-18 20:15:34 +0200
committerLennart Poettering <lennart@poettering.net>2010-06-18 20:15:34 +0200
commit33be102a214e7010949496549f4c737b0f8269a3 (patch)
treeb44c8395dbcb7737e275de0500e17481b4baf0ee
parent2cb1a60d14f869023652482a380ca7b659dcf78f (diff)
cgroup: make sure the user cannot accidentaly unmount our cgroup filesystem
-rw-r--r--fixme4
-rw-r--r--src/cgroup.c20
-rw-r--r--src/manager.c14
-rw-r--r--src/manager.h5
4 files changed, 27 insertions, 16 deletions
diff --git a/fixme b/fixme
index 23fda7e57e..dfd496d7da 100644
--- a/fixme
+++ b/fixme
@@ -61,14 +61,10 @@
* make systemd bus activatable
-* pin /cgroup/systemd
-
* systemd-sysvinit as package
* install must understand templates
-* upstart fallback in systemctl
-
* abstract namespace dbus socket
* /sbin/shutdown argv[2..] message
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;