[PATCH 1/5] conf: Introduce os/shim element

Michal Privoznik posted 5 patches 6 days, 4 hours ago
[PATCH 1/5] conf: Introduce os/shim element
Posted by Michal Privoznik 6 days, 4 hours ago
For secure boot environments where <loader/> is signed, it may be
unfeasible to keep the binary up to date (esp. when revoking
certificates contained within). To address that, QEMU introduced
'-shim' cmd line option which side loads another UEFI binary
which can then contain new certification authorities or list of
revocations. Expose it as <shim/> element that's nested under
<os/>, just like kernel and initrd are.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
 docs/formatdomain.rst                                |  5 +++++
 src/conf/domain_conf.c                               | 12 ++++++++----
 src/conf/domain_conf.h                               |  1 +
 src/conf/domain_validate.c                           |  6 ++++++
 src/conf/schemas/domaincommon.rng                    |  5 +++++
 .../launch-security-sev-direct.x86_64-latest.xml     |  1 +
 tests/qemuxmlconfdata/launch-security-sev-direct.xml |  1 +
 7 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index cbe378e61d..087e77217e 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -397,6 +397,7 @@ and full virtualized guests.
      <kernel>/root/f8-i386-vmlinuz</kernel>
      <initrd>/root/f8-i386-initrd</initrd>
      <cmdline>console=ttyS0 ks=http://example.com/f8-i386/os/</cmdline>
+     <shim>/path/to/shim.efi</shim>
      <dtb>/root/ppc.dtb</dtb>
    </os>
    ...
@@ -417,6 +418,10 @@ and full virtualized guests.
    The contents of this element specify arguments to be passed to the kernel (or
    installer) at boot time. This is often used to specify an alternate primary
    console (eg serial port), or the installation media source / kickstart file
+``shim``
+   Use specified fully-qualified path to load an initial UEFI bootloader that
+   handles chaining to a trusted full bootloader under secure boot
+   environments.
 ``dtb``
    The contents of this element specify the fully-qualified path to the
    (optional) device tree binary (dtb) image in the host OS.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f42b7075ad..907e11cced 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3922,6 +3922,7 @@ virDomainOSDefClear(virDomainOSDef *os)
     g_free(os->kernel);
     g_free(os->initrd);
     g_free(os->cmdline);
+    g_free(os->shim);
     g_free(os->dtb);
     g_free(os->root);
     g_free(os->slic_table);
@@ -17732,6 +17733,7 @@ virDomainDefParseBootKernelOptions(virDomainDef *def,
     def->os.kernel = virXPathString("string(./os/kernel[1])", ctxt);
     def->os.initrd = virXPathString("string(./os/initrd[1])", ctxt);
     def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt);
+    def->os.shim = virXPathString("string(./os/shim[1])", ctxt);
     def->os.dtb = virXPathString("string(./os/dtb[1])", ctxt);
     def->os.root = virXPathString("string(./os/root[1])", ctxt);
 }
@@ -17904,10 +17906,10 @@ virDomainDefParseBootOptions(virDomainDef *def,
     /*
      * Booting options for different OS types....
      *
-     *   - A bootloader (and optional kernel+initrd)  (xen)
-     *   - A kernel + initrd                          (xen)
-     *   - A boot device (and optional kernel+initrd) (hvm)
-     *   - An init script                             (exe)
+     *   - A bootloader (and optional kernel+initrd)            (xen)
+     *   - A kernel + initrd                                    (xen)
+     *   - A boot device (and optional kernel+initrd(+shim))    (hvm)
+     *   - An init script                                       (exe)
      */
 
     switch ((virDomainOSType) def->os.type) {
@@ -28414,6 +28416,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
                           def->os.initrd);
     virBufferEscapeString(buf, "<cmdline>%s</cmdline>\n",
                           def->os.cmdline);
+    virBufferEscapeString(buf, "<shim>%s</shim>\n",
+                          def->os.shim);
     virBufferEscapeString(buf, "<dtb>%s</dtb>\n",
                           def->os.dtb);
     virBufferEscapeString(buf, "<root>%s</root>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e7947741bd..32dabfeaa7 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2501,6 +2501,7 @@ struct _virDomainOSDef {
     char *kernel;
     char *initrd;
     char *cmdline;
+    char *shim;
     char *dtb;
     char *root;
     char *slic_table;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index ad3d17f0fd..6807d8e46a 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1726,6 +1726,12 @@ virDomainDefOSValidate(const virDomainDef *def,
         }
     }
 
+    if (def->os.shim && !def->os.kernel) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("shim only allowed with kernel option"));
+        return -1;
+    }
+
     return 0;
 }
 
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 824da9d066..95196bee6e 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1552,6 +1552,11 @@
           <text/>
         </element>
       </optional>
+      <optional>
+        <element name="shim">
+          <text/>
+        </element>
+      </optional>
       <optional>
         <element name="dtb">
           <ref name="absFilePath"/>
diff --git a/tests/qemuxmlconfdata/launch-security-sev-direct.x86_64-latest.xml b/tests/qemuxmlconfdata/launch-security-sev-direct.x86_64-latest.xml
index e289b1e95e..dea8236540 100644
--- a/tests/qemuxmlconfdata/launch-security-sev-direct.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/launch-security-sev-direct.x86_64-latest.xml
@@ -9,6 +9,7 @@
     <kernel>/vmlinuz</kernel>
     <initrd>/initrd</initrd>
     <cmdline>runme</cmdline>
+    <shim>/shim</shim>
     <boot dev='hd'/>
   </os>
   <cpu mode='custom' match='exact' check='none'>
diff --git a/tests/qemuxmlconfdata/launch-security-sev-direct.xml b/tests/qemuxmlconfdata/launch-security-sev-direct.xml
index 80ce6412dd..76277b6278 100644
--- a/tests/qemuxmlconfdata/launch-security-sev-direct.xml
+++ b/tests/qemuxmlconfdata/launch-security-sev-direct.xml
@@ -9,6 +9,7 @@
     <kernel>/vmlinuz</kernel>
     <initrd>/initrd</initrd>
     <cmdline>runme</cmdline>
+    <shim>/shim</shim>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
-- 
2.45.3