On Thu, Feb 6, 2020 at 11:38 AM joshua stein <j...@openbsd.org> wrote:

> On Thu, 06 Feb 2020 at 11:21:11 -0700, Todd C. Miller wrote:
> > On Thu, 06 Feb 2020 10:45:44 -0700, "Theo de Raadt" wrote:
> >
> > > That feels better, and will be more atomic.
> >
> > Unfortunately, we can't do this in ptmioctl() since we don't have
> > the index of the open ptm device to use to check for the presence
> > of UF_EXCLOSE.  So it has to be done in libc instead.
>
> Alright, so like this then?
>

I'm sorry, but this is only superficially correct: the otherwise
unobtainable value of O_CLOEXEC (and SOCK_CLOEXEC) is that it's atomic with
the creation of the fd: there is no window where another thread calling
execve() or fork() will catch the fd without the flag set.  Setting the
flag in the libc code doesn't provide that guarantee.

I see two ways to do this in a way that provides the guarantee without
breaking the existing ioctl(PTMGET) ABI:

1) rename PTMGET to PTMGET_O66; add PTMGET which *always* sets FD_CLOEXEC
on both fds and change libc to instead _clear_ FD_CLOEXEC when O_CLOEXEC is
not passed.  Downside: extra syscalls in the common case

2) rename PTMGET to PTMGET_O66 and struct ptmget to struct ptmget_o66;
define a new struct ptmget which includes an "int flags" member which can
be used to pass O_* flags that should be applied by the kernel to both
control and slave fd before returning; change libc to set that from its
flags argument.

2b) bonus: do (2) but also provide a flag which tells the kernel to *not
open* the slave, and use that in posix_openpt(), fixing a subtle bug in our
posix_openpt()'s behavior

I guess I meant three ways.


Side note: posix_openpt() should, like openpty(), unconditionally pass
O_CLOEXEC when opening /dev/ptm.


Philip Guenther

Reply via email to