Skip to content

SELinux Policy Development

Stefan Berger edited this page May 5, 2024 · 7 revisions

For the SELinux policy development the following command lines have been useful:

# Disable the don't audit statements in the policy to see everything that fails
> sudo semodule --disable_dontaudit --build

# Have audit2allow create a policy with all the rules that fail; then fish out the
# rules that are relevant for swtpm, which are those related to svirt_t and svirt_tcg_t
> audit2allow -i /var/log/audit/audit.log -l -M mypolicy

# move swtpm related rules from mypolicy.te into src/selinux/swtpm_svirt.te
> gedit mypolicy.te src/selinux/swtpm_svirt.te

# build the SELinux policy packages
> make -j4

# Remove the old swtpm SELinux policy packages
> sudo semodule --remove swtpm_libvirt swtpm_svirt swtpm

# Load the new swtpm SELinux policy packages
> sudo semodule --install src/selinux/swtpm.pp.bz2 src/selinux/swtpm_svirt.pp.bz2 src/selinux/swtpm_libvirt.pp.bz2

# At the end go back to enabling the don't audit rules
> sudo semodule --build

The following script is useful to exercising some of the interactions of libvirt with swtpm and swtpm with the system:

Note: Modify auditd's service script to enable restarts

#!/usr/bin/env bash

virsh undefine PLAIN-TPM-VM
virsh define plainvm.xml

rm -rf /var/log/audit/audit.log
systemctl restart auditd

virsh start PLAIN-TPM-VM
virsh save PLAIN-TPM-VM myvm.bin
virsh restore myvm.bin
virsh destroy PLAIN-TPM-VM --remove-logs
virsh undefine PLAIN-TPM-VM

audit2allow -i /var/log/audit/audit.log -l -M mypolicy
cat mypolicy.te

Notes:

  • Remove contents of /var/lib/swtpm-localca for rules that may only be needed once.
  • Some user may have access /run/user/*/libvirt/qemu/run/swtpm and require rules related to user_tmp_t

Use the following domain XML:

<domain type='kvm'>
  <name>PLAIN-TPM-VM</name>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>512288</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64'>hvm</type>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
  </features>
  <cpu mode='custom' match='exact' check='none'>
    <model fallback='forbid'>qemu64</model>
  </cpu>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/plainvm.raw'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <controller type='usb' index='0' model='piix3-uhci'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <tpm model='tpm-crb'>
      <backend type='emulator' version='2.0'/>
    </tpm>
    <graphics type='vnc' port='-1' autoport='yes'>
      <listen type='address'/>
    </graphics>
    <audio id='1' type='none'/>
    <video>
      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </memballoon>
  </devices>
</domain>