From b72a4ec6f2dad47c285a1e91e7c712131f743049 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Wed, 10 Jun 2026 18:29:58 +0900 Subject: [PATCH] platform/local/tpm: create swtpm socket in temp directory under /tmp The swtpm unix socket was created relative to the test output directory under _kola_temp/, which triggers AppArmor denials for the swtpm profile on systems with AppArmor enabled: - mantle debug log: 2026-06-10T08:40:19Z util: dnsmasq-dhcp[30]: RTR-SOLICIT(kola-2616517) 6e:2a:7b:93:45:aa === RUN cl.tpm.eventlog 2026-06-10T08:40:22Z platform/local: Prepared swtpm process "/usr/bin/swtpm socket --tpmstate dir=./tpm --ctrl type=unixio,path=./tpm/socket --tpm2" with CWD "_kola_temp/qemu-2026-06-10-0840-13/cl.tpm.eventlog/e2eba778-2553-4563-a150-2e2e40d61639" 2026-06-10T08:40:22Z platform/local: swtpm PID: 40 2026-06-10T08:40:22Z util: swtpm: Could not open UnixIO socket: Permission denied 2026-06-10T08:40:22Z platform: disabling auto-read-only for QEMU drives 2026-06-10T08:40:22Z platform/machine/qemu: NewMachine: ["qemu-system-aarch64" "-machine" "virt" "-cpu" "cortex-a57" "-m" "2512" "-smp" "4" "-uuid" "e2eba778-2553-4563-a150-2e2e40d61639" "-display" "none" "-chardev" "file,id=log,path=console.txt" "-serial" "chardev:log" "-object" "rng-random,filename=/dev/urandom,id=rng0" "-device" "virtio-rng-pci,rng=rng0" "-drive" "if=pflash,unit=0,file=/work/__build__/images/images/arm64-usr/latest/flatcar_production_qemu_uefi_efi_code.qcow2,format=qcow2,readonly=on" "-drive" "if=pflash,unit=1,file=flatcar_production_qemu_uefi_efi_vars.qcow2,format=qcow2" "-chardev" "socket,id=chrtpm,path=tpm/socket" "-tpmdev" "emulator,id=tpm0,chardev=chrtpm" "-device" "tpm-tis-device,tpmdev=tpm0" "-fw_cfg" "name=opt/org.flatcar-linux/config,file=ignition.json" "-add-fd" "fd=3,set=1" "-drive" "if=none,id=d3,format=qcow2,file=/dev/fdset/1,auto-read-only=off" "-device" "virtio-blk-device,drive=d3,serial=primary-disk,bootindex=1" "-netdev" "tap,id=tap,fd=4" "-device" "virtio-net-device,netdev=tap,mac=02:00:00:00:00:02"], cwd: "_kola_temp/qemu-2026-06-10-0840-13/cl.tpm.eventlog/e2eba778-2553-4563-a150-2e2e40d61639", "10.0.0.2", "10.0.0.2" 2026-06-10T08:40:22Z platform/machine/qemu: qemu PID (manual cleanup needed if --remove=false): 50 qemu-system-aarch64: -chardev socket,id=chrtpm,path=tpm/socket: Failed to connect to 'tpm/socket': No such file or directory 2026-06-10T08:40:23Z util: dnsmasq-dhcp[30]: RTR-SOLICIT(kola-2616517) 6e:2a:7b:93:45:aa 2026-06-10T08:40:28Z util: dnsmasq-dhcp[30]: RTR-ADVERT(br0) fd00:: - host kernel audit: journalctl -xe | grep 'DENIED.*swtpm' | tail -n 20 Jun 10 17:40:22 localhost kernel: audit: type=1400 audit(1781080822.038:163): apparmor="DENIED" operation="mknod" class="file" profile="swtpm" name="/work/__TESTS__/qemu_uefi/_kola_temp/qemu-2026-06-10-0840-13/cl.tpm.eventlog/e2eba778-2553-4563-a150-2e2e40d61639/tpm/socket" pid=1828693 comm="swtpm" requested_mask="c" denied_mask="c" fsuid=0 ouid=0 Jun 10 17:43:39 localhost kernel: audit: type=1400 audit(1781081019.925:164): apparmor="DENIED" operation="mknod" class="file" profile="swtpm" name="/work/__TESTS__/qemu_uefi/_kola_temp/qemu-2026-06-10-0840-13/cl.tpm.eventlog/e2eba778-2553-4563-a150-2e2e40d61639/tpm/socket" pid=1828926 comm="swtpm" requested_mask="c" denied_mask="c" fsuid=0 ouid=0 Jun 10 17:43:47 localhost kernel: audit: type=1400 audit(1781081027.251:165): apparmor="DENIED" operation="mknod" class="file" profile="swtpm" name="/work/__TESTS__/qemu_uefi/_kola_temp/qemu-2026-06-10-0840-13/cl.tpm.eventlog/e2eba778-2553-4563-a150-2e2e40d61639/tpm/socket" pid=1828943 comm="swtpm" requested_mask="c" denied_mask="c" fsuid=0 ouid=0 The test runs inside a container managed by run_local_tests.sh which mounts the current directory into the container. The socket created under the mounted directory is subject to the host's AppArmor policy for the swtpm profile. Create the socket in a temporary directory under /tmp/ instead, using os.MkdirTemp. This avoids the AppArmor restriction and prevents collisions between concurrent test runs. The SocketRelativePathFromTestDir method is renamed to SocketPath and now returns an absolute path, since the socket is no longer placed relative to the test directory. Signed-off-by: Li Zhijian --- platform/local/tpm.go | 22 +++++++--------------- platform/machine/qemu/cluster.go | 2 +- platform/machine/unprivqemu/cluster.go | 2 +- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/platform/local/tpm.go b/platform/local/tpm.go index 1924dc9ba..7743739f6 100644 --- a/platform/local/tpm.go +++ b/platform/local/tpm.go @@ -13,23 +13,16 @@ import ( type SoftwareTPM struct { process *exec.ExecCmd dirFromKolaCwd string - dirFromTestDir string } func NewSwtpm(testDir string, tpmDir string) (*SoftwareTPM, error) { - dirFromKolaCwd := filepath.Join(testDir, tpmDir) - swtpm := &SoftwareTPM{dirFromKolaCwd: dirFromKolaCwd, dirFromTestDir: tpmDir} - - if err := os.Mkdir(swtpm.dirFromKolaCwd, 0700); err != nil { - return nil, fmt.Errorf("Failed to create TPM dir: %v", err) + dirFromKolaCwd, err := os.MkdirTemp("", "mantle-tpm-") + if err != nil { + return nil, fmt.Errorf("Failed to create TPM temp dir: %v", err) } + swtpm := &SoftwareTPM{dirFromKolaCwd: dirFromKolaCwd} - swtpm.process = exec.Command("swtpm", "socket", "--tpmstate", fmt.Sprintf("dir=./%v", swtpm.dirFromTestDir), "--ctrl", fmt.Sprintf("type=unixio,path=./%v", swtpm.SocketRelativePathFromTestDir()), "--tpm2") - // Use the test directory as current working directory - // so that we don't have a socket path argument that - // exceeds 108 chars which is the limit for UNIX sockets - // (Using ./ as prefix helps to know that these are relative - // path arguments). + swtpm.process = exec.Command("swtpm", "socket", "--tpmstate", fmt.Sprintf("dir=%v", swtpm.dirFromKolaCwd), "--ctrl", fmt.Sprintf("type=unixio,path=%v", swtpm.SocketPath()), "--tpm2") swtpm.process.Dir = testDir plog.Debugf("Prepared swtpm process %q with CWD %q", swtpm.process, swtpm.process.Dir) out, err := swtpm.process.StderrPipe() @@ -55,7 +48,6 @@ func (swtpm *SoftwareTPM) Stop() { os.RemoveAll(swtpm.dirFromKolaCwd) } -func (swtpm *SoftwareTPM) SocketRelativePathFromTestDir() string { - const socket string = "socket" - return filepath.Join(swtpm.dirFromTestDir, socket) +func (swtpm *SoftwareTPM) SocketPath() string { + return filepath.Join(swtpm.dirFromKolaCwd, "socket") } diff --git a/platform/machine/qemu/cluster.go b/platform/machine/qemu/cluster.go index 26c1bd366..606787eb4 100644 --- a/platform/machine/qemu/cluster.go +++ b/platform/machine/qemu/cluster.go @@ -124,7 +124,7 @@ ExecStartPost=/usr/bin/ln -fs /run/metadata/flatcar /run/metadata/coreos if err != nil { return nil, fmt.Errorf("starting swtpm: %v", err) } - options.SoftwareTPMSocket = swtpm.SocketRelativePathFromTestDir() + options.SoftwareTPMSocket = swtpm.SocketPath() defer func() { if swtpm != nil { swtpm.Stop() diff --git a/platform/machine/unprivqemu/cluster.go b/platform/machine/unprivqemu/cluster.go index dc5ebfcbe..0579f4f5a 100644 --- a/platform/machine/unprivqemu/cluster.go +++ b/platform/machine/unprivqemu/cluster.go @@ -137,7 +137,7 @@ LinkLocalAddressing=no if err != nil { return nil, fmt.Errorf("starting swtpm: %v", err) } - options.SoftwareTPMSocket = swtpm.SocketRelativePathFromTestDir() + options.SoftwareTPMSocket = swtpm.SocketPath() defer func() { if swtpm != nil { swtpm.Stop()