Bug 101898 - Containers (#100344): fd-passing-based creation
Summary: Containers (#100344): fd-passing-based creation
Status: ASSIGNED
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: git master
Hardware: All All
: medium enhancement
Assignee: Simon McVittie
QA Contact: D-Bus Maintainers
URL:
Whiteboard:
Keywords:
Depends on: 101354
Blocks: 100344
  Show dependency treegraph
 
Reported: 2017-07-24 14:27 UTC by Simon McVittie
Modified: 2017-08-01 11:42 UTC (History)
4 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon McVittie 2017-07-24 14:27:39 UTC
+++ This bug was initially created as a clone of Bug #100344 +++

Following on from Bug #101354, Allison wants to be able to arrange for container instances' servers to appear inside containers in a more elegant way than creating them outside and bind-mounting them in. I already intended to do this, but it is not part of the minimum viable product (Bug #101354).

Design sketch:

The named_parameters a{sv} argument may contain:

    ServerSocket: h
        A socket (fstat() must indicate format S_IFSOCK)
        with SO_DOMAIN = AF_UNIX and SO_TYPE = SOCK_STREAM. The
        container manager will arrange for bind() and listen() to be called
        on this socket so that it is made available inside the container.

        If ServerSocketReadyNotifier is not provided, the container manager
        must already have called bind() and listen() (the SO_ACCEPTCONN socket
        option is 1 and getsockname() returns an address), such that this
        socket is already ready for the message bus to call accept() on it.
        In this case the AddServer() method will return the socket's path
        and D-Bus address as usual.

        If ServerSocketReadyNotifier is provided, then the container manager
        may delay calling bind() and listen() until just before it makes the
        ServerSocketNotifierReadyNotifier poll readable. In this case the
        AddServer() method cannot determine the socket's address, so it
        will return an empty byte-array instead of the socket's absolute
        path, and an empty string instead of its D-Bus address.

    ServerSocketReadyNotifier: h
        The reading end of a pipe or FIFO (format S_IFIFO). The container
        manager will wait for this pipe to poll readable, then close it
        and begin to accept() on the ServerSocket.

        (The container manager should keep the write end of this socket open
        until it has called bind() and listen() on the ServerSocket,
        then close the write end, resulting in the read end polling readable.)
Comment 1 Simon McVittie 2017-07-24 14:43:12 UTC
Implementation sketch:

We can use fstat() to check that the passed socket and pipe are of the types we expect, to avoid callers doing anything crazy with non-socket or non-pipe fds. It might well be a good idea to getsockopt() the socket for SO_DOMAIN and SO_TYPE too - the usual motto of "we can always make it more liberal later".

From socket(7) it looks like we can getsockopt() for SO_ACCEPTCONN (at least on Linux) to check that it's already listening when we want to accept() it. As a safety-catch we probably still want to make sure the dbus-daemon won't busy-loop on an invalid server fd, though.

Open question: can a FUSE filesystem intercept fstat() on an open fd and make it take arbitrarily long, resulting in a DoS on dbus-daemon when it tries to fstat() them? If it can, then this mode of container creation has to be a privileged operation (root or bus owner only).
Comment 2 Philip Withnall 2017-08-01 11:42:53 UTC
(In reply to Simon McVittie from comment #0)
>         If ServerSocketReadyNotifier is provided, then the container manager
>         may delay calling bind() and listen() until just before it makes the
>         ServerSocketNotifierReadyNotifier poll readable. In this case the
>         AddServer() method cannot determine the socket's address, so it
>         will return an empty byte-array instead of the socket's absolute
>         path, and an empty string instead of its D-Bus address.

Typo: s/ServerSocketNotifierReadyNotifier/ServerSocketReadyNotifier/?


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct.