From: dac.override@gmail.com (Dominick Grift) Date: Sun, 7 Jun 2015 19:02:44 +0200 Subject: [refpolicy] [PATCH] proposal for libvirt vfio/vt-d support In-Reply-To: <55747110.5030901@web.de> References: <55746E03.90502@web.de> <55747110.5030901@web.de> Message-ID: <20150607170243.GA29073@x131e> To: refpolicy@oss.tresys.com List-Id: refpolicy.oss.tresys.com On Sun, Jun 07, 2015 at 06:28:00PM +0200, Alexander Wetzel wrote: > > The attached patch proposes a way to allow pci device pass through via > a new selinux boolean "virt_use_vfio" for libvirt. > > This was originally proposed in a slightly different version as gentoo > enhancement here: https://bugs.gentoo.org/show_bug.cgi?id=522736 > (It's only tested as patch against the gentoo version of the refpoliciy.) > > I used it for around one year to pass an ISDN PCIe card to a guest and > verified today the function with an USB PCI device. (The ISDN card is no > longer in the system.) > USB HUP was ok in guest with lspci and lsusb, but a USB stick did not > work as expected. That's not related to selinux and was ignored here, > since I have the same problem with selinux in permissive mode on the host. > > The patch adds "vfio_device_t;", the boolean virt_use_vfio and when the > boolean is set the following rules: > > allow virtd_t self:process setrlimit; > allow virtd_t self:capability sys_resource; > allow virtd_t svirt_t:process rlimitinh; > allow virtd_t vfio_device_t:chr_file { relabelfrom setattr }; > allow svirt_t vfio_device_t:chr_file { read write open ioctl }; > This looks fine to me. It must have taken you a while to identify that rlimitinh is required. The way you implemented this in the patch below has some issues though. See inline comments below. > Here the errors I get when I remove one of the rights (keeping all the > others in place): > > Without "allow virtd_t self:process setrlimit" or "allow virtd_t > self:capability sys_resource": > error: Failed to start domain web-old > error: internal error: Process exited prior to exec: libvirt: error : > cannot limit locked memory to 5368709120: Permission denied > > Without "allow virtd_t svirt_t:process rlimitinh": > error: Failed to start domain web-old > error: internal error: early end of file from monitor: possible problem: > 2015-06-07T14:28:21.433403Z qemu-system-x86_64: -device > vfio-pci,host=00:1d.0,id=hostdev0,bus=pci.0,addr=0xd,rombar=1: > vfio_dma_map(0x3ebad4fcd0, 0x0, 0xa0000, 0x39030000000) = -12 (Cannot > allocate memory) > 2015-06-07T14:28:21.433480Z qemu-system-x86_64: -device > vfio-pci,host=00:1d.0,id=hostdev0,bus=pci.0,addr=0xd,rombar=1: > vfio_dma_map(0x3ebad4fcd0, 0xc0000, 0x20000, 0x39144200000) = -12 > (Cannot allocate memory) > 2015-06-07T14:28:21.433538Z qemu-system-x86_64: -device > vfio-pci,host=00:1d.0,id=hostdev0,bus=pci.0,addr=0xd,rombar=1: > vfio_dma_map(0x3ebad4fcd0, 0x100000, 0xdff00000, 0x39030100000) = -12 > (Cannot allocate memory) > 2015-06-07T14:28:21.433707Z qemu-system-x86_64: -device > vfio-pci,host=00:1d.0,id=hostdev0,bus=pci.0,addr=0xd,rombar=1: > vfio_dma_map(0x3ebad4fcd0, 0x100000000, 0x20000000, 0x39110000000) = -12 > (Cannot allocate memory) > 2015-06-07T14:28:21.433730Z qemu-system-x86_64: -device > vfio-pci,host=00:1d.0,id=hostdev0,bus=pci.0,addr=0xd,rombar=1: vfio: > > > Without "allow virtd_t vfio_device_t:chr_file relabelfrom" > error: Failed to start domain web-old > error: unable to set security context > 'system_u:object_r:svirt_image_t:s0:c587,c898' on '/dev/vfio/2': > Permission denied > > > Without "allow virtd_t vfio_device_t:chr_file setattr": > --> Can't reproduce an error without this right any more. > I'm pretty sure it was needed in the past, see gentoo ticket from link > above. > > > Without any of the permissions of > "allow svirt_t vfio_device_t:chr_file { read write open ioctl }": > error: Failed to start domain web-old > error: internal error: early end of file from monitor: possible problem: > 2015-06-07T15:40:47.505774Z qemu-system-x86_64: -device > vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0xd: vfio: supported > vfio version: 0, reported version: -1 > 2015-06-07T15:40:47.505814Z qemu-system-x86_64: -device > vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0xd: vfio: failed to > setup container for group 2 > 2015-06-07T15:40:47.505835Z qemu-system-x86_64: -device > vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0xd: vfio: failed to > get group 2 > 2015-06-07T15:40:47.505858Z qemu-system-x86_64: -device > vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0xd: Device > initialization failed. > 2015-06-07T15:40:47.505883Z qemu-system-x86_64: -device > vfio-pci,host=00:1a.0,id=hostdev0,bus=pci.0,addr=0xd: Device 'vfio-pci' > could not be initialized > > > diff -ru refpolicy_orig/policy/modules/contrib/virt.te refpolicy/policy/modules/contrib/virt.te > --- refpolicy_orig/policy/modules/contrib/virt.te 2014-06-16 19:45:41.000000000 +0200 > +++ refpolicy/policy/modules/contrib/virt.te 2015-06-07 16:01:56.160252828 +0200 > @@ -70,6 +70,14 @@ > ## > gen_tunable(virt_use_xserver, false) > > +## > +###

