Zbigniew Jędrzejewski-Szmek dd42fc
From 91dd24f207a5cb93227d4a7d364f033bfd572a31 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek dd42fc
From: Lennart Poettering <lennart@poettering.net>
Zbigniew Jędrzejewski-Szmek dd42fc
Date: Mon, 10 Mar 2014 21:36:01 +0100
Zbigniew Jędrzejewski-Szmek dd42fc
Subject: [PATCH] nspawn: don't try mknod() of /dev/console with the correct
Zbigniew Jędrzejewski-Szmek dd42fc
 major/minor
Zbigniew Jędrzejewski-Szmek dd42fc
Zbigniew Jędrzejewski-Szmek dd42fc
We overmount /dev/console with an external pty anyway, hence there's no
Zbigniew Jędrzejewski-Szmek dd42fc
point in using the real major/minor when we create the node to
Zbigniew Jędrzejewski-Szmek dd42fc
overmount. Instead, use the one of /dev/null now.
Zbigniew Jędrzejewski-Szmek dd42fc
Zbigniew Jędrzejewski-Szmek dd42fc
This fixes a race against the cgroup device controller setup we are
Zbigniew Jędrzejewski-Szmek dd42fc
using. In case /dev/console was create before the cgroup policy was
Zbigniew Jędrzejewski-Szmek dd42fc
applied all was good, but if created in the opposite order the mknod()
Zbigniew Jędrzejewski-Szmek dd42fc
would fail, since creating /dev/console is not allowed by it. Creating
Zbigniew Jędrzejewski-Szmek dd42fc
/dev/null instances is however permitted, and hence use it.
Zbigniew Jędrzejewski-Szmek dd42fc
Zbigniew Jędrzejewski-Szmek dd42fc
(cherry picked from commit eb0f0863f5af48865fb4569e2076d5f9e2313995)
Zbigniew Jędrzejewski-Szmek dd42fc
---
Zbigniew Jędrzejewski-Szmek dd42fc
 src/nspawn/nspawn.c | 25 ++++++++++---------------
Zbigniew Jędrzejewski-Szmek dd42fc
 1 file changed, 10 insertions(+), 15 deletions(-)
Zbigniew Jędrzejewski-Szmek dd42fc
Zbigniew Jędrzejewski-Szmek dd42fc
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
Zbigniew Jędrzejewski-Szmek dd42fc
index 84b7276..091307b 100644
Zbigniew Jędrzejewski-Szmek dd42fc
--- a/src/nspawn/nspawn.c
Zbigniew Jędrzejewski-Szmek dd42fc
+++ b/src/nspawn/nspawn.c
Zbigniew Jędrzejewski-Szmek dd42fc
@@ -852,23 +852,19 @@ static int setup_ptmx(const char *dest) {
Zbigniew Jędrzejewski-Szmek dd42fc
 }
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
 static int setup_dev_console(const char *dest, const char *console) {
Zbigniew Jędrzejewski-Szmek dd42fc
+        _cleanup_umask_ mode_t u;
Zbigniew Jędrzejewski-Szmek dd42fc
+        const char *to;
Zbigniew Jędrzejewski-Szmek dd42fc
         struct stat st;
Zbigniew Jędrzejewski-Szmek dd42fc
-        _cleanup_free_ char *to = NULL;
Zbigniew Jędrzejewski-Szmek dd42fc
         int r;
Zbigniew Jędrzejewski-Szmek dd42fc
-        _cleanup_umask_ mode_t u;
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
         assert(dest);
Zbigniew Jędrzejewski-Szmek dd42fc
         assert(console);
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
         u = umask(0000);
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
-        if (stat(console, &st) < 0) {
Zbigniew Jędrzejewski-Szmek dd42fc
-                log_error("Failed to stat %s: %m", console);
Zbigniew Jędrzejewski-Szmek dd42fc
+        if (stat("/dev/null", &st) < 0) {
Zbigniew Jędrzejewski-Szmek dd42fc
+                log_error("Failed to stat /dev/null: %m");
Zbigniew Jędrzejewski-Szmek dd42fc
                 return -errno;
Zbigniew Jędrzejewski-Szmek dd42fc
-
Zbigniew Jędrzejewski-Szmek dd42fc
-        } else if (!S_ISCHR(st.st_mode)) {
Zbigniew Jędrzejewski-Szmek dd42fc
-                log_error("/dev/console is not a char device");
Zbigniew Jędrzejewski-Szmek dd42fc
-                return -EIO;
Zbigniew Jędrzejewski-Szmek dd42fc
         }
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
         r = chmod_and_chown(console, 0600, 0, 0);
Zbigniew Jędrzejewski-Szmek dd42fc
@@ -877,16 +873,15 @@ static int setup_dev_console(const char *dest, const char *console) {
Zbigniew Jędrzejewski-Szmek dd42fc
                 return r;
Zbigniew Jędrzejewski-Szmek dd42fc
         }
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
-        if (asprintf(&to, "%s/dev/console", dest) < 0)
Zbigniew Jędrzejewski-Szmek dd42fc
-                return log_oom();
Zbigniew Jędrzejewski-Szmek dd42fc
-
Zbigniew Jędrzejewski-Szmek dd42fc
         /* We need to bind mount the right tty to /dev/console since
Zbigniew Jędrzejewski-Szmek dd42fc
          * ptys can only exist on pts file systems. To have something
Zbigniew Jędrzejewski-Szmek dd42fc
-         * to bind mount things on we create a device node first, that
Zbigniew Jędrzejewski-Szmek dd42fc
-         * has the right major/minor (note that the major minor
Zbigniew Jędrzejewski-Szmek dd42fc
-         * doesn't actually matter here, since we mount it over
Zbigniew Jędrzejewski-Szmek dd42fc
-         * anyway). */
Zbigniew Jędrzejewski-Szmek dd42fc
+         * to bind mount things on we create a device node first, and
Zbigniew Jędrzejewski-Szmek dd42fc
+         * use /dev/null for that since we the cgroups device policy
Zbigniew Jędrzejewski-Szmek dd42fc
+         * allows us to create that freely, while we cannot create
Zbigniew Jędrzejewski-Szmek dd42fc
+         * /dev/console. (Note that the major minor doesn't actually
Zbigniew Jędrzejewski-Szmek dd42fc
+         * matter here, since we mount it over anyway). */
Zbigniew Jędrzejewski-Szmek dd42fc
 
Zbigniew Jędrzejewski-Szmek dd42fc
+        to = strappenda(dest, "/dev/console");
Zbigniew Jędrzejewski-Szmek dd42fc
         if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
Zbigniew Jędrzejewski-Szmek dd42fc
                 log_error("mknod() for /dev/console failed: %m");
Zbigniew Jędrzejewski-Szmek dd42fc
                 return -errno;