On Thu, Apr 18, 2019 at 03:24:13PM +0200, marcandre.lureau(a)redhat.com wrote:
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
I am throwing this away for discussions, and early feedback.
With the upcoming release of libslirp[1], we have an opportunity to
run SLIRP networking in a separate process. This will allow for
stricter security policies for both qemu & slirp, as slirp is
notoriously not very safe (discussed on ML, various CVEs, and even the
code says so explicitly in the comments), yet people rely on it regularly.
For network type "user", libvirt could spawn an helper process (an
experimental version is [2]). It would setup a socket pair between
qemu and the helper and use -net socket. qemu could then be built
without libslirp! (imho, qemu should deprecate built-in -net user
support, and doesn't need to grow its own sub-process handling)
This libvirt patch is a bit rough, I am not sure where things should
go. In particular, how to manage the subprocesses properly (security
aspects, and lifecycle etc), and how to deal with migration (prevent
migrating from non-helper to helper version etc).
Security is an interesting question
- DAC permissions
- with session libvirt we have no choice - it will be the
same UID as QEMU and libvirtd
- with system libvirt we can run the helper under the same
UID/GID as QEMU (this might be the shared qemu:qemu pair,
or it might be a custom uniq-per-VM UID/GID pair). With
the shared UID/GID qemu:qemu, it would benefit from a
separate slirp UID/GID. If the VM is using a uniq-per-VM
UID/GID though, using a single "slirp" user would be a
security regression.
I'm inclined to ignore DAC UID/GID as a means of isolating
slirp from QEMU
- MAC permissions
Clearly the slirp helper must have a dedicated SELinux
domain "slirp_t". We should then append the uniq-per-VM
category to this. This gives strong separation between QEMU
and SLIRP, as well as between SLIRPS for each QEMU
- Capabilities
Ideally slirp will have zero capabilities
At this point, the slirp-helper doesn't handle migration. But is
it
really worth it? From a guest POV, it would look like packet lost or
disconnection. Adding migration handling is possible, to avoid a
disconnection event. How should it be done? via a libvirt provided
socket for storage? via its own file transferred by libvirt? via qemu
somehow (qemu wouldn't really know about the external process but
would copy around the migration bits?).
How does migration actually work today with built-in slirp ? I
Assume that all open network connections are lost right now ?
What actual state does QEMU transfer for built-in slirp what
does that achieve in practice ?
Ideally we would "live migrate" all existing QEMU processes using
built-in slirp to use the slirp helper. Even if this doesn't
actually do much useful stuff due to all connections being lost,
it allows us to automatically enable external slirp for everything
out of the box. Requiring an opt-in config for external slirp makes
it less compelling & will massively reduce uptake.
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 :|