#3 Ship the JSON firmware "descriptor files"
Closed 3 months ago by kashyapc. Opened 3 months ago by kashyapc.
rpms/ kashyapc/edk2 master  into  master

@@ -0,0 +1,35 @@ 

+ {

+     "description": "OVMF for i386, with SB+SMM, SB enabled, MS certs enrolled",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf-ia32/OVMF_CODE.secboot.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "i386",

+             "machines": [

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "enrolled-keys",

+         "requires-smm",

+         "secure-boot",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

@@ -0,0 +1,36 @@ 

+ {

+     "description": "OVMF for x86_64, with SB+SMM, SB enabled, MS certs enrolled",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "x86_64",

+             "machines": [

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "amd-sev",

+         "enrolled-keys",

+         "requires-smm",

+         "secure-boot",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

@@ -0,0 +1,34 @@ 

+ {

+     "description": "OVMF for i386, with SB+SMM, empty varstore",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf-ia32/OVMF_CODE.secboot.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "i386",

+             "machines": [

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "requires-smm",

+         "secure-boot",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

file added
+35

@@ -0,0 +1,35 @@ 

+ {

+     "description": "OVMF for x86_64, with SB+SMM, empty varstore",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "x86_64",

+             "machines": [

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "amd-sev",

+         "requires-smm",

+         "secure-boot",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

@@ -0,0 +1,33 @@ 

+ {

+     "description": "OVMF for i386, without SB, without SMM, with empty varstore",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf-ia32/OVMF_CODE.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "i386",

+             "machines": [

+                 "pc-i440fx-*",

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

file added
+34

@@ -0,0 +1,34 @@ 

+ {

+     "description": "OVMF for x86_64, without SB, without SMM, with empty varstore",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_CODE.fd",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/ovmf/OVMF_VARS.fd",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "x86_64",

+             "machines": [

+                 "pc-i440fx-*",

+                 "pc-q35-*"

+             ]

+         }

+     ],

+     "features": [

+         "acpi-s3",

+         "amd-sev",

+         "verbose-dynamic"

+     ],

+     "tags": [

+ 

+     ]

+ }

@@ -0,0 +1,31 @@ 

+ {

+     "description": "UEFI firmware for aarch64, verbose logs",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/aarch64/vars-template-pflash.raw",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "aarch64",

+             "machines": [

+                 "virt-*"

+             ]

+         }

+     ],

+     "features": [

+         "verbose-static"

+     ],

+     "tags": [

+ 

+     ]

+ }

@@ -0,0 +1,31 @@ 

+ {

+     "description": "UEFI firmware for arm, verbose logs",

+     "interface-types": [

+         "uefi"

+     ],

+     "mapping": {

+         "device": "flash",

+         "executable": {

+             "filename": "/usr/share/edk2/arm/QEMU_EFI-pflash.raw",

+             "format": "raw"

+         },

+         "nvram-template": {

+             "filename": "/usr/share/edk2/arm/vars-template-pflash.raw",

+             "format": "raw"

+         }

+     },

+     "targets": [

+         {

+             "architecture": "arm",

+             "machines": [

+                 "virt-*"

+             ]

+         }

+     ],

+     "features": [

+         "verbose-static"

+     ],

+     "tags": [

+ 

+     ]

+ }

file modified
+46 -1

@@ -50,7 +50,7 @@ 

  Name:           edk2

  #Version:       {edk2_date}git{edk2_githash}

  Version:        %{edk2_stable_date}stable

- Release:        1%{dist}

+ Release:        2%{dist}

  Summary:        EFI Development Kit II

  

  License:        BSD

@@ -67,6 +67,16 @@ 

  Source12:       update-tarball.sh

  Source13:       openssl-patch-to-tarball.sh

  

+ # Fedora-specific JSON "descriptor files"

+ Source14: 	40-edk2-ovmf-sb-enrolled.json

+ Source15: 	50-edk2-ovmf-sb.json

+ Source16: 	60-edk2-ovmf.json

+ Source17: 	40-edk2-ovmf-ia32-sb-enrolled.json

+ Source18: 	50-edk2-ovmf-ia32-sb.json

+ Source19: 	60-edk2-ovmf-ia32.json

+ Source20: 	70-edk2-aarch64-verbose.json

+ Source21: 	70-edk2-arm-verbose.json

+ 

  # non-upstream patches

  Patch0001: 0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch

  Patch0002: 0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch

@@ -408,9 +418,27 @@ 

  ln -sf ../%{name}/ovmf/OVMF_VARS.fd                %{buildroot}/usr/share/OVMF

  ln -sf ../%{name}/ovmf/OVMF_VARS.secboot.fd        %{buildroot}/usr/share/OVMF

  ln -sf ../%{name}/ovmf/UefiShell.iso               %{buildroot}/usr/share/OVMF

+ 

+ # For distro-provided firmware packages, the specification

+ # (https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/firmware.json)

+ # says the JSON "descriptor files" to be searched in this directory:

+ # `/usr/share/firmware/`.  Create it.

+ mkdir -p %{buildroot}/%{_datadir}/qemu/firmware

+ 

+ # Install the two variants of the x86_64 firmware descriptor files

+ # (50-edk2-x86_64-secure.json and 60-edk2-x86_64.json)

+ install -pm 644 %{SOURCE14} %{buildroot}/%{_datadir}/qemu/firmware

+ install -pm 644 %{SOURCE15} %{buildroot}/%{_datadir}/qemu/firmware

+ install -pm 644 %{SOURCE16} %{buildroot}/%{_datadir}/qemu/firmware

  %endif

  %if 0%{?build_ovmf_ia32:1}

  cp -a ovmf-ia32 %{buildroot}/usr/share/%{name}

+ 

+ # Install the two variants of the ia32 firmware descriptor files

+ # (50-edk2-i386-secure.json and 60-edk2-i386.json)

+ install -pm 644 %{SOURCE17} %{buildroot}/%{_datadir}/qemu/firmware

+ install -pm 644 %{SOURCE18} %{buildroot}/%{_datadir}/qemu/firmware

+ install -pm 644 %{SOURCE19} %{buildroot}/%{_datadir}/qemu/firmware

  %endif

  %if 0%{?build_aavmf_aarch64:1}

  cp -a aarch64 %{buildroot}/usr/share/%{name}

@@ -418,10 +446,15 @@ 

  mkdir %{buildroot}/usr/share/AAVMF

  ln -sf ../%{name}/aarch64/QEMU_EFI-pflash.raw      %{buildroot}/usr/share/AAVMF/AAVMF_CODE.fd

  ln -sf ../%{name}/aarch64/vars-template-pflash.raw %{buildroot}/usr/share/AAVMF/AAVMF_VARS.fd

+ 

+ # Install the AArch64 firmware descriptor file (60-edk2-aarch64.json)

+ install -pm 644 %{SOURCE20} %{buildroot}/%{_datadir}/qemu/firmware

  %endif

  %if 0%{?build_aavmf_arm:1}

  cp -a arm %{buildroot}/usr/share/%{name}

  ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw          %{buildroot}/usr/share/AAVMF/AAVMF32_CODE.fd

+ # Install the ARM firmware descriptor file (60-edk2-arm.json)

+ install -pm 644 %{SOURCE21} %{buildroot}/%{_datadir}/qemu/firmware

  %endif

  

  install qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator %{buildroot}%{_bindir}

@@ -479,9 +512,11 @@ 

  %doc ovmf-whitepaper-c770f8c.txt

  %dir /usr/share/%{name}

  %dir /usr/share/%{name}/ovmf

+ %dir /usr/share/qemu/firmware

  /usr/share/%{name}/ovmf/OVMF*.fd

  /usr/share/%{name}/ovmf/*.efi

  /usr/share/%{name}/ovmf/*.iso

+ /usr/share/qemu/firmware/*.json

  /usr/share/OVMF

  %endif

  

@@ -493,9 +528,11 @@ 

  %doc ovmf-whitepaper-c770f8c.txt

  %dir /usr/share/%{name}

  %dir /usr/share/%{name}/ovmf-ia32

+ %dir /usr/share/qemu/firmware

  /usr/share/%{name}/ovmf-ia32/OVMF*.fd

  /usr/share/%{name}/ovmf-ia32/*.efi

  /usr/share/%{name}/ovmf-ia32/*.iso

+ /usr/share/qemu/firmware/*.json

  %endif

  

  %if 0%{?build_aavmf_aarch64:1}

@@ -504,8 +541,10 @@ 

  %license LICENSE.openssl

  %dir /usr/share/%{name}

  %dir /usr/share/%{name}/aarch64

+ %dir /usr/share/qemu/firmware

  /usr/share/%{name}/aarch64/QEMU*.fd

  /usr/share/%{name}/aarch64/*.raw

+ /usr/share/qemu/firmware/*.json

  /usr/share/AAVMF/AAVMF_*

  %endif

  

@@ -515,13 +554,19 @@ 

  %license LICENSE.openssl

  %dir /usr/share/%{name}

  %dir /usr/share/%{name}/arm

+ %dir /usr/share/qemu/firmware

  /usr/share/%{name}/arm/QEMU*.fd

  /usr/share/%{name}/arm/*.raw

+ /usr/share/qemu/firmware/*.json

  /usr/share/AAVMF/AAVMF32_*

  %endif

  

  

  %changelog

+ * Wed Jul 10 2019 Kashyap Chamarthy <kchamart@redhat.com> - 20190308stable-2

+ - Ship Fedora-variant JSON "firmware descriptor files"

+ - Resolves rhbz#1728652

+ 

  * Mon Mar 18 2019 Cole Robinson <aintdiscole@gmail.com> - 20190308stable-1

  - Use YYYYMMDD versioning to fix upgrade path

  

Ship the JSON firmware "descriptor files"

From version 4.1 (due in August 2019) onwards, QEMU ships the so-called
firmware "descriptor files". These are small JSON files that describe
details about UEFI firmware binaries — such as the fimware binary path,
its architecture, supported machine type, NVRAM template and so forth.

You can see examples of these files from the QEMU upstream Git:
https://git.qemu.org/?p=qemu.git;a=tree;f=pc-bios/descriptors

$> tree descriptors/
descriptors/
├── 50-edk2-i386-secure.json
├── 50-edk2-x86_64-secure.json
├── 60-edk2-aarch64.json
├── 60-edk2-arm.json
├── 60-edk2-i386.json
└── 60-edk2-x86_64.json

QEMU 4.1 itself will ship the above files. However, Fedora needs to
ship these file as part of its EDK2 package.

Why?

(1) Quoting (with minor formatting edits) Laszlo Ersek:

  Distributions providing their own EDK2 packages would not include
  the descriptors from upstream QEMU, even if they otherwise package
  QEMU.  That's beause the descriptor files in QEMU match the
  firmware bundled with QEMU -- but the firmware images in the
  distros' own EDK2 packages are different.  So, if a distro
  provides an EDK2 package, then the same EDK2 package should offer
  matching descriptors.  QEMU offers descriptors (soon) because QEMU
  technically distributes edk2 firmware binaries (soon).  [Where
  "soon" == QEMU 4.1]

(2) And as Dan Berrangé reminded on IRC:

  In Fedora, we need to ship them [the "descriptor files"] as part
  of the EDK2 package, because Fedora throws away all the firmware
  files that QEMU bundles, because we're [Fedora] required to
  rebuild everything from pristine source.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1728652 ("RFE:
Ship the JSON firmware "descriptor files" as part of EDK2").

[Ccing a few "usual suspects".]

Hi @lersek @puiterwijk @berrange @crobinso,

When you get a few minutes, please have a gander at this Pull Request.

Here's a scratch build (that seems to be heading towards success): https://koji.fedoraproject.org/koji/taskinfo?taskID=36171184

[Edit: the above build failed.]

Oops, forgot to update the paths in the JSON files; fixing...fixed.

rebased onto 3f0fa3d

3 months ago

Here is a successful scratch build: https://koji.fedoraproject.org/koji/taskinfo?taskID=36171700

Edit: The above build had a duplicate spec line; fixed it and re-issued a new scratch build: https://koji.fedoraproject.org/koji/taskinfo?taskID=36181955

rebased onto ed5ddcb

3 months ago

This seems pretty useless to me, given that you're copying fromm the original file locations later.

The RPM needs to own the directory too eg "%dir /usr/share/qemu/firmware" since it isn't depending on any other package which owns this dir. Likewise for the other sub-RPMs. It is fine for multiple RPMs to own the same directory.

This seems pretty useless to me, given that you're copying fromm the original file locations later.

Hmm, I did that cp so that it will inject them into the SRPM. But I just tested and it's indeed useless and not required — because, as you noticed, the copying in the %install section takes care that the JSON files are also included in the SRPM.

I'll remove the needless cp.

The RPM needs to own the directory too eg "%dir /usr/share/qemu/firmware" since it isn't depending on any other package which owns this dir. Likewise for the other sub-RPMs. It is fine for multiple RPMs to own the same directory.

Ah, yes. Will fix. (And yeah, I learnt that multiple RPMs to own the same directory from you in the past. :-))

@kashyapc

Sorry about the late response. My general opinion is that, if a
distribution ships its own edk2 firmware builds, like Fedora and RHEL
do, then the distribution should not include the firmware binaries
bundled with upstream QEMU, in the downstream QEMU package.

As I understand, this matches Dan's point from above,

because Fedora throws away all the firmware files that QEMU bundles,
because we're [Fedora] required to rebuild everything from pristine
source

Looking at the Fedora QEMU spec file, at dist-git commit 8e85e5e9aad0
("Rebuild for new brltty.", 2019-06-28), this appears factual: see the
rm -fr commands near the comments Provided by package ....

This pattern needs to be extended to edk2. The QEMU spec file should
receive a new section titled Provided by package edk2-whatever,
deleting files that match the shell pattern edk2*. The
upstream-installed descriptor JSON documents should be deleted as well.

Regarding Fedora's edk2 package, we should not copy (mostly blindly) the
descriptor files provided by upstream QEMU. Those descriptors correspond
to the firmware binaries bundled with upstream QEMU, and not
(necessarily) to the ones provided by Fedora. Fedora's edk2 package
should provide descriptors that match Fedora's firmware binaries (build
options), and variable store templates.

The double-digit priority prefixes should be constructed from scratch. I
guess it's subjective what descriptor ("firmware use case") gets what
priority. I would suggest the following:

  • Descriptor files belonging to different QEMU targets (= emulation
    architectures) should not be ordered against each other. A full
    ordering of descriptors should only be established within each QEMU
    target in isolation. The orderings can be parallel to each other
    across QEMU targets.

  • For any given architecture, if a firmware use case is offered where
    the binary contains the secure boot feature (such that it is actually
    secure), and the varstore template enables the secure boot
    operational mode, then the descriptor should have priority 40.

  • For any given arch, if a firmware use case is offered where the binary
    contains the secure boot feature (such that it is actually secure),
    but the varstore template does not enable the secure boot
    operational mode, then the descriptor should have priority 50.

  • For any given arch, if a firmware use case is offered where the binary
    does not contain the secure boot feature, then the descriptor should
    have priority 60 (or weaker / higher number).

  • For any given arch, a firmware use case where the secure boot feature
    is offered, but it's actual security is not enforced in virtual
    hardware, a firmware use case (= descriptor file) should not be
    offered at all.

  • For any given arch, if a firmware use case is offered with the
    verbose-static feature, then its descriptor should have weaker
    priority (higher number) than the same use case without
    verbose-static, if such a use case exists.

For an example, please look at RHEL8 edk2 dist-git commit 5a489685cc38
(for RHBZ#1600230).

The above guidelines are satisfied by both the upstream QEMU descriptors
and by those in RHEL8 edk2.

I'll attempt to look at Fedora's edk2 package now, and recommend some
descriptors.

This revolutionary bug tracker does not allow me to attach files, so please see:

https://bugzilla.redhat.com/show_bug.cgi?id=1728652#c2

rebased onto 9dfb7ca

3 months ago

@kashyapc
Sorry about the late response.

No problem; I don't count on instant responses :-)

My general opinion is that, if a
distribution ships its own edk2 firmware builds, like Fedora and RHEL
do, then the distribution should not include the firmware binaries
bundled with upstream QEMU, in the downstream QEMU package.
As I understand, this matches Dan's point from above,

Yes, it does.

[...]

Looking at the Fedora QEMU spec file, at dist-git commit 8e85e5e9aad0
("Rebuild for new brltty.", 2019-06-28), this appears factual: see the
rm -fr commands near the comments Provided by package ....
This pattern needs to be extended to edk2. The QEMU spec file should
receive a new section titled Provided by package edk2-whatever,
deleting files that match the shell pattern edk2*. The upstream-installed descriptor
JSON documents should be deleted as well.

Seems like Cole already did that yesterday :-) See Fedora's QEMU dist-git commit:160bf4b (Update to qemu-4.1.0-rc0, 2019-07-11).

Regarding Fedora's edk2 package, we should not copy (mostly blindly) the
descriptor files provided by upstream QEMU. Those descriptors correspond
to the firmware binaries bundled with upstream QEMU, and not
(necessarily) to the ones provided by Fedora. Fedora's edk2 package
should provide descriptors that match Fedora's firmware binaries (build
options), and variable store templates.

The double-digit priority prefixes should be constructed from scratch. I
guess it's subjective what descriptor ("firmware use case") gets what
priority. I would suggest the following:

[...]

For any given arch, a firmware use case where the secure boot feature
is offered, but it's actual security is not enforced in virtual
hardware, a firmware use case (= descriptor file) should not be
offered at all.

For any given arch, if a firmware use case is offered with the
verbose-static feature, then its descriptor should have weaker
priority (higher number) than the same use case without
verbose-static, if such a use case exists.

Yes, noted. Thanks for the thorough response.

A couple of questions for my own education:

  • The "actual security is not enforced in virtual hardware" bit is referring to enabling
    SMM for the guest, or something else?
  • Also, what does this "verbose-static" mean?

For an example, please look at RHEL8 edk2 dist-git commit 5a489685cc38
(for RHBZ#1600230).

Yes, I did take a look at them; thanks for the reference.

The above guidelines are satisfied by both the upstream QEMU descriptors
and by those in RHEL8 edk2.
I'll attempt to look at Fedora's edk2 package now, and recommend some
descriptors.

Thanks, again!

rebased onto 90e8275

3 months ago

@lersek @berrange

I think I've addressed the points both of you mentioned, and force-pushed the changes to this Pull Request. (A small nuisance: on src.fedoraproject.org, you can't see the diff from the previous iteration when you force-push.)

For convenience, a short summary of things I've addressed:

@kashyapc

The "actual security is not enforced in virtual hardware" bit is referring to enabling SMM for the guest [...] ?

Yes.

Also, what does this "verbose-static" mean?

It's documented in docs/interop/firmware.json:

# @verbose-static: The firmware unconditionally produces a large amount
#                  of debug messages, which may impact boot performance.
#                  This feature may typically be carried by certain UEFI
#                  firmware for the "virt-*" machine types of the @arm
#                  and @aarch64 emulation targets, where the debug
#                  messages are written to the first (always present)
#                  PL011 UART. @verbose-static is mutually exclusive
#                  with @verbose-dynamic.

BTW, I think this PR should be closed, as @crobinso has applied the patch (see dist-git 674b3c8).

Cole tweaked some other stuff too, which I welcome. A particular varstore template file, made for x86_64, can be used by i386 too (and vice versa), and the JSONs I provided earlier utilized that (with i386 referring to x86_64). Cole detached those from each other in dist-git 429a275, which certainly makes for more self-contained subpackages.

BTW, I think this PR should be closed, as @crobinso has applied the patch (see dist-git 674b3c8).

Ah, I didn't know of that, as @crobinso directly applied the patch. That's why I didn't get a notification. Was expecting this PR to be "explicitly merged", or a note saying "Closes: #3" in the commit, which would marked this PR as closed and have sent me a notification.

Here are some keywords (thanks, Patrick Uiterwijk) that are recognized:
https://docs.pagure.org/pagure/usage/magic_words.html

Cole tweaked some other stuff too, which I welcome. A particular varstore template file, made for x86_64, can be used by i386 too (and vice versa), and the JSONs I provided earlier utilized that (with i386 referring to x86_64). Cole detached those from each other in dist-git 429a275, which certainly makes for more self-contained subpackages.

Yeah, just read the two commits on top of mine, they are useful. Thanks!

Pull-Request has been closed by kashyapc

3 months ago

"Closed" as the patch from this change is directly committed: https://src.fedoraproject.org/rpms/edk2/c/674b3c8a27a8