chiark / gitweb /
nspawn: make /dev/kmsg unavailable in the container, but allow access to /proc/kmsg
[elogind.git] / src / nspawn / nspawn.c
index 9fc256e51d073f73d34664e4139b5a4cda36f41a..71cdd3f39f27e23ab248dc84058ccf437f2f7399 100644 (file)
@@ -38,6 +38,8 @@
 #include <sys/signalfd.h>
 #include <grp.h>
 #include <linux/fs.h>
 #include <sys/signalfd.h>
 #include <grp.h>
 #include <linux/fs.h>
+#include <sys/un.h>
+#include <sys/socket.h>
 
 #include <systemd/sd-daemon.h>
 
 
 #include <systemd/sd-daemon.h>
 
@@ -392,6 +394,13 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
 
         u = umask(0000);
 
 
         u = umask(0000);
 
+        /* We create the kmsg FIFO as /dev/kmsg, but immediately
+         * delete it after bind mounting it to /proc/kmsg. While FIFOs
+         * on the reading side behave very similar to /proc/kmsg,
+         * their writing side behaves differently from /dev/kmsg in
+         * that writing blocks when nothing is reading. In order to
+         * avoid any problems with containers deadlocking due to this
+         * we simply make /dev/kmsg unavailable to the container. */
         if (asprintf(&from, "%s/dev/kmsg", dest) < 0) {
                 log_error("Out of memory");
                 r = -ENOMEM;
         if (asprintf(&from, "%s/dev/kmsg", dest) < 0) {
                 log_error("Out of memory");
                 r = -ENOMEM;
@@ -454,6 +463,9 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
                 goto finish;
         }
 
                 goto finish;
         }
 
+        /* And now make the FIFO unavailable as /dev/kmsg... */
+        unlink(from);
+
 finish:
         free(from);
         free(to);
 finish:
         free(from);
         free(to);
@@ -926,7 +938,7 @@ int main(int argc, char *argv[]) {
                     dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
                         goto child_fail;
 
                     dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
                         goto child_fail;
 
-                if (mount(arg_directory, "/", "bind", MS_BIND|MS_MOVE, NULL) < 0) {
+                if (mount(arg_directory, "/", "bind", MS_BIND, NULL) < 0) {
                         log_error("mount(MS_MOVE) failed: %m");
                         goto child_fail;
                 }
                         log_error("mount(MS_MOVE) failed: %m");
                         goto child_fail;
                 }