diff mbox series

[1/1] fs/cpio: make initramfs init script survive 'console=' kernel argument

Message ID 80e3e080-0af3-99de-ff8f-9de5e3dca8a6@exertus.fi
State Accepted
Headers show
Series [1/1] fs/cpio: make initramfs init script survive 'console=' kernel argument | expand

Commit Message

Timo Ketola Sept. 23, 2019, 10:58 a.m. UTC
When booting with 'console=<empty>' in the kernel command line (as e.g.
U-Boot does with silent flags in effect), opening /dev/console fails.
That is fatal in the /init script and kernel will panic. It is also
needless, because the kernel tries to open it anyway (well, as long as
we have console node in initramfs /dev; cpio.mk creates that alright).

Signed-off-by: Timo Ketola <timo.ketola@exertus.fi>
---
 fs/cpio/init | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

Comments

Peter Korsgaard Sept. 23, 2019, 1:10 p.m. UTC | #1
>>>>> "Timo" == Timo Ketola <Timo.Ketola@exertus.fi> writes:

 > When booting with 'console=<empty>' in the kernel command line (as e.g.
 > U-Boot does with silent flags in effect), opening /dev/console fails.
 > That is fatal in the /init script and kernel will panic. It is also
 > needless, because the kernel tries to open it anyway (well, as long as
 > we have console node in initramfs /dev; cpio.mk creates that alright).

Also when devtmpfs is used? We manually mount devtmpfs in the initramfs,
so the kernel presumably cannot have opened /dev/console before
executing /init, and we do not add a static device node for
/dev/console.


 > Signed-off-by: Timo Ketola <timo.ketola@exertus.fi>
 > ---
 >  fs/cpio/init | 4 +---
 >  1 file changed, 1 insertion(+), 3 deletions(-)

 > diff --git a/fs/cpio/init b/fs/cpio/init
 > index dbe09ac..72b2401 100755
 > --- a/fs/cpio/init
 > +++ b/fs/cpio/init
 > @@ -1,7 +1,5 @@
 >  #!/bin/sh
 >  # devtmpfs does not get automounted for initramfs
 >  /bin/mount -t devtmpfs devtmpfs /dev
 > -exec 0</dev/console
 > -exec 1>/dev/console
 > -exec 2>/dev/console
 > +
 >  exec /sbin/init "$@"
 > -- 
 > 2.7.4
 > _______________________________________________
 > buildroot mailing list
 > buildroot@busybox.net
 > http://lists.busybox.net/mailman/listinfo/buildroot
Timo Ketola Sept. 23, 2019, 4:55 p.m. UTC | #2
On 23.9.2019 16.10, Peter Korsgaard wrote:
>>>>>> "Timo" == Timo Ketola <Timo.Ketola@exertus.fi> writes:
> 
>  > When booting with 'console=<empty>' in the kernel command line (as e.g.
>  > U-Boot does with silent flags in effect), opening /dev/console fails.
>  > That is fatal in the /init script and kernel will panic. It is also
>  > needless, because the kernel tries to open it anyway (well, as long as
>  > we have console node in initramfs /dev; cpio.mk creates that alright).
> 
> Also when devtmpfs is used? We manually mount devtmpfs in the initramfs,
> so the kernel presumably cannot have opened /dev/console before
> executing /init, and we do not add a static device node for
> /dev/console.

But I thought BR does just that here:

https://git.busybox.net/buildroot/tree/fs/cpio/cpio.mk

line 24, 25
Peter Korsgaard Sept. 23, 2019, 5:07 p.m. UTC | #3
>>>>> "Timo" == Timo Ketola <timo@exertus.fi> writes:

 > On 23.9.2019 16.10, Peter Korsgaard wrote:
 >>>>>>> "Timo" == Timo Ketola <Timo.Ketola@exertus.fi> writes:
 >> 
 >> > When booting with 'console=<empty>' in the kernel command line (as e.g.
 >> > U-Boot does with silent flags in effect), opening /dev/console fails.
 >> > That is fatal in the /init script and kernel will panic. It is also
 >> > needless, because the kernel tries to open it anyway (well, as long as
 >> > we have console node in initramfs /dev; cpio.mk creates that alright).
 >> 
 >> Also when devtmpfs is used? We manually mount devtmpfs in the initramfs,
 >> so the kernel presumably cannot have opened /dev/console before
 >> executing /init, and we do not add a static device node for
 >> /dev/console.

 > But I thought BR does just that here:

 > https://git.busybox.net/buildroot/tree/fs/cpio/cpio.mk

 > line 24, 25

Heh, indeed - I forgot about that logic. Then I guess it is good, unless
something else in the boot sequence doesn't like a missing
stdin/stdout/stderr.
Timo Ketola Sept. 23, 2019, 7:31 p.m. UTC | #4
Peter,

On 23.9.2019 20.07, Peter Korsgaard wrote:
>>>>>> "Timo" == Timo Ketola <timo@exertus.fi> writes:
>  > But I thought BR does just that here:
> 
>  > https://git.busybox.net/buildroot/tree/fs/cpio/cpio.mk
> 
>  > line 24, 25
> 
> Heh, indeed - I forgot about that logic. Then I guess it is good, unless
> something else in the boot sequence doesn't like a missing
> stdin/stdout/stderr.

I think BusyBox's init takes care about that. See my conversation with
Arnout:

http://lists.busybox.net/pipermail/buildroot/2019-September/259889.html

And thanks for looking at this.

--

Timo
Timo Ketola Sept. 24, 2019, 5:24 a.m. UTC | #5
Hi there,

