This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/22145] ttyname() gives up too early in the face of namespaces


https://sourceware.org/bugzilla/show_bug.cgi?id=22145

--- Comment #11 from Christian Brauner <christian.brauner at mailbox dot org> ---
(In reply to Luke Shumaker from comment #10)
> Hi Christian,
> 
> I'm sorry I didn't CC you, I meant to (I guess that's what I get for
> thinking I can do things at 3 AM).

No worries, I just wanted to point it out for the future. :) The more eyes on
this code the better!

> 
>  >     > lxc-execute -n a5 -- bash
>  >     bash: cannot set terminal process group (1): Inappropriate ioctl for
> device
>  >     bash: no job control in this shell
>  >
>  >     root@a5:/# tty
>  >     /dev/console
> 
> Huh?  From my understanding, either `bash` should not be spitting out
> those errors, or `tty` should also be saying "not a tty"; which is
> what I see with systemd-nspawn:

Stupid question, but did you make sure that you're running a version with
Serge's and my patch in the container?

> 
>     $ sudo systemd-nspawn --register=no --keep-unit -D /path/to/my-container
>     Spawning container my-container on /path/to/my-container.
>     Press ^] three times within 1s to kill container.
>     -bash: cannot set terminal process group (-1): Inappropriate ioctl for
> device
>     -bash: no job control in this shell
>     [root@my-container ~]# tty
>     not a tty
>     [root@my-container ~]# findmnt|grep console
>     │ └─/dev/console                      devpts[/6]                        
> devpts  rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000
>     [root@my-container ~]# ls -al /dev/pts
>     total 0
>     drwxr-xr-x 2 root root    0 Oct  6 14:11 .
>     drwxr-xr-x 5 root root  340 Oct  6 14:11 ..
>     crw-rw-rw- 1 root root 5, 2 Oct  6 14:11 ptmx
> 
> At first I suspected that the difference is maybe you are running an
> older coreutils; and that the commits in 2.28 (937388c 2c622e1) in
> response to you reporting the equivalent issue in coreutils made the
> difference, but I see "not a tty" with both 2.27 and 2.28.  Anyway...

I've actually tried to make the tty program in coreutils sane in that
regard but upstream didn't like it because POSIX. Let's not get
into that. :) What I can tell you is that we've made things a little
better for the tty program but it didn't change anything in how the
output of ttyname{_r}() is shown.

> 
> Because magical TTY reasons that aren't really relevant, Bash needs to
> re-open(2) its TTY on a new FD to set up job control.  It won't do
> anything with it, it will immediately close it after it opens it.  It
> just needs to open it.  First, it tries "/dev/tty", and if that fails,
> it tries opening the path returned by `ttyname(0)`.
> 
> Here's what happened with systemd-nspawn/bash/glibc-2.25:
> 
>   - Bash calls `ttyname(0)` to identify the current TTY.
>   - `ttyname(0)` calls `readlink("/proc/self/fd/0", ...)` and gets
>     `"/6"` (or some other number).
>   - `ttyname(0)` calls `xstat64(..., "/6", ...)`, which fails.
>   - `ttyname(0)` then goes to a fall-back loop over all files
>     `/dev/pts/*` and `/dev/*` checking each to see if it matches our
>     TTY.
>   - `ttyname(0)` eventually comes across `/dev/console` which matches,
>     and returns that.
> 
> Here's what's happening with systemd-nspawn/bash/glibc-2.26:
> 
>   - Bash calls `ttyname(0)` to identify the current TTY.
>   - `ttyname(0)` calls `readlink("/proc/self/fd/0", ...)` and gets
>     `"/6"` (or some other number).
>   - `ttyname(0)` calls `xstat64(..., "/6", ...)`, which fails.
>   - `ttyname(0)` calls `is_pty(...)` to check if FD-0 is a PTY but the
>     device doesn't exist because it's from another namespace (which is
>     the case).
>   - `ttyname(0)` sets `errno=ENODEV` and returns `NULL` because
>     `is_pty(...)` returned true.
> 
> So, within the container, the TTY is named "/dev/console", and with
> glibc 2.25, ttyname() correctly returned "/dev/console", but glibc
> 2.26 ttyname() returns NULL and sets errno=ENODEV.

Thanks! I suggest ignoring differences between systemd-nspawn and liblxc
console setup from now on since the issue clearly should be generally fixed
in bash and glibc.

> 
> ----
> 
> > What your patch does is have ttyname() set ENODEV or have
> > ttyname_r() return ENODEV but in both cases no tty name will be
> > returned. So this presupposes that any program that calls
> > ttyname{_r}() recognizes that ENODEV means "is a tty but no path was
> > found" which is not the case for bash so I'm confused how that would
> > help you get around this problem.
> 
> Wait?  Now I'm confused.  Isn't that what *your* patch does?  My issue
> is that your is_pty()/ENODEV check ran too early, and prevents the old
> fallback search from running.

I'm going to build a glibc with your patch now and take a closer look.
If things look sane and it passes a couple of tests sending around {p,t}ty
fds I think we're good to go.
Bash however, still needs to handle the job control case better because
as you saw jobctl still fails even if /dev/console is correctly detected.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]