Blame SOURCES/0027-Revert-OvmfPkg-use-generic-QEMU-image-loader-for-sec.patch

1d2c45
From 74e5313dfa6719f7990c7e175e035d17c9b3f657 Mon Sep 17 00:00:00 2001
1d2c45
From: Laszlo Ersek <lersek@redhat.com>
1d2c45
Date: Fri, 5 Jun 2020 23:44:43 +0200
1d2c45
Subject: Revert "OvmfPkg: use generic QEMU image loader for secure boot
1d2c45
 enabled builds"
1d2c45
1d2c45
Notes about the RHEL-8.2/20190904-37eef91017ad [edk2-stable201908] ->
1d2c45
RHEL-8.3/20200603-ca407c7246bf [edk2-stable202005] rebase:
1d2c45
1d2c45
- new patch (to be dropped later, hopefully)
1d2c45
1d2c45
This reverts commit ced77332cab626f35fbdb36630be27303d289d79.
1d2c45
1d2c45
Upstream commit ced77332cab6 ("OvmfPkg: use generic QEMU image loader for
1d2c45
secure boot enabled builds", 2020-03-05) changes the "Secure Boot threat
1d2c45
model" in a way that is incompatible with at least two use cases.
1d2c45
1d2c45
Namely, OVMF has always considered kernel images direct-booted via fw_cfg
1d2c45
as trusted, bypassing Secure Boot validation. While that approach is
1d2c45
rooted in a technicality (namely, OVMF doesn't load such images with the
1d2c45
LoadImage() UEFI boot service / through the UEFI stub, but with the
1d2c45
Linux/x86 Boot Protocol), that doesn't mean it's wrong. The direct-booted
1d2c45
kernel from fw_cfg comes from the host side, and Secure Boot in the guest
1d2c45
is a barrier between the guest firmware and the guest operating system --
1d2c45
it's not a barrier between host and guest.
1d2c45
1d2c45
Upstream commit ced77332cab6 points out that the above (historical) OVMF
1d2c45
behavior differs from ArmVirtQemu's -- the latter direct-boots kernels
1d2c45
from fw_cfg with the LoadImage() / StartImage() boot services. While that
1d2c45
difference indeed exists between OVMF and ArmVirtQemu, it's not relevant
1d2c45
for RHEL downstream. That's because we never build the ArmVirtQemu
1d2c45
firmware with the Secure Boot feature, so LoadImage() can never reject the
1d2c45
direct-booted kernel due to a signing issue.
1d2c45
1d2c45
Subjecting a kernel direct-booted via fw_cfg to Secure Boot verification
1d2c45
breaks at least two use cases with OVMF:
1d2c45
1d2c45
- It breaks the %check stage in the SPEC file.
1d2c45
1d2c45
  In that stage, we use the "ovmf-vars-generator" utility from the
1d2c45
  "qemu-ovmf-secureboot" project, for verifying whether the Secure Boot
1d2c45
  operational mode is enabled. The guest kernel is supposed to boot, and
1d2c45
  to print "Secure boot enabled".
1d2c45
1d2c45
  As guest kernel, we pick whatever host kernel is available in the Brew
1d2c45
  build root. The kernel in question may be a publicly released RHEL
1d2c45
  kernel, signed with "Red Hat Secure Boot (signing key 1)", or a
1d2c45
  development build, signed for example with "Red Hat Secure Boot Signing
1d2c45
  3 (beta)". Either way, none of these keys are accepted by the
1d2c45
  certificates that were enrolled by "ovmf-vars-generator" /
1d2c45
  "EnrollDefaultKeys.efi" in the %build stage. Therefore, the %check stage
1d2c45
  fails.
1d2c45
1d2c45
- It breaks "virt-install --location NETWORK-URL" Linux guest
1d2c45
  installations, if the variable store template used for the new domain
1d2c45
  has the Secure Boot operational mode enabled. "virt-install --location"
1d2c45
  fetches the kernel from the remote OS tree, and passes it to the guest
1d2c45
  firmware via fw_cfg. Therefore the above symptom appears (even for
1d2c45
  publicly released OSes).
1d2c45
1d2c45
  Importantly, if the user downloads the installer ISO of the publicly
1d2c45
  released Fedora / RHEL OS, and exposes the ISO to the guest for example
1d2c45
  as a virtio-scsi CD-ROM, then the installation with "virt-install"
1d2c45
  (without "--location") does succeed. That's because that way, "shim" is
1d2c45
  booted first, from the UEFI-bootable CD-ROM. "Shim" does pass Secure
1d2c45
  Boot verification against the Microsoft certificates, and then it is
1d2c45
  "shim" that accepts the "Red Hat Secure Boot (signing key 1)" signature
1d2c45
  on the guest kernel.
1d2c45
1d2c45
Some ways to approach this problem (without reverting upstream commit
1d2c45
ced77332cab6):
1d2c45
1d2c45
- Equip "ovmf-vars-generator" / "EnrollDefaultKeys.efi" to enroll the
1d2c45
  public half of "Red Hat Secure Boot (signing key 1)" in the %build
1d2c45
  stage. Use a publicly released RHEL kernel in the %check stage.
1d2c45
1d2c45
  Downsides:
1d2c45
1d2c45
  - The Brew build root does not offer any particular released RHEL
1d2c45
    kernel, so either the %check stage would have to download it, or the
1d2c45
    SRPM would have to bundle it. However, Brew build environments do not
1d2c45
    have unfettered network access (rightly so), so the download wouldn't
1d2c45
    work. Furthermore, for bundling with the SRPM, such a kernel image
1d2c45
    could be considered too large.
1d2c45
1d2c45
  - Does not solve the "virt-install --location" issue for other vendors'
1d2c45
    signed kernels.
1d2c45
1d2c45
- Invoke "ovmf-vars-generator" / "EnrollDefaultKeys.efi" multiple times
1d2c45
  during %build, to create multiple varstore templates. One that would
1d2c45
  accept publicly released RHEL kernels, and another to accept development
1d2c45
  kernels. Don't try to use a particular guest kernel for verification;
1d2c45
  instead, check what kernel Brew offers in the build environment, and use
1d2c45
  the varstore template matching *that* kernel.
1d2c45
1d2c45
  Downsides:
1d2c45
1d2c45
  - It may be considered useless to perform %check with a varstore
1d2c45
    template that is *not* the one that we ship.
1d2c45
1d2c45
  - Does not solve the "virt-install --location" issue for other vendors'
1d2c45
    signed kernels.
1d2c45
1d2c45
- Sign the RHEL kernels such that the currently enrolled certificates
1d2c45
  accept them.
1d2c45
1d2c45
  Downsides:
1d2c45
1d2c45
  - Not feasible at all; it would require Microsoft to sign our kernels.
1d2c45
    "Shim" exists exactly to eliminate such signing requirements.
1d2c45
1d2c45
- Modify "virt-install --location NETWORK-URL" such that it download a
1d2c45
  complete (UEFI-bootable) installer ISO image, rather than broken-out
1d2c45
  vmlinuz / initrd files. In other words, replace direct (fw_cfg) kernel
1d2c45
  boot with a CD-ROM / "shim" boot, internally to "virt-install".
1d2c45
1d2c45
  Downsides:
1d2c45
1d2c45
  - Defeats the goal of "virt-install --location NETWORK-URL", and defeats
1d2c45
    the network installation method of (for example) Anaconda.
1d2c45
1d2c45
For now, revert upstream commit ced77332cab6, in order to return to the
1d2c45
model we had used in RHEL-8.2 and before. The following ticket has been
1d2c45
filed to investigate the problem separately:
1d2c45
<https://bugzilla.redhat.com/show_bug.cgi?id=1844653>.
1d2c45
1d2c45
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
1d2c45
---
1d2c45
 OvmfPkg/OvmfPkgIa32.dsc    | 4 ----
1d2c45
 OvmfPkg/OvmfPkgIa32X64.dsc | 4 ----
1d2c45
 OvmfPkg/OvmfPkgX64.dsc     | 4 ----
1d2c45
 3 files changed, 12 deletions(-)
1d2c45
1d2c45
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
1d2c45
index e8868136d8..5b1e757cb9 100644
1d2c45
--- a/OvmfPkg/OvmfPkgIa32.dsc
1d2c45
+++ b/OvmfPkg/OvmfPkgIa32.dsc
1d2c45
@@ -379,11 +379,7 @@
1d2c45
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
1d2c45
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
1d2c45
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
1d2c45
-!if $(SECURE_BOOT_ENABLE) == TRUE
1d2c45
-  QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
1d2c45
-!else
1d2c45
   QemuLoadImageLib|OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
1d2c45
-!endif
1d2c45
 !if $(TPM_ENABLE) == TRUE
1d2c45
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
1d2c45
   Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
1d2c45
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
1d2c45
index d05275a324..5dffc32105 100644
1d2c45
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
1d2c45
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
1d2c45
@@ -383,11 +383,7 @@
1d2c45
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
1d2c45
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
1d2c45
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
1d2c45
-!if $(SECURE_BOOT_ENABLE) == TRUE
1d2c45
-  QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
1d2c45
-!else
1d2c45
   QemuLoadImageLib|OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
1d2c45
-!endif
1d2c45
 !if $(TPM_ENABLE) == TRUE
1d2c45
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
1d2c45
   Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
1d2c45
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
1d2c45
index cac4cecf18..a2a76fdeea 100644
1d2c45
--- a/OvmfPkg/OvmfPkgX64.dsc
1d2c45
+++ b/OvmfPkg/OvmfPkgX64.dsc
1d2c45
@@ -383,11 +383,7 @@
1d2c45
   PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
1d2c45
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
1d2c45
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
1d2c45
-!if $(SECURE_BOOT_ENABLE) == TRUE
1d2c45
-  QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
1d2c45
-!else
1d2c45
   QemuLoadImageLib|OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
1d2c45
-!endif
1d2c45
 !if $(TPM_ENABLE) == TRUE
1d2c45
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
1d2c45
   Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
1d2c45
-- 
1d2c45
2.18.1
1d2c45