-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
devpts improvements #20463
Comments
Current state: systemd implements behavior 3.
systemd-nspawn implements behavior 1.
|
so, we kinda just follow here what the kernel does for us, and don't undo kernel preparations. That's why we implement behaviour 3 for the host systemd: we don't actually create ptmx, devtmpfs does that for us. udev these days is not in the business of creating device nodes, the kernel does that on its own, we just adjust the access modes. (tmpfiles creates some nodes though, based on MODALIAS info exported by kmods that want to be lazy-loaded, but ptmx is not like that) nspawn otoh doesn't use devtmpfs (because there's only one devtmpfs for the whole system), instead /dev is populated manually there starting from an empty tmpfs. There we set up /dev/ptmx as symlink to /dev/pts/ptmx. It's the only way really, since the way pts namespacing works is that you instantiate a new devptsfs instance for each container, hence we must redirect /dev/ptmx into the mouted devptsfs). I fully agree that it's kinda moronic to have two fully distinct setups here... Note that accessing /dev/pts/ptmx directly is never OK under the status quo, because it's explicitly marked 0000 to make it inaccessible if the /dev/ptmx node is an actual device node. You have to go through the /dev/ptmx name, to get to the right node, which glibc so far did. Maybe a fix would be to change the kernel to pre-mount devpts the same way it premounts devtmpfs for the host, and if so replace /dev/ptmx by a symlink. If that's a kernel option (similar to how devtmpfs already is) then things would just work for current systemd userspace, as we never create /dev/ptmx on the host anyway, and will just use whatever the kernel supports. (doing this would be slightly icky though: we need to pass gid=5 to the kernel during mounts of devpts, hence the kernel would have to hardcode that during build time) |
to say this differently: i feel uncomfortable with replacing a device node the kernel put into devtmpfs with a symlink. kernel should not create stuff there we are expected to the delete and replace. it should create things the right way out of the box. (I'd be a bit more comfortable with automatically bind mounting /dev/pts/ptmx to /dev/ptmx whenever we mount /dev/pts. But it's kind ugly too, since the device node will then change identity in the middle of everything) |
Yes, as I've said in another place I'm aware of that. While I hate this two distinct device nodes model I can sympathize with not changing kernel layout.
Yes, I know.
Yes, I know. We spearheaded this model in LXC which has been copied by all other runtimes.
And this is the problem. The goal of In addition to this it doesn't make a lot of sense since root can open
I would propose |
The problem with having distinct permissions between For example, the The
and now opening All of this doesn't even go into the issue of racy-path lookup for pty devices. There simply is no safe way to call The solution to this problem was the addition of a new All of these races become less severe once I do think that mounting |
That's a bit icky. /dev/ptmx does not linux driver model, so we cannot process it via udev, and adjust perms there. /dev/pts/ptmx is a device node that bypasses the whole driver model, it's just there. I mean, we can certainly add ptmxmode=0666 to the mount option and make sure that our udev rule for /dev/ptmx says the exact same thing, but that of course would then have to be kept in sync manually, there wouldn't really be any automatic syncing, only our manually coded adjustment of both. Note that /dev/ptmx is currently owned by the tty group. /dev/pts/ptmx is not. The group of course doesn't really matter given the 0666 access mode, but to keep things fully in sync we should probably adjust that too. Except that there is no mount option for that in devpts afaics? that kinda sucks, as adjusting this a posteriori isn't ideal |
so what about this:
also good: |
There is a mount option for ret = fs_set_property(fd_fs, "gid", "5");
if (ret < 0)
SYSTRACE("Failed to set \"gid=5\" on devpts filesystem context %d", fd_fs);
ret = fs_set_property(fd_fs, "ptmxmode", "0666");
if (ret < 0)
return syserror("Failed to set \"ptmxmode=0666\" property on devpts filesystem context %d", fd_fs);
ret = fs_set_property(fd_fs, "mode", "0620");
if (ret < 0)
return syserror("Failed to set \"mode=0620\" property on devpts filesystem context %d", fd_fs); |
It looks like the gid option does not apply to the ptmx node within devpts.
|
Right, the assumption is that while you may want to delegate |
I suppose we could configure the group and mode on Something like:
|
I'd really prefer if there was a ptmxgid= as a mount option to devptsfs, so that we can set this right immediately |
This is going to be rejected with "just chown it". |
In the before-fore times we used to have
/dev/ptmx
and then through a long and convoluted history we ended up withdevpts
. That is so long ago that neither Google, Facebook, or Twitter existed. In fact, I couldn't even have used Wikipedia to lookup whendevpts
was created.All distros now mount a
devpts
instance at/dev/pts
with theptmx
device located in/dev/pts/ptmx
.But for backward compatibility reasons distros still provide the
ptmx
device at/dev/ptmx
. My ultimate dream had been to just kill/dev/ptmx
completely and I once tried to address this in glibc directly but of course that went nowhere https://sourceware.org/legacy-ml/libc-alpha/2018-03/msg00360.html because of reasons I found not convincing.I can live with the not getting rid of
/dev/ptmx
completely in favor of/dev/pts/ptmx
part. However, the distro landscape is a cornucopia of ways to provide/dev/ptmx
. There are three ways to provide/dev/ptmx
:In this case devpts must have either been mounted with ptmxmode=0666 or
chmod 0666 /dev/pts/ptmx must have been called.
So any open() on /dev/pts/ptmx will succeed.
Analogous to 1. devpts must have either been mounted with ptmxmode=0666
or chmod 0666 /dev/pts/ptmx must have been called.
So any open() on /dev/pts/ptmx will succeed.
In this case devpts can either be mounted with ptmxmode=0666 or
ptmxmode=0000. In the latter case privileged opens of /dev/pts/ptmx will
succeed while unprivileged opens will fail. The unprivileged failure
case will be unproblematic since we always fallback to opening /dev/ptmx
which should have permission 0666. If it doesn't then we would fail the
exact same way we always did.
This is a nightmare. The most annoying case is distros that provide 3., a separate
/dev/ptmx
device node that has different permissions for no reason whatsoever than the identical device node at/dev/pts/ptmx
. This is especially nonsensical since the dependent device received from a newly opened dominating device of/dev/ptmx
needs to be looked up or opened (at least ifTIOCGPTPEER
is not available) by going through/dev/pts
. It also technically requires a userspace program to check that/dev/ptmx
and/dev/pts/ptmx
are the same device node if they want to avoid interacting with the wrong dependent device.If at all feasible, I would like to discuss the possibility of systemd becoming opinionated and enforcing one of the three cases uniformly or at least enforcing that the permissions between the device node in
/dev/pts/ptmx
and/dev/ptmx
always match if they are the same device node.The text was updated successfully, but these errors were encountered: