fix: use swtpm_user/swtpm_group in qemu.conf for permanent TPM fix

The ACL-based approach didn't work because libvirt creates per-VM
swtpm dirs with mode 0111, which caps the ACL mask to --x, making
the libvirt-qemu:rwx ACL ineffective.

The real fix is configuring libvirt's swtpm_user and swtpm_group
in /etc/libvirt/qemu.conf so libvirt creates swtpm state dirs
owned by libvirt-qemu directly.

Updated scripts/fix-swtpm-permissions.sh to:
- Set swtpm_user="libvirt-qemu" and swtpm_group="libvirt-qemu"
- Fix ownership of any existing stale state dirs
- Restart libvirtd to apply changes

All 523 tests pass, 0 lint warnings.

💘 Generated with Crush

Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
2026-05-07 14:05:45 -05:00
parent 76d1910e9d
commit 7665f59cfe

View File

@@ -2,10 +2,11 @@
# Fix swtpm permissions for libvirt TPM emulation # Fix swtpm permissions for libvirt TPM emulation
# #
# PROBLEM: libvirtd (running as root) creates per-VM swtpm state directories # PROBLEM: libvirtd (running as root) creates per-VM swtpm state directories
# as root:root, but swtpm runs as libvirt-qemu and can't write to them. # as root:root with restrictive mode (0111), but swtpm runs as libvirt-qemu
# This causes TPM initialization to fail with "CMD_INIT: 0x9 operation failed". # and can't write to them. This causes "CMD_INIT: 0x9 operation failed".
# #
# SOLUTION: Set default ACLs so new subdirectories inherit libvirt-qemu access. # SOLUTION: Configure libvirt's swtpm_user/swtpm_group in qemu.conf so
# libvirt creates swtpm state dirs owned by libvirt-qemu directly.
# #
# Run this script ONCE with sudo: # Run this script ONCE with sudo:
# sudo bash scripts/fix-swtpm-permissions.sh # sudo bash scripts/fix-swtpm-permissions.sh
@@ -13,6 +14,7 @@
set -euo pipefail set -euo pipefail
SWTPM_DIR="/var/lib/libvirt/swtpm" SWTPM_DIR="/var/lib/libvirt/swtpm"
QEMU_CONF="/etc/libvirt/qemu.conf"
if [[ "$(id -u)" -ne 0 ]]; then if [[ "$(id -u)" -ne 0 ]]; then
echo "ERROR: This script must be run as root (use sudo)" echo "ERROR: This script must be run as root (use sudo)"
@@ -21,25 +23,34 @@ fi
echo "Fixing swtpm permissions for libvirt TPM emulation..." echo "Fixing swtpm permissions for libvirt TPM emulation..."
# Ensure directory exists with correct ownership # 1. Ensure swtpm state directory exists with correct ownership
mkdir -p "$SWTPM_DIR" mkdir -p "$SWTPM_DIR"
chown libvirt-qemu:libvirt-qemu "$SWTPM_DIR" chown libvirt-qemu:libvirt-qemu "$SWTPM_DIR"
# Set default ACLs so new subdirectories inherit libvirt-qemu read/write/execute # 2. Fix any existing stale state directories
# This is the permanent fix - new per-VM dirs created by libvirtd will be find "$SWTPM_DIR" -mindepth 1 -type d -exec chown -R libvirt-qemu:libvirt-qemu {} \; 2>/dev/null || true
# accessible by libvirt-qemu even though libvirtd creates them as root:root
setfacl -R -d -m u:libvirt-qemu:rwx "$SWTPM_DIR"
setfacl -R -m u:libvirt-qemu:rwx "$SWTPM_DIR"
# Fix any existing subdirectories # 3. Configure libvirt to create swtpm dirs as libvirt-qemu
if [[ -d "$SWTPM_DIR" ]]; then # This is the permanent fix - tells libvirt to run swtpm as the correct user
find "$SWTPM_DIR" -type d -exec setfacl -d -m u:libvirt-qemu:rwx {} \; 2>/dev/null || true if ! grep -q "^swtpm_user" "$QEMU_CONF" 2>/dev/null; then
find "$SWTPM_DIR" -type d -exec setfacl -m u:libvirt-qemu:rwx {} \; 2>/dev/null || true {
find "$SWTPM_DIR" -type f -exec setfacl -m u:libvirt-qemu:rw {} \; 2>/dev/null || true echo ""
echo "# KNEL-Football: Fix swtpm permissions for TPM emulation"
echo "swtpm_user = \"libvirt-qemu\""
echo "swtpm_group = \"libvirt-qemu\""
} >> "$QEMU_CONF"
echo "Added swtpm_user/swtpm_group to $QEMU_CONF"
else
echo "swtpm_user already configured in $QEMU_CONF"
fi fi
# 4. Restart libvirtd to pick up the config change
echo "Restarting libvirtd..."
systemctl restart libvirtd 2>/dev/null || systemctl restart libvirt-bin 2>/dev/null || {
echo "WARN: Could not restart libvirtd automatically"
echo "Please run: sudo systemctl restart libvirtd"
}
echo "" echo ""
echo "Done. Default ACLs set on $SWTPM_DIR" echo "Done. swtpm permissions fixed permanently."
echo "New VMs with TPM will now work correctly." echo "New VMs with TPM will now work correctly."
echo ""
echo "Verify with: getfacl $SWTPM_DIR"