All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Korsgaard <peter@korsgaard.com>
To: buildroot@busybox.net
Subject: [Buildroot] [PATCH] fs/cpio/init: unbreak ttyname_r() on glibc after dropping /dev/console exec
Date: Sat, 29 Aug 2020 15:09:11 +0200	[thread overview]
Message-ID: <20200829130911.19760-1-peter@korsgaard.com> (raw)

Commit 98a6f1fc02e41 (fs/cpio: make initramfs init script survive 'console='
kernel argument) dropped the explicit /dev/console execs for fd 0,1,2, as
they fail when booted with console= and aren't really needed as the kernel
will setup fd 0,1,2 from /dev/console before executing the initramfs anyway.

Not doing this unfortunately confuses glibc's ttyname_r(3) implementation
(used by E.G.  busybox/coreutils 'tty'), causing it to fail with ENOENT as
it does a fstat on fd 0 and tries to match up st_ino / st_dev against the
entries in /dev (since glibc 2.26):

 commit 15e9a4f378c8607c2ae1aa465436af4321db0e23
 Author: Christian Brauner <christian.brauner@canonical.com>
 Date:   Fri Jan 27 15:59:59 2017 +0100

    linux ttyname and ttyname_r: do not return wrong results

    If a link (say /proc/self/fd/0) pointing to a device, say /dev/pts/2, in a
    parent mount namespace is passed to ttyname, and a /dev/pts/2 exists (in a
    different devpts) in the current namespace, then it returns /dev/pts/2.
    But /dev/pts/2 is NOT the current tty, it is a different file and device.

    Detect this case and return ENODEV.  Userspace can choose to take this as a hint
    that the fd points to a tty device but to act on the fd rather than the link.

    Signed-off-by: Serge Hallyn <serge@hallyn.com>
    Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>

The reason it fails is that we manually mount devtmpfs on /dev in /init, so
the /dev/console used by the kernel (in rootfs) is not the same file as
/dev/console at runtime (in devtmpfs).

Notice: Once logged in, tty does work correctly.  Presumably login reopens
stdin/stdout/stderr.

To fix this, re-add the exec of /dev/console for fd 0,1,2, but only do so if
possible.  Because of the above mentioned shell behaviour (specified by
POSIX [0]), perform this check in a subshell.

[0] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_20_01

Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
 fs/cpio/init | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/cpio/init b/fs/cpio/init
index b0af18b67a..f74ef7e15f 100755
--- a/fs/cpio/init
+++ b/fs/cpio/init
@@ -1,4 +1,15 @@
 #!/bin/sh
 # devtmpfs does not get automounted for initramfs
 /bin/mount -t devtmpfs devtmpfs /dev
+
+# use the /dev/console device node from devtmpfs if possible to not
+# confuse glibc's ttyname_r().
+# This may fail (E.G. booted with console=), and errors from exec will
+# terminate the shell, so use a subshell for the test
+if (exec 0</dev/console) 2>/dev/null; then
+    exec 0</dev/console
+    exec 1>/dev/console
+    exec 2>/dev/console
+fi
+
 exec /sbin/init "$@"
-- 
2.20.1

             reply	other threads:[~2020-08-29 13:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-29 13:09 Peter Korsgaard [this message]
2020-08-29 13:24 ` [Buildroot] [PATCH] fs/cpio/init: unbreak ttyname_r() on glibc after dropping /dev/console exec Yann E. MORIN
2020-08-29 13:40   ` Peter Korsgaard
2020-08-29 14:43 ` Yann E. MORIN
2020-08-29 17:40 ` Peter Korsgaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200829130911.19760-1-peter@korsgaard.com \
    --to=peter@korsgaard.com \
    --cc=buildroot@busybox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.