moby: /proc/self/fd/{0,1,2} are not valid (with --tty)
This is probably the root cause of #6880 and #8755.
Reproduced on 1.4.1 and 1.5.0.
Steps to reproduce:
$ docker run -ti --rm ubuntu ls -l /proc/self/fd
lrwx------ 1 root root 64 Mar 18 11:32 0 -> /25
lrwx------ 1 root root 64 Mar 18 11:32 1 -> /25
lrwx------ 1 root root 64 Mar 18 11:32 2 -> /25
lr-x------ 1 root root 64 Mar 18 11:32 3 -> /proc/1/fd
Expected: /fd/{0,1,2} symlinks should point to the same thing as docker run -ti --rm ubuntu tty
.
Got: they point to some random point on the root of the filesystem which doesn’t exist.
Effect: This breaks the command tty
(and therefore tmux and various other programs) from a docker exec
into the container. The reason is that readlink(/proc/self/fd/0)
returns a path that doesn’t exist. It also breaks any program which uses /dev/std{in,out,err}
, because these are symlinks to items in the /proc/self/fd/
directory.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 34 (34 by maintainers)
Commits related to this issue
- uspace: Work around reported docker /dev/stdout bug Reportedly, using /dev/stdout as the destination of objcopy fails in a docker container. This may be docker/docker#11462. This reformulation, whi... — committed to LinuxCNC/linuxcnc by jepler 8 years ago
- console: fix "is not a tty" issues The root cause of the issue is this: https://github.com/moby/moby/issues/11462 Since /dev/pts is mounted with newinstance the stdin/stdout of the console you i... — committed to OverC/meta-overc by deleted user 7 years ago
When docker is creating the container, it’s launching the main process with a TTY that was created using the host’s devpts mount. Thus things like
/proc/$pid/fd/0
are pointing to where the TTY is on the host’s devpts mount. Docker isn’t doing any magic here, it’s simply mounting a new devpts inside the container, so its contents don’t match the host’s. Also, docker also doesn’t control where/proc/$pid/fd/$fd
points to. That’s controlled by the kernel./dev/stdin
(and stdout/stderr) however are just vanilla symlinks that point to/proc/self/fd/0
(and 1/2)./proc/$pid/fd/$fd
are "magic"ish. When you open one of these files (talking about the system levelopen()
call), the kernel is duplicating that process’s file descriptor. It’s not resolving the symlink and opening what it points to.The only (yes, only, there is no other) way to solve this (meaning to have
/proc/$pid/fd/$fd
point to valid paths in/dev/pts
) is for the process that docker launches inside the container, to have a TTY that was created using the container’s devpts mount.