On Mon, Sep 16, 2019 at 11:00:35AM +0100, Dr. David Alan Gilbert wrote: > (Copying in Stefan since he was looking at DBus for virtiofs) > > * Marc-André Lureau (marcandre.lur...@redhat.com) wrote: > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> > > --- > > docs/interop/dbus.rst | 73 ++++++++++++++++++++++++++++++++++++++++++ > > docs/interop/index.rst | 1 + > > 2 files changed, 74 insertions(+) > > create mode 100644 docs/interop/dbus.rst > > > > diff --git a/docs/interop/dbus.rst b/docs/interop/dbus.rst > > new file mode 100644 > > index 0000000000..c08f026edc > > --- /dev/null > > +++ b/docs/interop/dbus.rst > > @@ -0,0 +1,73 @@ > > +===== > > +D-Bus > > +===== > > + > > +Introduction > > +============ > > + > > +QEMU may be running with various helper processes involved: > > + - vhost-user* processes (gpu, virtfs, input, etc...) > > + - TPM emulation (or other devices) > > + - user networking (slirp) > > + - network services (DHCP/DNS, samba/ftp etc) > > + - background tasks (compression, streaming etc) > > + - client UI > > + - admin & cli > > + > > +Having several processes allows stricter security rules, as well as > > +greater modularity. > > + > > +While QEMU itself uses QMP as primary IPC (and Spice/VNC for remote > > +display), D-Bus is the de facto IPC of choice on Unix systems. The > > +wire format is machine friendly, good bindings exist for various > > +languages, and there are various tools available. > > + > > +Using a bus, helper processes can discover and communicate with each > > +other easily, without going through QEMU. The bus topology is also > > +easier to apprehend and debug than a mesh. However, it is wise to > > +consider the security aspects of it. > > + > > +Security > > +======== > > + > > +A QEMU D-Bus bus should be private to a single VM. Thus, only > > +cooperative tasks are running on the same bus to serve the VM. > > + > > +D-Bus, the protocol and standard, doesn't have mechanisms to enforce > > +security between peers once the connection is established. Peers may > > +have additional mechanisms to enforce security rules, based for > > +example on UNIX credentials. > > + > > +dbus-daemon can enforce various policies based on the UID/GID of the > > +processes that are connected to it. It is thus a good idea to run > > +helpers as different UID from QEMU and set appropriate policies (so > > +helper processes are only allowed to talk to qemu for example). > > + > > +For example, this allows only ``qemu`` user to talk to ``qemu-helper`` > > +``org.qemu.Helper1`` service: > > + > > +.. code:: xml > > + > > + <policy user="qemu"> > > + <allow send_destination="org.qemu.Helper1"/> > > + <allow receive_sender="org.qemu.Helper1"/> > > + </policy> > > + > > + <policy user="qemu-helper"> > > + <allow own="org.qemu.Helper1"/> > > + </policy> > > + > > + > > +dbus-daemon can also perfom SELinux checks based on the security > > +context of the source and the target. For example, ``virtiofs_t`` > > +could be allowed to send a message to ``svirt_t``, but ``virtiofs_t`` > > +wouldn't be allowed to send a message to ``virtiofs_t``. > > I think we need to start thinking about this more now rather than > 'can'. .
Thinking about DBus usage with helpers, as compared to the current state with monolithic QEMU, the top priority is to ensure no degradation in security vs current practice. That is fairly easy from libvirt's POV - we simply need to make sure that the dbus daemon and all helpers get given the same SELinux svirt_t content as used for QEMU, so each QEMU is still siloed to the same extent. If SELinux is not enabled, then currently an out of the box libvirt config only protects the host from QEMU, it doesn't protect QEMU from other QEMUs, since they all run the same user ID. It is possible to tell libvirt to run each QEMU as a separate user ID if the mgmt app has a range of user IDs avalable. In this case, we would simply run the helpers/dbus as the same per-QEMU user ID to ensure we don't regress. Getting an improved security model is obviously the ultimate goal, as this modularity needs to offer some benefit to outweight its costs. In terms of SELinux, this will involve creating distinct SElinux contexts for each helper process. (svirt_slirp_t, svirt_swtpm_t, etc, etc). In terms of DAC, in the per QEMU user ID scenario, we would need to allocate at least 2 UIDs for each QEMU process, so that helpers would be separate from the QEMU. To be honest it would be better if we had 3 UIDs, to the dbus daemon was separated from both the helpers and QEMU. This starts to sound like alot of UIDs which is tedious to manage. Libvirt already puts QEMU in a separate mount namespace. From a DAC POV, to get meaninguful separation will probably want libvirt to consider the "user" namespace too. This is quite a bit of work to get everything labelled right for different user namespace, but it may well simplify mgmt thereafter. We still have the same problem though, of needing to assign a range of user IDs for each user namespace. Overall, I can see the possible technical options for securing this use of DBus, so I'm not too concerned here. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|