Package: schroot Version: 1.6.10-3 Severity: normal Tags: upstream As documented in <http://lxr.free-electrons.com/source/Documentation/filesystems/devpts.txt?v=3.16> and in <https://www.kernel.org/doc/Documentation/filesystems/devpts.txt> (for historical context you might want to read the v3.16 version, chosen to represent Debian jessie, before the latest version), the preferred way to set up /dev/pts inside containers in recent kernels is to mount a new instance of the devpts filesystem on /dev/pts, either use ptmxmode=666 or chmod /dev/pts/ptmx to 0666 afterwards, and arrange for /dev/ptmx to be equivalent to /dev/pts/ptmx via a symbolic link or bind-mount.
In particular, this would make the chroots created by debootstrap versions 1.0.76 to 1.0.88 (inclusive) work as expected. In those chroots, /dev/ptmx is a symbolic link to pts/ptmx. That is considered to be a RC bug in debootstrap (#817236, RC because it broke existing functionality), and I have proposed a patch; but with my proposed patch, debootstrap will still create chroots with /dev/ptmx -> pts/ptmx if it is run in a container manager that restricts device node creation, such as systemd-nspawn, because that seemed better than failing outright. Invoking script(1) is a common way to test this. A nice side-effect of this change, which I discovered while testing a cut-down version of the same code in a new debootstrap autopkgtest, is that it makes script(1) work inside "schroot --sbuild" inside a LXC container on a Debian jessie kernel. Previously, that would have failed. I'm filing this as a new bug rather than detaching one of the merged bugs from #817236 because the only one that originally concerned schroot was #817236 itself, and it would seem needlessly confusing to repurpose that bug number. I attach a schroot patch that does as I request. I'm also going to attach a patch to #817236 that will extend debootstrap's autopkgtest to run a heavily cut-down version of the same logic, to confirm that it does in fact work. Unfortunately, this does cause a regression for interactive use: processes inside an interactive schroot cannot tell that their stdin/stdout/stderr is in fact connected to a terminal, because that terminal is not visible to them. As a result, programs like sudo and screen will refuse to run, unless wrapped in something like "script /dev/null". So it might be necessary for schroot to provide its own pty (one that *is* valid inside the chroot) and forward input/output to/from the terminal outside the chroot, or something? (I think that's what container managers like lxc and systemd-nspawn do.) As a result I'm not tagging this as 'patch'. Regards, S
From: Simon McVittie <s...@debian.org> Date: Mon, 20 Feb 2017 10:43:24 +0000 Subject: Mount a new instance of /dev/pts in the chroot This is considered to be best-practice for container managers in Linux >= v2.6.29 with CONFIG_DEVPTS_MULTIPLE_INSTANCES=y. That config option was made unconditional in v4.7. This has some assumptions, which cannot be avoided if we are going to mount /dev/pts using schroot's fstab: * If the kernel is older than v4.7, it is assumed to be v2.6.29 or later with CONFIG_DEVPTS_MULTIPLE_INSTANCES=y. Users of older kernels, or intermediate versions with CONFIG_DEVPTS_MULTIPLE_INSTANCES=n, can revert this change via /etc. * gid 5 must be the right owner for ptys. This is correct for Debian (it's the hard-coded tty group specified in base-passwd) and probably many other distributions (it's systemd's configure-time default) but not necessarily correct everywhere. However, if the host system and the chroot disagree on the right gid, schroot's previous behaviour would have been wrong anyway, because it bind-mounted the host's /dev/pts. * /dev/ptmx inside the chroot must be either a real device node (as created by debootstrap < 1.0.76) or a symlink to pts/ptmx (as created by debootstrap >= 1.0.76). I have proposed a debootstrap patch to make it create the real device node again if possible. However, there is a desire for debootstrap to be runnable under container managers that restrict creation of device nodes, such as systemd-nspawn; under these container managers, creating /dev/ptmx as a symlink to pts/ptmx is the best that can be done. Bind-mounting /dev/pts/ptmx over /dev/ptmx, so that we get the new instance's /dev/ptmx equivalent instead of the host's, can only be done from code, so I have done it in the 10mount hook instead of in the fstab. --- etc/profile-templates/buildd/linux/fstab | 2 +- etc/profile-templates/default/linux/fstab | 2 +- etc/profile-templates/desktop/linux/fstab | 2 +- etc/profile-templates/sbuild/linux/fstab | 2 +- etc/setup.d/10mount | 12 ++++++++++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/etc/profile-templates/buildd/linux/fstab b/etc/profile-templates/buildd/linux/fstab index 26efe88..f2f6136 100644 --- a/etc/profile-templates/buildd/linux/fstab +++ b/etc/profile-templates/buildd/linux/fstab @@ -1,4 +1,4 @@ -/dev/pts /dev/pts none rw,bind 0 0 +/dev/pts /dev/pts devpts rw,newinstance,ptmxmode=666,mode=620,gid=5 0 0 tmpfs /dev/shm tmpfs defaults 0 0 # Mount a large scratch space for the build, so we don't use up # space on an LVM snapshot of the chroot itself. diff --git a/etc/profile-templates/default/linux/fstab b/etc/profile-templates/default/linux/fstab index 777f0ed..181ed80 100644 --- a/etc/profile-templates/default/linux/fstab +++ b/etc/profile-templates/default/linux/fstab @@ -1,5 +1,5 @@ /dev /dev none rw,bind 0 0 -/dev/pts /dev/pts none rw,bind 0 0 +/dev/pts /dev/pts devpts rw,newinstance,ptmxmode=666,mode=620,gid=5 0 0 /home /home none rw,bind 0 0 /tmp /tmp none rw,bind 0 0 diff --git a/etc/profile-templates/desktop/linux/fstab b/etc/profile-templates/desktop/linux/fstab index 7f61d8d..b0dae37 100644 --- a/etc/profile-templates/desktop/linux/fstab +++ b/etc/profile-templates/desktop/linux/fstab @@ -1,5 +1,5 @@ /dev /dev none rw,bind 0 0 -/dev/pts /dev/pts none rw,bind 0 0 +/dev/pts /dev/pts devpts rw,newinstance,ptmxmode=666,mode=620,gid=5 0 0 /home /home none rw,bind 0 0 /tmp /tmp none rw,bind 0 0 diff --git a/etc/profile-templates/sbuild/linux/fstab b/etc/profile-templates/sbuild/linux/fstab index 26efe88..f2f6136 100644 --- a/etc/profile-templates/sbuild/linux/fstab +++ b/etc/profile-templates/sbuild/linux/fstab @@ -1,4 +1,4 @@ -/dev/pts /dev/pts none rw,bind 0 0 +/dev/pts /dev/pts devpts rw,newinstance,ptmxmode=666,mode=620,gid=5 0 0 tmpfs /dev/shm tmpfs defaults 0 0 # Mount a large scratch space for the build, so we don't use up # space on an LVM snapshot of the chroot itself. diff --git a/etc/setup.d/10mount b/etc/setup.d/10mount index 296a162..8382151 100755 --- a/etc/setup.d/10mount +++ b/etc/setup.d/10mount @@ -269,3 +269,15 @@ if [ $STAGE = "setup-start" ] || [ $STAGE = "setup-recover" ]; then fi fi + +if [ $STAGE = "setup-start" ] || [ $STAGE = "setup-recover" ]; then + # Depending on how /dev was set up, /dev/ptmx might either be + # character device (5,2), or a symbolic link to pts/ptmx. + # Either way we want it to be equivalent to /dev/pts/ptmx, assuming + # both exist. + if [ -e "$CHROOT_PATH/dev/pts/ptmx" ] && \ + [ -e "$CHROOT_PATH/dev/ptmx" ] && \ + ! [ "$CHROOT_PATH/dev/pts/ptmx" -ef "$CHROOT_PATH/dev/ptmx" ]; then + mount --bind "$CHROOT_PATH/dev/pts/ptmx" "$CHROOT_PATH/dev/ptmx" + fi +fi