dotcloud/docker — pull request #5773 by alexlarsson (2014-05-13 12:52:46+00:00)
Title: Make unprivileged systemd work in docker

Currently systemd doesn't work inside a docker container without privileges. It requires CAP_SYS_ADMIN or it will fail to mount the name=systemd cgroup hierarchy, and without this there is just no way to have systemd work.

However, granting CAP_SYS_ADMIN is a very dangerous thing. It allows mounting cgroups, procfs, sysfs or other non-namespaced filesystems which can then be used to get host privileges. For instance, its possible to mount the cgroup device filesystem and move pid 1 out of the devices container, then mknod a /dev/kmem and read arbitrary kernel memory.

Systemd will however work pretty well without any extra privileges if /sys/fs/cgroup/systemd is already mounted, even if no other cgroups are available. This can be done in a pretty safe way, which this patch implements:

First of all we mount a tmpfs on /sys/fs/cgroup (where we can then create the dirs to mount cgroupfs:es). Then we loop over all named cgroup hierarchies in the host (typically only systemd) and bind-mount them read-only into the container. Then, if the container itself is inside a non-root directory in one those filesystems we bind mount that particular subdirectory read-write. For example, we mount `/sys/fs/cgroup/systemd` read-only, and `/sys/fs/cgroup/systemsystem.slice/docker-3a7bd888f18a9fbc66b55114c71be94d72b10b9ffd02f1b12e6551f9c5f87520.scope` read-write. This allows the systemd inside the container to create sub-cgroups and move processes into them, but it does not allow it to escape from the container.

The only weakness with the above is that some features, like PrivateTmp don't work, because they require systemd to mount a /tmp, and that requires CAP_SYS_ADMIN. As long as your container avoids such features it just works.