Without disabling SELinux enforcement, an attempt to deploy a VM generates the following audit message:
type=AVC msg=audit(1504194626.938:877): avc: denied { transition } for pid=9574 comm="libvirtd" path="/usr/local/bin/qemu-system-x86_64" dev="dm-19" ino=31526884 scontext=system_u:system_r:spc_t:s0 tcontext=system_u:system_r:svirt_tcg_t:s0:c408,c741 tclass=process |
Running this through audit2allow provides a little more visibility into the problem:
#============= spc_t ============== #!!!! The file '/usr/local/bin/qemu-system-x86_64' is mislabeled on your system. #!!!! Fix with $ restorecon -R -v /usr/local/bin/qemu-system-x86_64 allow spc_t svirt_tcg_t:process transition; |
This is probably due to running as much of the virtualization machinery in containers. /usr/local/bin/qemu-system-x86_64 comes from inside the libvirt container. It does not exist on the base OS filesystem. Thus, just running restorecon won’t do much.
While it is tempting to make this change and hope that everything works, I’ve learned that SELinux is dilligent enough that, if one thing fails, it is usually a few related things that are actually failing, and just dealing with the first is not enough. settting SELinux into permissive mode ande deploying a VM produces a much longer list of avcs. Runnning these through audit2allow generates the following:
#============= spc_t ============== #!!!! The file '/usr/local/bin/qemu-system-x86_64' is mislabeled on your system. #!!!! Fix with $ restorecon -R -v /usr/local/bin/qemu-system-x86_64 allow spc_t svirt_tcg_t:process transition; #============= svirt_lxc_net_t ============== allow svirt_lxc_net_t svirt_tcg_t:dir { getattr open read search }; allow svirt_lxc_net_t svirt_tcg_t:file { getattr open read }; #============= svirt_tcg_t ============== allow svirt_tcg_t cgroup_t:file { getattr open write }; #!!!! The file '/dev/ptmx' is mislabeled on your system. #!!!! Fix with $ restorecon -R -v /dev/ptmx allow svirt_tcg_t container_devpts_t:chr_file open; #!!!! The file '/run/docker.sock' is mislabeled on your system. #!!!! Fix with $ restorecon -R -v /run/docker.sock allow svirt_tcg_t container_runtime_t:unix_stream_socket connectto; allow svirt_tcg_t self:capability { audit_write dac_override net_admin setgid setuid sys_ptrace sys_resource }; allow svirt_tcg_t self:netlink_audit_socket { create nlmsg_relay }; allow svirt_tcg_t spc_t:fifo_file { getattr ioctl write }; allow svirt_tcg_t svirt_lxc_net_t:dir search; allow svirt_tcg_t svirt_lxc_net_t:file { getattr open read }; allow svirt_tcg_t svirt_lxc_net_t:lnk_file read; allow svirt_tcg_t sysfs_t:filesystem getattr; #!!!! WARNING: 'unlabeled_t' is a base type. allow svirt_tcg_t unlabeled_t:dir { add_name mounton read remove_name write }; #!!!! WARNING: 'unlabeled_t' is a base type. #!!!! The file '/usr/local/bin/qemu-system-x86_64' is mislabeled on your system. #!!!! Fix with $ restorecon -R -v /usr/local/bin/qemu-system-x86_64 allow svirt_tcg_t unlabeled_t:file { append create entrypoint execute execute_no_trans getattr ioctl lock open read unlink write }; allow svirt_tcg_t unlabeled_t:lnk_file read; |
While audit2allow will get you going again, it often produces a policy that is too permissive. Before blindly accepting this new policy, we need to look through it and figure out if there are better policy rules that acheive the same ends.
Many of the rules look sane on a first glance. For example,
allow svirt_tcg_t container_runtime_t:unix_stream_socket connectto; |
allowing a file with the label svirt_tcg_t and the process runtime label of container_runtime to talk to a unix domain socket is obviously required to perform libvirt based tasks.
I suspect that the right solution involves modifying the libvirt container definition to properly set the SELinux context internally, as well as possibly adding something to the manifest for the daemonset to honor/carry forward the SELinux values.