SELinux Workarounds for binaries with the wrong label

You may have ran into issues with SELinux when using certain programs. On the discord, swtpm has popped up several times. Greetd and waydroid also have this issue (See OCI SELinux labeling mismatch when package only ships binary policy - greetd is broken · Issue #510 · ostreedev/ostree-rs-ext · GitHub, Bazzite Waydroid Setup Guide). The issue for swtpm specifically is that the SELinux label is not updated during OCI build time. While upstream works on this issue, we can use the following workaround (note: this has only been tested with swtpm)

Our workaround is to take a copy of the binary, bind mount it over the mislabeled binary, and then restorecon it in place. Effectively, we have made this portion of /usr now mutable.

To have this happen each time on boot, you can use the following systemd oneshot service.

# /etc/systemd/system/swtpm-workaround.service
[Unit]
Description=Workaround swtpm not having the correct label
ConditionFileIsExecutable=/usr/bin/swtpm
After=local-fs.target

[Service]
Type=oneshot
ExecStartPre=/usr/bin/bash -c "[ -x /usr/local/bin/.swtpm ] || /usr/bin/cp /usr/bin/swtpm /usr/local/bin/.swtpm"
ExecStartPre=/usr/bin/mount --bind /usr/local/bin/.swtpm /usr/bin/swtpm
ExecStart=/usr/sbin/restorecon /usr/bin/swtpm
ExecStartPost=/usr/bin/ls -lZ /usr/bin/swtpm
ExecStop=/usr/bin/umount /usr/bin/swtpm
ExecStop=/usr/bin/rm /usr/local/bin/.swtpm
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

For swtpm specifically to work as well, you need to make sure that the /var/lib/swtpm-localca directory exists and is readable/writeable by user tss.

With these in place, you are able to now use swtpm with your VMs.


← View Universal Blue General Documentation

1 Like

The Ganto/lxc4 COPR has recently landed SELinux support for Incus.

Unfortunately, you will need to take some additional steps to make sure it will work. You need at least the incus rpm versioned 4.0.4 for support.

These are the following additional steps you will need to make:

  1. You need to make sure the binaries in /usr have the correct file contexts. You can do this by adapting the above systemd service. Here’s an example:
# /etc/systemd/system/incus-workaround.service
[Unit]
Description=Workaround SELinux issues with Incus...
ConditionPathExists=/usr/bin/incus
ConditionPathExists=/usr/bin/incus-agent
ConditionPathExists=/usr/lib/incus
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/bin/mount --bind -o rw /usr/bin/incus /usr/bin/incus
ExecStart=/usr/bin/mount --bind -o rw /usr/bin/incus-agent /usr/bin/incus-agent
ExecStart=/usr/bin/mount --bind -o rw /usr/lib/incus /usr/lib/incus
ExecStart=/usr/sbin/restorecon -R -v /usr/bin/incus
ExecStart=/usr/sbin/restorecon -R -v /usr/bin/incus-agent
ExecStart=/usr/sbin/restorecon -R -v /usr/lib/incus
ExecStart=/usr/bin/umount /usr/bin/incus
ExecStart=/usr/bin/umount /usr/bin/incus-agent
ExecStart=/usr/bin/umount /usr/lib/incus
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

Next, you will need to make sure what is already in /var has the correct labels. You can fix these by running the following commands:

# restorecon -R -v /var/lib/incus
# restorecon -R -v /var/log/incus

Make sure you’ve enabled the service. You can do a reboot and will be able to start the incus socket and service. Have fun using Incus to manage system containers and VMs.