Fedora 40: Systemd cannot fix SELinux security context because it is blocked by SELinux itself

I am using Looking Glass in a VFIO gaming PC setup.

Looking Glass would create /dev/kvmfr0 on boot. It is a special file on host that is accessed and written by the VFIO VM (AFAIK).

❯ ls /dev/kvmfr0 -lZ  
crw-rw----. 1 eleung kvm system_u:object_r:device_t:s0 239, 0 Jan  3 02:03 /dev/kvmfr0

Since SELinux blocks the access by default, I changed the label of /dev/kvmfr0 to svirt_tmpfs_t (which allows VM processes to access it):

sudo semanage fcontext -a -t svirt_tmpfs_t /dev/kvmfr0
sudo restorecon -v /dev/kvmfr0

This works on the first time. However, the labeling is lost after a reboot, and manually running restorecon fails because SELinux blocks it.

dmesg log:

❯ sudo dmesg | grep kvmfr
[    1.470613] kvmfr: loading out-of-tree module taints kernel.
[    1.470616] kvmfr: module verification failed: signature and/or required key missing - tainting kernel
[    1.470798] kvmfr: creating 1 static devices
[    1.481651] kvmfr: kvmfr_module_init: module loaded
[    3.812541] systemd[1]: Unable to fix SELinux security context of /dev/kvmfr0: Permission denied
[    3.812545] audit: type=1400 audit(1735841030.299:4): avc:  denied  { associate } for  pid=1 comm="systemd" name="kvmfr0" dev="devtmpfs" ino=253 scontext=system_u:object_r:svirt_tmpfs_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=filesystem permissive=0

I am not sure about the implication of running audit2allow against this blocked relabeling action. What should I do here?

The labeling shouldn’t be lost on a reboot (at least not the way you’ve done it). What is the output of semanage -o -? (after you’ve rebooted)

This is the output:

❯ sudo semanage -o -     
boolean -D
login -D
interface -D
user -D
port -D
node -D
fcontext -D
module -D
ibendport -D
ibpkey -D
permissive -D
boolean -m -1 selinuxuser_execmod
boolean -m -1 virt_sandbox_use_all_caps
boolean -m -1 virt_use_nfs
fcontext -a -f a -t svirt_tmpfs_t -r 's0' '/dev/kvmfr0'

So the rule is still there after a reboot. What systemd service is trying to fix the permissions? What command exactly is it executing?

It looks like it would grant anything running with the svirt_tmpfs_t access to anything labeled device_t:

# echo 'type=1400 audit(1735841030.299:4): avc:  denied  { associate } for  pid=1 comm="systemd" name="kvmfr0" dev="devtmpfs" ino=253 scontext=system_u:object_r:svirt_tmpfs_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=filesystem permissive=0' | audit2allow -m allow-svirt-assoc

module allow-svirt-assoc 1.0;

require {
	type device_t;
	type svirt_tmpfs_t;
	class filesystem associate;
}

#============= svirt_tmpfs_t ==============

allow svirt_tmpfs_t device_t:filesystem associate;

If you are OK with that, just change -m to -M in the above command and it should generate a policy module that you can install with semodule -i allow-svirt-assoc.pp (you’ll need to have the selinux-policy-devel package installed). It doesn’t look too bad to me, but it depends on what runs as svirt_tmpfs_t and whether you want to trust it with access to your devices.