creating simple selinux module fails with assertion on line x violated by allow something_t fixed_disk_device_t

By thomas, 21 September, 2009
I'm still working with my own kvm implementation even though RedHat has released their own in RHEL 5.4, they are, however, at version 83, I'm on 88. I'd rather stay current since kvm is moving so fast that each new version fixes bugs and adds many new features.

I ran into a problem when applying the new selinux policy from RH, they have added support for qemu/kvm to the policy, which is great but blows up on my fibre channel disks. I tried to create an selinux module to fix the problem but kept getting this:

[root@hypervisor kvm]# semodule -i kvmmultipath.pp libsepol.check_assertion_helper: assertion on line 0 violated by allow qemu_t fixed_disk_device_t:blk_file { write }; libsepol.check_assertion_helper: assertion on line 0 violated by allow qemu_t fixed_disk_device_t:blk_file { read }; libsepol.check_assertions: 2 assertion violations occured libsemanage.semanage_expand_sandbox: Expand module failed semodule: Failed!
My te file looked like this:
module kvmmultipath 1.0; require { type fixed_disk_device_t; type qemu_t; class file { read write getattr }; class blk_file { read write getattr }; } #============= qemu_t ============== allow qemu_t fixed_disk_device_t:blk_file { read write getattr };
The problem here is that blk_file isn't just a simple class, it relies on file. I tried including file, but that didn't work either. The solution was to read the manual :-( and use the devel package. I installed selinux-policy-devel and looked at the include files, the one of interest here is /usr/share/selinux/devel/include/kernel/storage.if which defines a interfaces called storage_raw_read_fixed_disk and storage_raw_write_fixed_disk. Using these interfaces instead of the allow statement fixed the problem. To use these interfaces, I had to change the policy definition to use the macro policy_module also. I then used the Makefile in devel to make the module.
policy_module(kvmmultipath, 1.0); require { type fixed_disk_device_t; type qemu_t; class file { read write getattr }; class blk_file { read write getattr }; } #============= qemu_t ============== storage_raw_read_fixed_disk(qemu_t); storage_raw_write_fixed_disk(qemu_t);
To build the module:
[root@hypervisor kvm]# pwd /usr/share/selinux/devel/kvm [root@hypervisor kvm]# ls kvmmultipath.te [root@hypervisor kvm]# make -f ../Makefile Compiling targeted kvmmultipath module /usr/bin/checkmodule: loading policy configuration from tmp/kvmmultipath.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/kvmmultipath.mod Creating targeted kvmmultipath.pp policy package rm tmp/kvmmultipath.mod.fc tmp/kvmmultipath.mod [root@hypervisor kvm]# semodule -i kvmmultipath.pp

Yay, kvm's can access the fibre channel again..now to upgrade the rest of the hypervisors.