Hide Forgot
Description of problem: Recently we added support for fd: protocol migration to libvirt, which means we create a TCP socket, connect it to destination qemu, and pass it using SCM_RIGHTS to source qemu (previously source qemu was opening the socket itself). To be able to send the socket to qemu, we need to label it but we are not allowed to. The attempt results in type=AVC msg=audit(1314013212.316:93716): avc: denied { relabelto } for pid=19499 comm="libvirtd" name="" dev=sockfs ino=636054 scontext=unconfined_u:system_r:virtd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:svirt_image_t:s0:c54,c853 tclass=tcp_socket type=SYSCALL msg=audit(1314013212.316:93716): arch=c000003e syscall=190 success=no exit=-13 a0=16 a1=3ea2216239 a2=7f64441a43f0 a3=2c items=0 ppid=1 pid=19499 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=1 comm="libvirtd" exe="/usr/sbin/libvirtd" subj=unconfined_u:system_r:virtd_t:s0-s0:c0.c1023 key=(null) Version-Release number of selected component (if applicable): selinux-policy-3.7.19-107.el6.noarch libvirt-0.9.4-?.el6 The patch that does correct labeling of the socket is not in libvirt yet (see bug 731243). As soon as it's there, I'll update this BZ with the right libvirt release to test with. How reproducible: 100% Steps to Reproduce: 1. create a domain 2. try to migrate it using non-peer2peer migration # virsh migrate DOM qemu+ssh://target/system Actual results: error: unable to set security context 'system_u:object_r:svirt_image_t:s0:c54,c853' on fd 22: Permission denied Expected results: Successfully labeled socket so that migration can proceed. Additional info:
We allow this for
(In reply to comment #1) > We allow this for I apologize. Bad window.
The following AVCs were reported when I tried running migration with selinux in permissive mode: type=AVC msg=audit(1314098069.651:94776): avc: denied { relabelto } for pid=19499 comm="libvirtd" name="" dev=sockfs ino=678882 scontext=unconfined_u:system_r:virtd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:svirt_image_t:s0:c54,c853 tclass=tcp_socket type=AVC msg=audit(1314098069.653:94777): avc: denied { read write } for pid=10369 comm="qemu-kvm" path="socket:[678882]" dev=sockfs ino=678882 scontext=system_u:system_r:svirt_t:s0:c54,c853 tcontext=system_u:object_r:svirt_image_t:s0:c54,c853 tclass=tcp_socket type=AVC msg=audit(1314098069.755:94778): avc: denied { write } for pid=10369 comm="qemu-kvm" path="socket:[678882]" dev=sockfs ino=678882 scontext=system_u:system_r:svirt_t:s0:c54,c853 tcontext=system_u:object_r:svirt_image_t:s0:c54,c853 tclass=tcp_socket
And does it work with rules from these AVC msgs in enforcing mode? allow svirt_t svirt_image_t:tcp_socket { read write } allow virtd_t virt_image_type:tcp_socket relabel_file_perms;
Running audit2allow on my system produced the following local.te which made the problem go away. (Disclaimer, my use of selinux is pretty mechanical.) module local 1.0; require { type virtd_t; type svirt_t; class fifo_file write; } #============= svirt_t ============== allow svirt_t virtd_t:fifo_file write;
2d disclaimer: this is an F15 system with upstream libvirt, not RHEL.
This is the wrong label it should not be setting virt tcp_socket to svirt_image_t? Sockets should be labeled svirt_t not svirt_image_t. Similarly the virtd_t should have been relabeled svirt_t.
OK, I changed the code to label TCP sockets as svirt_t but still some tweak to selinux-policy is needed: avc: denied { associate } for pid=5616 comm="libvirtd" name="" dev=sockfs ino=932613 scontext=system_u:system_r:svirt_t:s0:c355,c490 tcontext=system_u:object_r:fs_t:s0 tclass=filesystem which run through audit2allow suggests the following policy: module tcp_socket 1.0; require { type fs_t; type svirt_t; class filesystem associate; } #============= svirt_t ============== allow svirt_t fs_t:filesystem associate; With this policy in, I get no AVCs even in enforcing mode.
Stephen and Eric is this a bug? fd = socket(TCP), connect(fd, SOMEREMOTEHOST). setffilecon($fd, "svirt_t:MCS") Shouldn't this be allowed. Without having to allow process types to be assigned to filesystems? Looks like a pseudo file system is causing the problem?
It is a pseudo filesystem, sockfs, which you chose to call fs_t: fs_use_task sockfs system_u:object_r:fs_t:s0; Everything is on a filesystem :) It's no different than creating a file on ext3. You need associate permissions...
Well I don't want to do that. I am testing out doing it another way where I label the sockfs file system as sockfs_t and then allow domain sockfs_t:filesystem associate; Testing it in F17 now.
You can't change the label of a connected TCP socket as there are several access control points involved in establishing a connection and changing the label on the socket changes the label on the connection which could cause an already established connection to fail. In addition, changing the label on an established connection could cause unknown problems with the other end of the connection if labeled networking is in use. The correct solution would be to set the correct label on socket using setsockcreatecon() before the connection is established.
(In reply to comment #12) > You can't change the label of a connected TCP socket as there are several > access control points involved in establishing a connection and changing the > label on the socket changes the label on the connection which could cause an > already established connection to fail. OK, this is a very convincing explanation, I'll go the setsockcreatecon() way and see if that works as expected. If so, I'll close this BZ as NOTABUG.
Great, when setsockcreatecon() is used for labeling the TCP socket, everything works without any change to selinux-policy. I'm closing this BZ...