On 31 May 2016 at 10:59, Ansis Atteka <ansisatteka(a)gmail.com> wrote:
On 31 May 2016 at 09:36, Daniel P. Berrange <berrange(a)redhat.com> wrote:
> On Mon, May 30, 2016 at 01:27:46PM -0700, Ansis Atteka wrote:
> > On Mon, May 30, 2016 at 12:29 AM, Christian Ehrhardt
> > <christian.ehrhardt(a)canonical.com> wrote:
> > > On Tue, May 24, 2016 at 4:10 PM, Aaron Conole <aconole(a)redhat.com>
> wrote:
> > >
> > >> Daniele Di Proietto <diproiettod(a)vmware.com> writes:
> > >>
> > >> > Hi Aaron,
> > >> >
> > >> > I'm still a little bit nervous about calling chown on a
(partially)
> > >> > user controlled file name.
> > >>
> > >> I agree, that always seems scary.
> > >>
> > >> > Before moving forward I wanted to discuss a couple of other
> options:
> > >> >
> > >> > * Ansis (in CC) suggested using -runas parameter in qemu. This
way
> > >> > qemu can open the socket as root and drop privileges before
> starting
> > >> > guest execution.
> > >>
> > >> I'm not sure how to do this with libvirt, or via the OpenStack
> Neutron
> > >> plugin. I also don't know if it would be an acceptable workaround
> for
> > >> users. Additionally, I recall there being something of a
"don't even
> > >> know if this works" around it. Maybe Christian or Ansis (both in
CC)
> > >> can expound on it.
> > >>
> >
> > Cross-posting to libvirt mailing list to hear opinion from libvirt
> developers.
> >
> > In short - the problem is that libvirtd process starts qemu process
> > under non-root user. Since qemu starts under non-root process, then
> > qemu can't connect to DPDK unix domain sockets created by ovs-vswitcd
> > process that runs under "root". There are two solutions to this
> > problem:
> > 1. let ovs-vswitchd process to chown its socket from "root" to
> > "libvirt" group and/or user (this is what Aarons patch proposes)
> > 2. make libvirtd process to start qemu process under "root" but then
> > let qemu to downgrade via "-run-as" flag after qemu has opened the
> > Unix Domain socket.
> >
> > Regarding solution #2. I think the necessary changes roughly would be
> to:
> > 1. invoke virCommandAddArgPair(cmd, "-runas", "libvirt")
before
> > starting qemu process; AND
> > 2. revert virCommandSetUID() that automatically downgrades user from
> > "root" to "libvirt" even before qemu starts.
> > I would like to hear feasibility of such solution from libvirt
> > developers? Or maybe there is even a better solution that I am
> > missing?
>
> That's not going to happen. Libvirt consider QEMU to be untrustworthy
> in general and so apply multiple techniques to confine QEMU before it is
> exec'd. This include dropping to non-0 uid/gid, applying apparmour/selinux
> policies, putting it in restricted cgroups, and potentially more in the
> future such as putting it in custom namespaces. We've no desire to use
> qemu's -runas, as that means we're trusting QEMU to actually drop
> privileges
> as it claims to.
>
Thanks for reply, Daniel! Yes, with -run-as flag it would be left at
qemu's discretion to give up 'root' privileges and I understand you that it
may not fit into security model chosen by libvirt.
> Libvirt's model is that libvirt will setup policies to allow QEMU access
> to the specific resources that it needs. so eg libvirt will chown the
> disk images associated with the VM to give it access.
>
> I'm missing history of this thread, but IIUC, the issue here is access
> to the UNIX domain socket associated with the vhost-user network backend
> for QEMU. If so, then I think it is a case where libvirt should be setting
> ownershup on that socket before starting QEMU, in order to grant access.
> This of course assumes there is a separate UNIX domain socket per VM
> that is launched.
>
If the current libvirt security model is that libvirt is already
chown()'ing resources needed by qemu, then perhaps vhost user socket may be
another thing that libvirt needs to chown()? Or do you think that it would
be better for libvirt to tell the user to which Open vSwitch needs to chown
the socket (via the ovs-vsctl call in
libvirt/src/util/virnetdevopenvswitch.c)?
Also, did I understand it correctly that libvirt also changes SELinux
context for resources that qemu would be consuming so that qemu would be
confined by additional Mandatory Access Control layer? If so, then I think
the current libvirt security model suggests that chown()'ing and
chcon()'ing should happen from libvirt and should not use Open vSwitch as a
proxy to do that, because otherwise Open vSwitch SELinux policy would need
to be loosened up to do such things.
Also, what got me concerned is that Open vSwitch already has a Mandatory
Access Control enforced under RHEL and Fedora distributions. For example,
if libvirt changes SELinux context for files and sockets created by Open
vSwitch then I am not sure how Open vSwitch would be able to cleanup them
without getting permission denied errors. I will try this out on Fedora to
see if my concern is justified.
I think that Libvirt chown()'ing DPDK sockets that were created by Open
vSwitch may work ok, because Open vSwitch is running under root user and
can reclaim the socket even after libvirt chown()'ed them away. However, I
think that Libvirt chcon()'ing sockets created by Open vSwitch would not
work very well with current SELinux policies. This is because by default
Open vSwitch is running under SELinux openvswitch_t domain and as minimum
would not be able to clean after itself in case of abrupt Open vSwitch
crash and if libvirt chcon()'ed the DPDK socket away from it:
# ls -laZ /var/run/openvswitch/db.sock
srwxr-x---. 1 root root system_u:object_r:openvswitch_var_run_t:s0 0 May 31
18:16 /var/run/openvswitch/db.sock
# chcon -t virt_var_run_t /var/run/openvswitch/db.sock
# ls -laZ /var/run/openvswitch/db.sock
srwxr-x---. 1 root root system_u:object_r:virt_var_run_t:s0 0 May 31 18:16
/var/run/openvswitch/db.sock
# kill -SIGSEGV `pidof ovsdb-server -s`
# tail /var/log/openvswitch/ovsdb-server.log
2016-06-01T01:16:04.265Z|00592|stream_unix|ERR|/var/run/openvswitch/db.sock:
binding failed: Permission denied
2016-06-01T01:16:04.268Z|00593|socket_util_unix|WARN|unlinking
"/var/run/openvswitch/db.sock": Permission denied
2016-06-01T01:16:04.268Z|00594|fatal_signal|WARN|could not unlink
"/var/run/openvswitch/db.sock" (Permission denied)
* the example above is not using DPDK socket, but OVSDB socket. Also, I
probably did not set the right SELinux type. However, I think this should
not change the result.
I think that ideally chown()'ing and chcon()'ing of DPDK sockets should be
done both in the same place - either both in libvirt or both in Open
vSwitch. Daniel, if libvirt would depend on Open vSwitch to do the actual
chown() and chcon() calls would that violate libvirt security model as
well? What are your thoughts?