On Fri, Sep 21, 2018 at 6:39 AM Tycho Andersen <tycho@xxxxxxxx> wrote: > > On Thu, Sep 20, 2018 at 07:18:45PM -0700, Andy Lutomirski wrote: > > > > I think we just want the operation to cover all the cases. Let PUT_FD > > take a source fd and a dest fd. If the source fd is -1, the dest is > > closed. If the source is -1 and the dest is -1, return -EINVAL. If > > the dest is -1, allocate an fd. If the dest is >= 0, work like > > dup2(). (The latter could be necessary to emulate things like, say, > > dup2 :)) > > ...then if we're going to allow overwriting fds, we'd need to lift out > the logic from do_dup2 somewhere? Is this getting too complicated? :) > fds are complicated :-p More seriously, though, I think it's okay if we don't support everything out of the box. getting the general semantics I suggested is kind of nice because the resulting API is conceptually simple, even if it encapsulates three cases. But I'd be okay with only supporting add-an-fd-at-an-unused-position and delete-an-fd out of the box -- more can be added if there's demand. But I think that exposing an operation that allocates and reserves an fd without putting anything in the slot is awkward, and it opens us up to weird corner cases becoming visible that are currently there but mostly hidden. For example, what happens if someone overwrites a reserved fd with dup2()? (The answer is apparently -EBUSY -- see the big comment in do_dup2() in fs/file.c.) But there's a more significant nastiness: what happens if someone abuses your new mechanism to overwrite a reserved fd that belongs to a different thread? It looks like you'll hit the BUG_ON(fdt->fd[fd] != NULL); in __fd_install(). So unless you actually track which unused fds you own and enforce that the final installation installs in the right slot, you have a problem. BTW, socketpair() isn't the only thing that can add two fds. recvmsg() can, too, as can pipe() and pipe2(). Some of the DRM ioctls may as well for all I know. But socketpair(), pipe(), and recvmsg() can be credibly emulated by adding each fd in sequence and then deleting them all of one fails. Sure, this could race against dup2(), but I'm not sure we care. --Andy