Bug 1929357
Summary: | UEFI: Provide a way how to configure different combinations of secure boot enabled/disabled and keys enrolled/not enrolled | ||||||
---|---|---|---|---|---|---|---|
Product: | Red Hat Enterprise Linux 8 | Reporter: | Stephen Finucane <stephenfin> | ||||
Component: | libvirt | Assignee: | Pavel Hrdina <phrdina> | ||||
Status: | CLOSED ERRATA | QA Contact: | Meina Li <meili> | ||||
Severity: | medium | Docs Contact: | |||||
Priority: | medium | ||||||
Version: | 8.0 | CC: | jdenemar, jsuchane, phrdina, virt-maint, yalzhang | ||||
Target Milestone: | rc | Keywords: | FutureFeature, Triaged | ||||
Target Release: | --- | ||||||
Hardware: | Unspecified | ||||||
OS: | Unspecified | ||||||
Whiteboard: | |||||||
Fixed In Version: | libvirt-6.0.0-36.el8 | Doc Type: | If docs needed, set a value | ||||
Doc Text: | Story Points: | --- | |||||
Clone Of: | Environment: | ||||||
Last Closed: | 2021-11-09 17:58:01 UTC | Type: | Feature Request | ||||
Regression: | --- | Mount Type: | --- | ||||
Documentation: | --- | CRM: | |||||
Verified Versions: | Category: | --- | |||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
Cloudforms Team: | --- | Target Upstream Version: | |||||
Embargoed: | |||||||
Bug Depends On: | |||||||
Bug Blocks: | 1369007, 1937150 | ||||||
Attachments: |
|
Description
Stephen Finucane
2021-02-16 17:54:56 UTC
Some additional information: $ ls /usr/share/qemu/firmware/ -1 40-edk2-ovmf-x64-sb-enrolled.json 50-edk2-ovmf-x64-sb.json 60-edk2-ovmf-x64.json 70-edk2-aarch64-verbose.json Another data point. This works: <os firmware="efi"> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <boot dev='cdrom'/> </os> It results in the following XML: <os> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <nvram>/home/stephenfin/.config/libvirt/qemu/nvram/alpinelinux-q35-uefi-experiment_VARS.fd</nvram> <boot dev='cdrom'/> </os> This does not work: <os firmware="efi"> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <boot dev='cdrom'/> </os> It results in the following XML, where we see the requested loader is totally ignored. This seems like it should be an error? <os> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> <nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'>/home/stephenfin/.config/libvirt/qemu/nvram/alpinelinux-q35-uefi-experiment_VARS.fd</nvram> <boot dev='cdrom'/> </os> Also, I tried with a Fedora 33 Workstation image and things boot just fine regardless of the bootloader configuration. This is presumably because the Fedora images are signed? I've documented my findings at [1], though it mostly duplicates what I've already said here. [1] https://that.guru/blog/uefi-secure-boot-in-libvirt/ (In reply to Stephen Finucane from comment #3) > Another data point. This works: > > <os firmware="efi"> > <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> > <loader readonly='yes' > type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> > <boot dev='cdrom'/> > </os> Apologies. This should read: <os> <type arch='x86_64' machine='pc-q35-5.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <boot dev='cdrom'/> </os> i.e. no 'firmware' attribute on the 'os' element. If the 'firmware' attribute is specified, everything else inside the '<os>' element is seemingly ignored, which seems wrong: surely this should raise an error rather than being silently dropped? I tried experimenting with the 'secure' attribute of the 'loader' element. For example: <os> <type arch="x86_64" machine="pc-q35-5.1">hvm</type> <loader readonly="yes" type="pflash" secure="no">/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> <boot dev="cdrom"/> </os> The docs [1] suggest setting the 'secure' attribute should allow me to control secure boot behavior, stating: Moreover, some firmwares may implement the Secure boot feature. Attribute secure can be used then to control it. This would also align with what I've been told me about secure boot-enabled firmware being able to be used for non-secure boot guests. However, secure boot still appears to be enabled and I'm unable to boot the guest, with the same Access Denied errors being raised by the bootloader. Note that doing the opposite and attempting to set the 'secure="yes"' attribute when using a non-secure boot firmware does fail as expected. For example: <os> <type arch="x86_64" machine="pc-q35-5.1">hvm</type> <loader readonly="yes" type="pflash" secure="yes">/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <boot dev="cdrom"/> </os> This fails with the following error message: error: Failed to create domain from alpine-test.xml error: unsupported configuration: Secure boot requires SMM feature enabled Finally, I have also tested this with a Mageia 7.1 netinstall image just to rule out issues with the Alpine Linux issue. This image was chosen as the Mageia docs suggest that UEFI is supported but secure boot is not [2]. Once again, I see an Access Denied error from the bootloader if the secboot firmware is used. [1] https://libvirt.org/formatdomain.html#bios-bootloader [2] https://wiki.mageia.org/en/About_EFI_UEFI#Secure_Boot Hi, thanks for the report. The situation with secure boot and firmwares is a bit complicated. One thing to note is that there is no '/usr/share/edk2/ovmf/OVMF_CODE.fd' in RHEL-8, my guess is that you tried it on Fedora. There are several JSON descriptions of firmware configurations: 1) '40-edk2-ovmf-sb.json' (RHEL-8), '40-edk2-ovmf-x64-sb-enrolled.json' (Fedora-33) - secure boot feature enabled, keys enrolled - With this configuration it will boot only signed loaders, others are rejected with 'Access denied' or 'permission denied' so similar. - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd' and NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'. 2) '50-edk2-ovmf.json' (RHEL-8), '50-edk2-ovmf-x64-sb.json' (Fedora-33) - secure boot feature enabled, no keys enrolled - With this configuration it will boot all loaders because there are no keys to verify any signature. - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd' and NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.fd'. 3) '60-edk2-ovmf-x64.json' (Fedora-33) - secure boot feature disabled, no keys enrolled - With this configuration it will boot all loaders because there is no secure boot feature available in the firmware. - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.fd' and NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.fd'. Currently with libvirt the <os firmware='efi'> will automatically select only option 1) as it is the first available JSON description. There is no other easy way in libvirt to configure options 2) and 3) except for providing all the paths to firmware in <loader> element and NVRAM template in <nvram> element. Now the 'secure' attribute has a bit misleading documentations as it doesn't control whether the feature is enabled/disabled in the firmware but it is used to tell to QEMU if the provided firmware is with secure boot feature enabled/disabled so QEMU knows how to handle the firmware and access to it. We definitely need to improve the documentation. There is another BZ 1906500 that hits the same limitation in libvirt without providing all the paths manually in the XML, you can check the comments for additional details. We need to probably add new attributes/elements to libvirt VM XML to have simple way how to configure options 2) and 3). (In reply to Pavel Hrdina from comment #5) > Hi, thanks for the report. > > The situation with secure boot and firmwares is a bit complicated. > > One thing to note is that there is no '/usr/share/edk2/ovmf/OVMF_CODE.fd' > in RHEL-8, my guess is that you tried it on Fedora. Correct. I had a long comment written out last week explaining this but BZ was returning HTTP 5xx errors and took my comment with it :) > There are several JSON descriptions of firmware configurations: > > 1) '40-edk2-ovmf-sb.json' (RHEL-8), '40-edk2-ovmf-x64-sb-enrolled.json' (Fedora-33) > > - secure boot feature enabled, keys enrolled > > - With this configuration it will boot only signed loaders, others are rejected > with 'Access denied' or 'permission denied' so similar. > > - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd' and > NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'. > > > 2) '50-edk2-ovmf.json' (RHEL-8), '50-edk2-ovmf-x64-sb.json' (Fedora-33) > > - secure boot feature enabled, no keys enrolled > > - With this configuration it will boot all loaders because there are no keys > to verify any signature. > > - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd' and > NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.fd'. > > > 3) '60-edk2-ovmf-x64.json' (Fedora-33) > > - secure boot feature disabled, no keys enrolled > > - With this configuration it will boot all loaders because there is no secure > boot feature available in the firmware. > > - This refers to firmware '/usr/share/edk2/ovmf/OVMF_CODE.fd' and > NVRAM template '/usr/share/edk2/ovmf/OVMF_VARS.fd'. > > > Currently with libvirt the <os firmware='efi'> will automatically select only > option 1) as it is the first available JSON description. > > There is no other easy way in libvirt to configure options 2) and 3) except for > providing all the paths to firmware in <loader> element and NVRAM template > in <nvram> element. > > Now the 'secure' attribute has a bit misleading documentations as it doesn't control > whether the feature is enabled/disabled in the firmware but it is used to tell to > QEMU if the provided firmware is with secure boot feature enabled/disabled so QEMU > knows how to handle the firmware and access to it. We definitely need to improve > the documentation. > > There is another BZ 1906500 that hits the same limitation in libvirt without > providing all the paths manually in the XML, you can check the comments for > additional details. > > We need to probably add new attributes/elements to libvirt VM XML to have simple > way how to configure options 2) and 3). Thank you for all the context. I'll feed this into back into the OpenStack Nova RFE. It sounds like we can use libvirt's discovery functionality but not the auto-configuration feature (at least not yet). For what it's worth, something akin to what I was trying to do (enable or disable secure boot via '<loader secure="yes|no"/>') would be fantastic and probably what we'll need to be able to consume this feature. Upstream commits: c91fa27306 qemu: implement support for firmware auto-selection feature filtering cff524af6c conf: introduce support for firmware auto-selection feature filtering 6330be1ba3 conf: use switch in virDomainDefParseBootOptions 108cb29c1c conf: introduce virDomainDefParseBootAcpiOptions b8dd70db4e conf: introduce virDomainDefParseBootLoaderOptions bcf97abfc6 conf: introduce virDomainDefParseBootFirmwareOptions bf9b3f8e57 conf: introduce virDomainDefParseBootKernelOptions b07116438c conf: introduce virDomainDefParseBootInitOptions f47d06260b docs: improve description of secure attribute for loader element Two additional commits that we will need to backport: a9b1375d7d conf: remove duplicated firmware type attribute c116b94814 domain_conf: Don't leak def->os.firmwareFeatures Verified Version: libvirt-6.0.0-36.module+el8.5.0+11222+c889b3f3.x86_64 qemu-kvm-4.2.0-51.module+el8.5.0+11141+9dff516f.x86_64 Verified Steps: 1. Prepare an OVMF guest with the signed image and unsigned image respectively. 2. Update enabled features with different combination in guest xml. # virsh dumpxml --inactive ovmf | grep /os -B7 <os firmware='efi'> <type arch='x86_64' machine='pc-q35-rhel8.4.0'>hvm</type> <firmware> <feature enabled='**yes**' name='enrolled-keys'/> <feature enabled='**yes**' name='secure-boot'/> </firmware> <boot dev='hd'/> </os> 2. Start the guest and check the boot process. # virsh start ovmf Domain 'ovmf' started # virt-viewer ovmf Test Matrix: S1: Boot OVMF guest with signed image and different features combination Test Matrix: secure-boot enrolled-keys Expected Result yes yes can boot yes no can boot no no can't start guest with error no yes can't start guest with error S2: Boot OVMF guest with non-signed image and different features combination secure-boot enrolled-keys Expected Result yes yes can't boot with has invalid signature error yes no can boot no no can't start guest with error no yes can't start guest with error The test results are expected. Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (Moderate: virt:rhel and virt-devel:rhel security, bug fix, and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2021:4191 |