stefanberger / swtpm

Libtpms-based TPM emulator with socket, character device, and Linux CUSE interface.
Other
582 stars 143 forks source link

openSUSE: TPM 1.2 not working with libvirt/qemu, swtpm_setup exit status 1, no log created #284

Closed kailiu42 closed 4 years ago

kailiu42 commented 4 years ago

After added a TPM 1.2 TIS emulated device, the VM cannot be started, with below errors in a popup dialog.

Error messages:

Error starting domain: internal error: Could not run '/usr/bin/swtpm_setup'. exit status: 1; Check error log '/var/log/swtpm/libvirt/qemu/testvm-swtpm.log' for details.

Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 75, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 111, in tmpcb
    callback(*args, **kwargs)
  File "/usr/share/virt-manager/virtManager/object/libvirtobject.py", line 66, in newfn
    ret = fn(self, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/object/domain.py", line 1281, in startup
    self._backend.create()
  File "/usr/lib64/python3.8/site-packages/libvirt.py", line 1234, in create
    if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirt.libvirtError: internal error: Could not run '/usr/bin/swtpm_setup'. exitstatus: 1; Check error log '/var/log/swtpm/libvirt/qemu/testvm-swtpm.log' for details.

The log file mentioned in the error is empty. With a TPM 2.0 TIS emulated device the VM can start and use the vTPM device normally.

The OS is openSUSE Tumbleweed. Since it's a rolling release distro there is no distro version. It's up to date as of 20200723. Key related component versions:

The domain XML file is as below:

<domain type='kvm'>
  <name>testvm</name>
  <uuid>9bf6ea0c-d3ec-4a76-8fdc-9c1aa986b505</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-5.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
    </hyperv>
    <vmport state='off'/>
  </features>
  <cpu mode='host-model' check='partial'/>
  <clock offset='localtime'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <timer name='hypervclock' present='yes'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/testvm.qcow2'/>
      <target dev='sda' bus='sata'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/mnt/data/Downloads/soft/Windows/cn_windows_10_business_editions_version_2004_updated_may_2020_x64_dvd_c2acd212.iso'/>
      <target dev='sdb' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <controller type='usb' index='0' model='qemu-xhci' ports='15'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x10'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='2' port='0x11'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x12'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0x13'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
    </controller>
    <controller type='pci' index='5' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='5' port='0x14'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:3a:56:7f'/>
      <source bridge='virbr0'/>
      <model type='e1000e'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <tpm model='tpm-tis'>
      <backend type='emulator' version='1.2'/>
    </tpm>
    <graphics type='spice' autoport='yes'>
      <listen type='address'/>
      <image compression='off'/>
    </graphics>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
    </memballoon>
  </devices>
</domain>
stefanberger commented 4 years ago

I would need your help verifying that the modifications I have made to swtpm_setup work for you on openSUSE. I have tried them inside a VM and they work for me at least.

Swtpm needs to be patched for TPM 1.2 support on openSUSE, which has tcsd (of trousers package) differently configured than for example Fedora has it seems.

Besides that there are some complications due to the installation of trousers (probably) not creating tss user and tss group likely because /dev/tpm0 is not on the system, at least it wasn't on the system I used.

I suppose you have a working version of libtpms, but here are now openSUSE build instructions for libtpms: https://github.com/stefanberger/libtpms/wiki#compile-and-install-on-opensuse-tumbleweed

For swtpm I created a branch with a few fixes for swtpm_setup. I will merge them into master and backport to the stable-0.3.0 branch.

Can you now do the following (after uninstalling the swtpm package you have used)

cd swtpm
git checkout origin/swtpm_setup_tcsd_interface_fixes -b swtpm_setup_tcsd_interface_fixes
make clean

From then on please follow the instructions here: https://github.com/stefanberger/swtpm/wiki#compile-and-install-on-opensuse-tumbleweed

Now you should have a working swtpm installation.

Please edit /etc/libvirt/qemu.conf to look like this:

[...]
# User for the swtpm TPM Emulator
#
# Default is 'tss'; this is the same user that tcsd (TrouSerS) installs
# and uses; alternative is 'root'
#
swtpm_user = "root"
swtpm_group = "tss"
[...]

Restart libvirt:

systemctl restart libvirt

Now try to start your VM.

If it doesn't start and the log indicates some access issues the following should help set the access to directory and files correctly following the change in user/group configuration to root/tss:

sudo chown -R root:tss /var/lib/swtpm-localca

Please let me know if this works for you. I have tried this inside a VM and it does resolve the issue for me.

Partially this is a packaging problem, so the following should happen (I think) besides the patches to swtpm:

stefanberger commented 4 years ago

I have used this domain XML:

<domain type='qemu'>
  <name>testvm</name>
  <uuid>e8a25bed-e4ce-4d68-b0c1-c202c6743e7f</uuid>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>2097152</currentMemory>
  <vcpu placement='static'>4</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-i440fx-5.0'>hvm</type>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <cpu mode='custom' match='exact' check='full'>
    <model fallback='forbid'>kvm64</model>
    <feature policy='require' name='hypervisor'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <pm>
    <suspend-to-mem enabled='yes'/>
    <suspend-to-disk enabled='yes'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>
    </controller>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <interface type='network'>
      <mac address='52:54:00:ae:ac:e8'/>
      <source network='default'/>
      <model type='rtl8139'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <input type='mouse' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <tpm model='tpm-tis'>
      <backend type='emulator' version='1.2'/>
    </tpm>
    <graphics type='vnc' port='-1' autoport='yes'>
      <listen type='address'/>
    </graphics>
    <video>
      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </memballoon>
  </devices>
</domain>
stefanberger commented 4 years ago

Also @kailiu42's domainXML adjusted for my VM worked:

<domain type='qemu'>
  <name>wintestvm</name>
  <uuid>9bf6ea0c-d3ec-4a76-8fdc-9c1aa986b505</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>2097152</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-5.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
    </hyperv>
    <vmport state='off'/>
  </features>
  <cpu mode='host-model' check='partial'/>
  <clock offset='localtime'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <timer name='hypervclock' present='yes'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <controller type='usb' index='0' model='qemu-xhci' ports='15'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x10'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='2' port='0x11'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x12'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0x13'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
    </controller>
    <controller type='pci' index='5' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='5' port='0x14'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:3a:56:7f'/>
      <source bridge='virbr0'/>
      <model type='e1000e'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <tpm model='tpm-tis'>
      <backend type='emulator' version='1.2'/>
    </tpm>
    <graphics type='spice' autoport='yes'>
      <listen type='address'/>
      <image compression='off'/>
    </graphics>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
    </memballoon>
  </devices>
</domain>
kailiu42 commented 4 years ago

Thank you. After took the changes mentioned in https://github.com/stefanberger/swtpm/issues/284#issuecomment-663091194 TPM 1.2 worked. I didn't even modify my domain XML, only recompiled the swtpm package from that branch, created tss user/group, and changed /etc/libvirt/qemu.conf.

kailiu42 commented 4 years ago

BTW, may I ask how soon would you release a new version for this? If it's going to be in like a couple weeks then I will wait for the new version and submit the new package for openSUSE.

stefanberger commented 4 years ago

I was going to do this fairly soon, like next week.

So you are packaging for openSUSE? I think you should make swtpm-tools depend on system-user-tss.

kailiu42 commented 4 years ago

The swtpm package is not yet in the openSUSE distro. It's in the "security" project - think it as a topic specific project for openSUSE, some of the packages there are in openSUSE distro, some are not (yet).

I'm not the maintainer for swtpm in the security project, but I can submit change request to the maintainer, like anybody can do. If the maintainer accepted my changes then the new version will carry the fix. I've recently submitted the 0.3.3 version update and libtpms 0.7.3 as I'm using them and noticed they were outdated.

Then anybody can install swtpm for openSUSE from the RPM repo of that security project. To make swtpm package accepted into openSUSE official repo it will take some request and reviews, which I may try but can't tell whether I can make it.

BTW, when you said swtpm-tools package, you meant the sub-package from swtpm containing the utilities under /usr/bin? I'm asking because on openSUSE it's only split into swtpm and the -devel packages.

stefanberger commented 4 years ago

For some reason the trousers package did not create the tss user and group but it should do that so it's available once swtpm_setup wants to use it. So that package should depend on system-user-tss and the swtpm package containing swtpm_setup should probably also depend on it.

kailiu42 commented 4 years ago

I will look into why the trousers package doesn't depend on the tss user, and see whether I should request to change both packages or only swtpm.

Thanks a lot!

stefanberger commented 4 years ago

I have google groups for announcements of new releases now:

kailiu42 commented 4 years ago

The trousers package in openSUSE is fixed now. The require to tss user was dropped accidentally due to a previous change. Since the swtpm package depends on the trousers package it will get the tss user. Once the new swtpm version is released I will send a new package request for openSUSE.

stefanberger commented 4 years ago

@kailiu42 FYI: I just tagged v0.3.3.

kailiu42 commented 4 years ago

Thanks. Package request has been submitted for openSUSE security/swtpm.

kailiu42 commented 4 years ago

The request has been accepted by openSUSE security/swtpm. Close as fixed.

@stefanberger thanks a lot.

stefanberger commented 4 years ago

@kailiu42 Can you tell the openSUSE packager to package 0.3.4 since it contains important fixes? Otherwise I can do that. Which website did you use?

kailiu42 commented 4 years ago

I will create the request for 0.3.4, don't worry.

The website is https://build.opensuse.org/package/show/security/swtpm

The process is very much like github. I create a fork(called branch) of the package and update it to 0.3.4, test to make sure it's OK then submit a PR(called submit package) to the maintainer. Once he accepts it the package is updated.

kailiu42 commented 4 years ago

It's been accepted by security/swtpm.

kailiu42 commented 4 years ago

@stefanberger just to let you know that this package has made into openSUSE Factory, which means it can be installed by all openSUSE Tumbleweed users directly without the need to enable some additional repository. Just run zypper in swtpm is sufficient.