> +### Determine whether confined virtual guests > +### can use vfio for pci device pass through (vt-d). > +###

> +###
> +gen_tunable(virt_use_vfio, false) > + > attribute virt_ptynode; > attribute virt_domain; > attribute virt_image_type; > @@ -340,6 +348,14 @@ > fs_manage_dos_files(virt_domain) > ') > > +tunable_policy(`virt_use_vfio',` > + dev_rw_vfio_dev(svirt_t) > + dev_trans_vfio_dev(virtd_t) > + allow virtd_t self:process setrlimit; > + allow virtd_t self:capability sys_resource; > + allow virtd_t svirt_t:process rlimitinh; > +') > + I would probably split this up into two boolean blocks one for svirt_t and one for virtd_t. This because the svirt policy and virtd policy are also split. This where the svirt_t policy is defined: tunable_policy(`virt_use_vfio',` dev_rw_vfio_dev(svirt_t) ') and this where the virtd_t policy is defined: tunable_policy(`virt_use_vfio',` allow virtd_t self:capability sys_resource; allow virtd_t self:process setrlimit; allow virtd_t svirt_t:process rlimitinh; dev_setattr_vfio_dev(virtd_t) dev_relabelfrom_vfio_dev(virtd_t) ') > optional_policy(` > tunable_policy(`virt_use_xserver',` > xserver_read_xdm_pid(virt_domain) > diff -ru refpolicy_orig/policy/modules/kernel/devices.fc refpolicy/policy/modules/kernel/devices.fc > --- refpolicy_orig/policy/modules/kernel/devices.fc 2014-06-16 19:44:12.000000000 +0200 > +++ refpolicy/policy/modules/kernel/devices.fc 2015-06-07 16:01:53.110252822 +0200 > @@ -118,6 +118,7 @@ > ifdef(`distro_suse', ` > /dev/usbscanner -c gen_context(system_u:object_r:scanner_device_t,s0) > ') > +/dev/vfio/(vfio)?[0-9]* -c gen_context(system_u:object_r:vfio_device_t,s0) I would probably use "/dev/vfio/.+ -c ..." > /dev/vhost-net -c gen_context(system_u:object_r:vhost_device_t,s0) > /dev/vbi.* -c gen_context(system_u:object_r:v4l_device_t,s0) > /dev/vbox.* -c gen_context(system_u:object_r:xserver_misc_device_t,s0) > diff -ru refpolicy_orig/policy/modules/kernel/devices.if refpolicy/policy/modules/kernel/devices.if > --- refpolicy_orig/policy/modules/kernel/devices.if 2014-09-12 15:52:18.000000000 +0200 > +++ refpolicy/policy/modules/kernel/devices.if 2015-06-07 16:01:53.110252822 +0200 > @@ -4611,6 +4611,42 @@ > > ######################################## > ## > +## Allow libvirt to use vfio for vt-d passthrough This summary is inaccurate. It does not allow libvirt to use vfio for vt-d passthrough. Instead it allows the calling domain to read and write vfio device nodes. A summary like this might be more appropriate: "Read and write vfio devices." > +## > +## > +## > +## Domain allowed access. > +## > +## > +# > +interface(`dev_rw_vfio_dev',` > + gen_require(` > + type device_t, vfio_device_t; > + ') > + > + allow $1 vfio_device_t:chr_file { read write open ioctl }; I would probably instead use: rw_chr_files_pattern($1, device_t, vfio_device_t) > +') > + > +######################################## > +## > +## Allow dev file transition to new user and type This summary is inaccurate. I would probably split this into two interfaces: 1. dev_setattr_vfio_dev() "Set attributes of vfio devices." 2. dev_relabelfrom_vfio_dev() "Relabel from vfio devices." > +## > +## > +## > +## Domain allowed access. > +## > +## > +# > +interface(`dev_trans_vfio_dev',` > + gen_require(` > + type device_t, vfio_device_t; > + ') > + > + allow $1 vfio_device_t:chr_file { relabelfrom setattr }; i would probably use for dev_relabelfrom_vfio_dev(): relabelfrom_chr_files_pattern($1, device_t, vfio_device_t) and for dev_setattr_vfio_dev() setattr_chr_files_pattern($1, device_t, vfio_device_t) > +') > + > +############################ > +## > ## Allow read/write the vhost net device > ## > ## > diff -ru refpolicy_orig/policy/modules/kernel/devices.te refpolicy/policy/modules/kernel/devices.te > --- refpolicy_orig/policy/modules/kernel/devices.te 2014-12-03 19:37:34.000000000 +0100 > +++ refpolicy/policy/modules/kernel/devices.te 2015-06-07 16:01:53.110252822 +0200 > @@ -273,6 +273,9 @@ > type userio_device_t; > dev_node(userio_device_t) > > +type vfio_device_t; > +dev_node(vfio_device_t) > + > type v4l_device_t; > dev_node(v4l_device_t) > > > _______________________________________________ > refpolicy mailing list > refpolicy at oss.tresys.com > http://oss.tresys.com/mailman/listinfo/refpolicy -- 02DFF788 4D30 903A 1CF3 B756 FB48 1514 3148 83A2 02DF F788 http://keys.gnupg.net/pks/lookup?op=vindex&search=0x314883A202DFF788 Dominick Grift -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 648 bytes Desc: not available Url : http://oss.tresys.com/pipermail/refpolicy/attachments/20150607/3249e85e/attachment.bin