I upgraded from F8 to F10 and SELinux no longer plays nice with KVM. It is prevented from setting up a tun device and configuring it. I get the following in dmesg: type=1400 audit(1230302457.484:33): avc: denied { net_admin } for pid=7459 comm="qemu-kvm" capability=12 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=unconfined_u:system_r:qemu_t:s0 tclass=capability type=1400 audit(1230302457.601:34): avc: denied { execute } for pid=7480 comm="qemu-kvm" name="qemu-ifup" dev=dm-0 ino=1311793 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:etc_t:s0 tclass=file type=1400 audit(1230302457.601:35): avc: denied { execute_no_trans } for pid=7480 comm="qemu-kvm" path="/etc/qemu-ifup" dev=dm-0 ino=1311793 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:etc_t:s0 tclass=file type=1400 audit(1230302457.602:36): avc: denied { execute } for pid=7480 comm="qemu-kvm" name="bash" dev=dm-0 ino=1245277 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file type=1400 audit(1230302457.602:37): avc: denied { read } for pid=7480 comm="qemu-kvm" name="bash" dev=dm-0 ino=1245277 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file type=1400 audit(1230302457.608:38): avc: denied { getattr } for pid=7482 comm="qemu-ifup" path="/bin/grep" dev=dm-0 ino=1245191 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file type=1400 audit(1230302457.608:39): avc: denied { execute } for pid=7482 comm="qemu-ifup" name="grep" dev=dm-0 ino=1245191 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file type=1400 audit(1230302457.608:40): avc: denied { read } for pid=7482 comm="qemu-ifup" name="grep" dev=dm-0 ino=1245191 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file type=1400 audit(1230302457.609:41): avc: denied { execute_no_trans } for pid=7482 comm="qemu-ifup" path="/bin/grep" dev=dm-0 ino=1245191 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file type=1400 audit(1230302457.637:42): avc: denied { getattr } for pid=7480 comm="qemu-ifup" path="/sbin/ifconfig" dev=dm-0 ino=884801 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.636:5): avc: denied { execute } for pid=6484 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.637:6): avc: denied { read } for pid=6484 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.637:7): avc: denied { execute } for pid=6484 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.638:8): avc: denied { read } for pid=6484 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.638:9): avc: denied { execute } for pid=6499 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.640:10): avc: denied { execute } for pid=6499 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.640:11): avc: denied { read } for pid=6499 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.715:12): avc: denied { execute } for pid=6511 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230302990.715:13): avc: denied { read } for pid=6511 comm="qemu-ifup" name="ifconfig" dev=dm-0 ino=884801 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230303496.435:11): avc: denied { execute_no_trans } for pid=6912 comm="qemu-ifup" path="/sbin/ifconfig" dev=dm-0 ino=884801 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:ifconfig_exec_t:s0 tclass=file type=1400 audit(1230303496.438:12): avc: denied { read } for pid=6912 comm="ifconfig" name="net" dev=proc ino=4026531869 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:proc_net_t:s0 tclass=lnk_file type=1400 audit(1230303496.438:13): avc: denied { read } for pid=6912 comm="ifconfig" name="unix" dev=proc ino=4026531984 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:proc_net_t:s0 tclass=file type=1400 audit(1230303496.438:14): avc: denied { create } for pid=6912 comm="ifconfig" scontext=unconfined_u:system_r:qemu_t:s0 tcontext=unconfined_u:system_r:qemu_t:s0 tclass=unix_dgram_socket type=1400 audit(1230303496.439:15): avc: denied { search } for pid=6912 comm="ifconfig" scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:sysctl_net_t:s0 tclass=dir type=1400 audit(1230303496.503:16): avc: denied { getattr } for pid=6898 comm="qemu-kvm" path="/dev/mapper/system-fiat" dev=tmpfs ino=590 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:fixed_disk_device_t:s0 tclass=blk_file type=1400 audit(1230303496.503:17): avc: denied { read write } for pid=6898 comm="qemu-kvm" name="system-fiat" dev=tmpfs ino=590 scontext=unconfined_u:system_r:qemu_t:s0 tcontext=system_u:object_r:fixed_disk_device_t:s0 tclass=blk_file This translates to the following rules: module local 1.0; require { type proc_net_t; type ifconfig_exec_t; type etc_t; type qemu_t; type port_t; type bin_t; type fixed_disk_device_t; type shell_exec_t; type sysctl_net_t; class lnk_file read; class capability net_admin; class file { getattr read execute execute_no_trans }; class blk_file { read write getattr }; class unix_dgram_socket create; class dir search; } #============= qemu_t ============== allow qemu_t bin_t:file { read getattr execute execute_no_trans }; allow qemu_t etc_t:file { execute execute_no_trans }; allow qemu_t fixed_disk_device_t:blk_file { read write getattr }; allow qemu_t ifconfig_exec_t:file { read getattr execute execute_no_trans }; allow qemu_t proc_net_t:file read; allow qemu_t proc_net_t:lnk_file read; allow qemu_t self:capability net_admin; allow qemu_t self:unix_dgram_socket create; allow qemu_t shell_exec_t:file { read execute }; allow qemu_t sysctl_net_t:dir search; Also, previously KVM hardcoded the script "/etc/qemu-ifup" to set up the network. This path now has to be explicitly configured. This might mean it need some special SELinux context.
/dev/mapper/system-fiat needs to be labeled virt_image_t # semanage fcontext -a -t virt_image_t /dev/mapper/system-fiat # restorecon /dev/mapper/system-fiat Should fix this. Daniel, this is what I was talking about using the qemu both for setup and the actual running of the qemu leads to excessive privs required for qemu.
If we ever hope to confine what a qemu process is doing, we need to separate out the setup from the running of the guest OS. So we need to processes run. libvirt_t->qemu_setup_t->qemu_t Running one process that sets up the guest os and then running the guest os, will force us to allow the guest os process the ability to manipulate the hosts networking. So if someone breaks out of the guest os, he will be able to change the network on the host machine.
Ahhhh, I understand what you mean now. So 'qemu' would start with 'qemu_setup_t' domain, and then 'drop privileges' by transitioning to the 'qemu_t'. The hard thing here is that you can hot-plug lots of virtual hardware, adding/removing NICs and Disks on the fly. Many deployment scenarios won't care about hotplug though, so we could certainly restrict them. NB for networking the normal case libvirtd will do the networking setup, passing QEMU a pre-opened & configured TAP device FD. Running shell scripts for setting up networking is only for when QEMU is launched outside context of libvirt.
(In reply to comment #2) > /dev/mapper/system-fiat needs to be labeled virt_image_t > > # semanage fcontext -a -t virt_image_t /dev/mapper/system-fiat > # restorecon /dev/mapper/system-fiat > > Should fix this. I'll give that a try. Oddly enough though, there were three other guests started after this with the same context for the storage, yet only this first one generated avc messages. Is there some filtering going on in the audit output? (In reply to comment #4) > NB for networking the normal case libvirtd will do the networking setup, > passing QEMU a pre-opened & configured TAP device FD. Running shell scripts for > setting up networking is only for when QEMU is launched outside context of > libvirt. No, not only. In my case I use libvirt and a <script/> addition in the <interface/>. I do this to get a routed guest, something that libvirt isn't supporting directly.
There's a lot to be said for having qemu/kvm/etc networking set up in _advance_ by the standard network scripts, using persistent tun devices. Then all qemu would have to do would be to open it and send packets; no actual configuration (even in libvirtd).
Any news here?
dwalsh: the problem here appears to be the use of a script to configure the tap interface e.g. <interface type='ethernet'> <target dev='vnet7'/> <script path='/etc/qemu-ifup-mynet'/> </interface> pierre: could you attach your domain's XML configuration and the network script?
IMHO, it is simply not practical to support SELinux enforcing mode when using type='ethernet'. The config will be executing arbitrary shell scripts and as such we have no way of knowing what the user will want to be able todo in these scripts. In addition allowing the running of arbitrary network commands from these scripts will compromise the security of all other QEMU configs, by allowing QEMU to execute ifcfg / ip commands that it should not ordinarily be allowed todo. The most practical option here is to determine how to support the desired network config directly in libvirtd, avoiding the need to run a guest with type='ethernet' config, and avoiding need for QEMU to be given ability to run arbitrary networking commands.
Fair enough - moving to upstream libvirt pierre: given danpb's comment, we need information on your configuration so that we can try and support this in libvirt without the need for a qemu-ifup script
My desires are fairly simple. I want my machines to be routed via the host, not bridged or any libvirt specific magic. My script is nothing special, only that it computes the IP configuration based on the if name (to keep things simple). It is acceptable to have to enter the host side configuration for each guest in a generic solution though. Example of one network configuration: <interface type='ethernet'> <mac address='00:16:3e:00:00:02'/> <script path='/etc/libvirt/qemu/ifup'/> <target dev='virt11'/> <model type='virtio'/> </interface> The "ifup" script: #!/bin/bash if ! echo $1 | grep "^virt[0-9]\+$" > /dev/null; then exit fi NUM=`echo $1 | sed 's%virt\([0-9]\+\)%\1%'` IPADDR=10.8.3.$[ $NUM * 8 + 1 ] NETMASK=255.255.255.248 ifconfig $1 $IPADDR netmask $NETMASK
Has anyone had a chance to look at this?
It is now worse than before - QEMU now runs unprivileged, so network scripts have non of the capabilities required to configure networking http://www.redhat.com/archives/libvir-list/2009-November/msg00336.html
Well thanks for that. Is anyone working on a solution that will support routed guests?
Ping! Any comments? You can't really go and remove a common use case like that without providing any alternatives.
In 0.8.2, /etc/libvirt/qemu.conf allows you to run with VMs with full capabilities clear_emulator_capabilities = 0 user = "root" group = "root" This is of course horribly insecure, but that's only option for direct use of qemu's ifup scripts.