** Changed in: linux (Ubuntu)
Status: Incomplete => Confirmed
--
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1755857
Title:
devpts: handle bind-mounts
Status in linux package in Ubuntu:
Confirmed
Bug description:
Hey everyone,
I sent a few patches to fix a regression caused by wrong behavior in
the devpts filesystem when used with the TIOCGPTPEER ioctl() we
implemented a while back. The context and reproducer can be taken from
my following commit message. The required patches are in Greg's tree
and are:
1.
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-testing&id=7d71109df186d630a41280670c8d71d0cf9b0da9
2.
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-testing&id=a319b01d9095da6f6c54bd20c1f1300762506255
3.
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-testing&id=4e15f760a43c7cb88e2b7ad6882501ccab5de29f
4.
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-testing&id=ce290a19609d5ecd4a240a4750e0ed9a476cf015
devpts: resolve devpts bind-mounts
Most libcs will still look at /dev/ptmx when opening the master fd of a pty
device. When /dev/ptmx is a bind-mount of /dev/pts/ptmx and the TIOCGPTPEER
ioctl() is used to safely retrieve a file descriptor for the slave side of
the pty based on the master fd, the /proc/self/fd/{0,1,2} symlinks will
point to /. A very simply reproducer for this issue presupposing a libc
that uses TIOCGPTPEER in its openpty() implementation is:
unshare --mount
mount --bind /dev/pts/ptmx /dev/ptmx
chmod 666 /dev/ptmx
script
ls -al /proc/self/fd/0
Having bind-mounts of /dev/pts/ptmx to /dev/ptmx not working correctly is a
regression. In addition, it is also a fairly common scenario in containers
employing user namespaces.
The reason for the current failure is that the kernel tries to verify the
useability of the devpts filesystem without resolving the /dev/ptmx
bind-mount first. This will lead it to detect that the dentry is escaping
its bind-mount. The reason is that while the devpts filesystem mounted at
/dev/pts has the devtmpfs mounted at /dev as its parent mount:
21 -- -- / /dev
-- 21 -- / /dev/pts
devtmpfs and devpts are on different devices
-- -- 0:6 / /dev
-- -- 0:20 / /dev/pts
This has the consequence that the pathname of the parent directory of the
devpts filesystem mount at /dev/pts is /. So if /dev/ptmx is a bind-mount
of /dev/pts/ptmx then the /dev/ptmx bind-mount and the devpts mount at
/dev/pts will end up being located on the same device which is recorded in
the superblock of their vfsmount. This means the parent directory of the
/dev/ptmx bind-mount will be /ptmx:
-- -- ---- /ptmx /dev/ptmx
Without the bind-mount resolution patch the kernel will now perform the
bind-mount escape check directly on /dev/ptmx. The function responsible for
this is devpts_ptmx_path() which calls pts_path() which in turn calls
path_parent_directory(). Based on the above explanation,
path_parent_directory() will yield / as the parent directory for the
/dev/ptmx bind-mount and not the expected /dev. Thus, the kernel detects
that /dev/ptmx is escaping its bind-mount and will set /proc/<pid>/fd/<nr>
to /.
This patch changes the logic to first resolve any bind-mounts. After the
bind-mounts have been resolved (i.e. we have traced it back to the
associated devpts mount) devpts_ptmx_path() can be called. In order to
guarantee correct path generation for the slave file descriptor the kernel
now requires that a pts directory is found in the parent directory of the
ptmx bind-mount. This implies that when doing bind-mounts the ptmx
bind-mount and the devpts mount should have a common parent directory. A
valid example is:
mount -t devpts devpts /dev/pts
mount --bind /dev/pts/ptmx /dev/ptmx
an invalid example is:
mount -t devpts devpts /dev/pts
mount --bind /dev/pts/ptmx /ptmx
This allows us to support:
- calling open on ptmx devices located inside non-standard devpts mounts:
mount -t devpts devpts /mnt
master = open("/mnt/ptmx", ...);
slave = ioctl(master, TIOCGPTPEER, ...);
- calling open on ptmx devices located outside the devpts mount with a
common ancestor directory:
mount -t devpts devpts /dev/pts
mount --bind /dev/pts/ptmx /dev/ptmx
master = open("/dev/ptmx", ...);
slave = ioctl(master, TIOCGPTPEER, ...);
while failing on ptmx devices located outside the devpts mount without a
common ancestor directory:
mount -t devpts devpts /dev/pts
mount --bind /dev/pts/ptmx /ptmx
master = open("/ptmx", ...);
slave = ioctl(master, TIOCGPTPEER, ...);
in which case save path generation cannot be guaranteed.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1755857/+subscriptions
--
Mailing list: https://launchpad.net/~kernel-packages
Post to : [email protected]
Unsubscribe : https://launchpad.net/~kernel-packages
More help : https://help.launchpad.net/ListHelp