I tested this as per Arnout's suggestion by booting with 'console=' /
'console=ttymxc0,115200' and with / without initramfs. The result
depends only on console setting:

# cat /proc/cmdline; ls -l /proc/1/fd
console=
total 0
lrwx------    1 root     root            64 Sep 24 05:01 0 -> /dev/null
lrwx------    1 root     root            64 Sep 24 05:01 1 -> /dev/null
lrwx------    1 root     root            64 Sep 24 05:01 2 -> /dev/null

# cat /proc/cmdline; ls -l /proc/1/fd
console=ttymxc0,115200
total 0
lrwx------    1 root     root            64 Sep 24 05:20 0 -> /dev/console
lrwx------    1 root     root            64 Sep 24 05:20 1 -> /dev/console
lrwx------    1 root     root            64 Sep 24 05:20 2 -> /dev/console

--

Timo
Timo Ketola Oct. 24, 2019, 7 p.m. UTC | #6
Hi,

Should I do something with this?

--

Timo
Yann E. MORIN April 25, 2020, 12:08 p.m. UTC | #7
Timo, All,

On 2019-09-23 10:58 +0000, Timo Ketola spake thusly:
> When booting with 'console=<empty>' in the kernel command line (as e.g.
> U-Boot does with silent flags in effect), opening /dev/console fails.
> That is fatal in the /init script and kernel will panic. It is also
> needless, because the kernel tries to open it anyway (well, as long as
> we have console node in initramfs /dev; cpio.mk creates that alright).
> 
> Signed-off-by: Timo Ketola <timo.ketola@exertus.fi>

I've applied to master, after extending the commit log with all the gory
details explaininng why we can indeed safely remove those redisrections
now.

Thank you for the patience on this patch.

Thanks also to Peter for helping on IRC about this research.

Regards,
Yann E. MORIN.

> ---
>  fs/cpio/init | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/fs/cpio/init b/fs/cpio/init
> index dbe09ac..72b2401 100755
> --- a/fs/cpio/init
> +++ b/fs/cpio/init
> @@ -1,7 +1,5 @@
>  #!/bin/sh
>  # devtmpfs does not get automounted for initramfs
>  /bin/mount -t devtmpfs devtmpfs /dev
> -exec 0</dev/console
> -exec 1>/dev/console
> -exec 2>/dev/console
> +
>  exec /sbin/init "$@"
> -- 
> 2.7.4
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Peter Korsgaard May 8, 2020, 9:52 a.m. UTC | #8
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:

 > Timo, All,
 > On 2019-09-23 10:58 +0000, Timo Ketola spake thusly:
 >> When booting with 'console=<empty>' in the kernel command line (as e.g.
 >> U-Boot does with silent flags in effect), opening /dev/console fails.
 >> That is fatal in the /init script and kernel will panic. It is also
 >> needless, because the kernel tries to open it anyway (well, as long as
 >> we have console node in initramfs /dev; cpio.mk creates that alright).
 >> 
 >> Signed-off-by: Timo Ketola <timo.ketola@exertus.fi>

 > I've applied to master, after extending the commit log with all the gory
 > details explaininng why we can indeed safely remove those redisrections
 > now.

 > Thank you for the patience on this patch.

 > Thanks also to Peter for helping on IRC about this research.

Committed to 2020.02.x, thanks.
Peter Korsgaard Aug. 20, 2020, 4:42 p.m. UTC | #9
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:

 > Timo, All,
 > On 2019-09-23 10:58 +0000, Timo Ketola spake thusly:
 >> When booting with 'console=<empty>' in the kernel command line (as e.g.
 >> U-Boot does with silent flags in effect), opening /dev/console fails.
 >> That is fatal in the /init script and kernel will panic. It is also
 >> needless, because the kernel tries to open it anyway (well, as long as
 >> we have console node in initramfs /dev; cpio.mk creates that alright).
 >> 
 >> Signed-off-by: Timo Ketola <timo.ketola@exertus.fi>

 > I've applied to master, after extending the commit log with all the gory
 > details explaininng why we can indeed safely remove those redisrections
 > now.

 > Thank you for the patience on this patch.

 > Thanks also to Peter for helping on IRC about this research.

It unfortunately causes a regression :/

I have a setup booting from an initramfs, using devtmpfs, busybox init
and glibc. One of the initscripts used ttyname_r(3) (through the busybox
tty applet), and with this change ttyname_3() fails rather than
returning /dev/console.

Looking at the glibc code, it does a fstat on fd(0), and then compares
st_ino / st_dev (and optionally st_rdev) against all the entries under
/dev.

As the kernel does not mount devtmpfs for us, fd 0 refers to the
/dev/console entry in the rootfs (cpio), but after devtmpfs is mounted,
/dev/console is the entry in the devtmpfs so st_dev / st_ino will no
longer match :/

This logic seems to be added to support containers. See the following
glibc commit:

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>


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

Any great ideas about how we can fix this? I would prefer to not add a
lot of logic in /init, so preferably not having to mount /proc and so
on. If we don't have a good solution, what then? Do we revert or keep it
like this?
diff mbox series

Patch

diff --git a/fs/cpio/init b/fs/cpio/init
index dbe09ac..72b2401 100755
--- a/fs/cpio/init
+++ b/fs/cpio/init
@@ -1,7 +1,5 @@ 
 #!/bin/sh
 # devtmpfs does not get automounted for initramfs
 /bin/mount -t devtmpfs devtmpfs /dev
-exec 0</dev/console
-exec 1>/dev/console
-exec 2>/dev/console
+
 exec /sbin/init "$@"