[libvirt PATCH 10/10] conf: stop ignoring <loader>/<nvram> with firmware auto-select

Daniel P. Berrangé berrange at redhat.com
Tue Feb 15 18:54:38 UTC 2022


Currently if the <os>  firmware attribute is set then we silently
ignore most of the <loader> and <nvram> element configs. This
changes the code so that we always fully parse the <loader> and
<nvram> but then use a post-parse method to explicitly reject
invalid combinations.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/conf/domain_conf.c                        | 50 ++++++++++----
 .../os-firmware-efi-bad-loader-path.err       |  1 +
 .../os-firmware-efi-bad-loader-path.xml       | 67 ++++++++++++++++++
 .../os-firmware-efi-bad-loader-type.err       |  1 +
 .../os-firmware-efi-bad-loader-type.xml       | 67 ++++++++++++++++++
 .../os-firmware-efi-bad-nvram-template.err    |  1 +
 .../os-firmware-efi-bad-nvram-template.xml    | 68 +++++++++++++++++++
 tests/qemuxml2argvtest.c                      |  3 +
 8 files changed, 243 insertions(+), 15 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.err
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.err
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.err
 create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ac2e068aea..542c9bda12 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4828,6 +4828,30 @@ virDomainDefPostParseOs(virDomainDef *def)
     }
 
     if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) {
+        if (def->os.loader->path) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("Loader path is not permitted with firmware attribute"));
+            return -1;
+        }
+
+        if (def->os.loader->type) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("Loader type is not permitted with firmware attribute"));
+            return -1;
+        }
+
+        if (def->os.loader->readonly) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("Loader read-only attribute is not permitted with firmware attribute"));
+            return -1;
+        }
+
+        if (def->os.loader->nvramTemplate) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("NVRAM template path is not permitted with firmware attribute"));
+            return -1;
+        }
+
         if (def->os.loader->nvram) {
             virReportError(VIR_ERR_XML_ERROR, "%s",
                            _("NVRAM path is not permitted with firmware attribute"));
@@ -17818,7 +17842,6 @@ virDomainLoaderDefParseXML(virDomainDef *def,
 {
     xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt);
     xmlNodePtr nvram_node = virXPathNode("./os/nvram[1]", ctxt);
-    const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE;
     virDomainLoaderDef *loader;
 
     if (!loader_node && !nvram_node)
@@ -17827,21 +17850,19 @@ virDomainLoaderDefParseXML(virDomainDef *def,
     def->os.loader = loader = g_new0(virDomainLoaderDef, 1);
 
     if (loader_node) {
-        if (!fwAutoSelect) {
-            if (virXMLPropTristateBool(loader_node, "readonly", VIR_XML_PROP_NONE,
-                                       &loader->readonly) < 0)
-                return -1;
+        if (virXMLPropTristateBool(loader_node, "readonly", VIR_XML_PROP_NONE,
+                                   &loader->readonly) < 0)
+            return -1;
 
-            if (virXMLPropEnum(loader_node, "type", virDomainLoaderTypeFromString,
-                               VIR_XML_PROP_NONZERO, &loader->type) < 0)
-                return -1;
+        if (virXMLPropEnum(loader_node, "type", virDomainLoaderTypeFromString,
+                           VIR_XML_PROP_NONZERO, &loader->type) < 0)
+            return -1;
 
-            if (!(loader->path = virXMLNodeContentString(loader_node)))
-                return -1;
+        if (!(loader->path = virXMLNodeContentString(loader_node)))
+            return -1;
 
-            if (STREQ(loader->path, ""))
-                VIR_FREE(loader->path);
-        }
+        if (STREQ(loader->path, ""))
+            VIR_FREE(loader->path);
 
         if (virXMLPropTristateBool(loader_node, "secure", VIR_XML_PROP_NONE,
                                    &loader->secure) < 0)
@@ -17855,8 +17876,7 @@ virDomainLoaderDefParseXML(virDomainDef *def,
         if (STREQ(loader->nvram, ""))
             VIR_FREE(loader->nvram);
 
-        if (!fwAutoSelect)
-            loader->nvramTemplate = virXMLPropString(nvram_node, "template");
+        loader->nvramTemplate = virXMLPropString(nvram_node, "template");
     }
 
     return 0;
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.err
new file mode 100644
index 0000000000..a8dbd0d6d8
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.err
@@ -0,0 +1 @@
+XML error: Loader path is not permitted with firmware attribute
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml
new file mode 100644
index 0000000000..02eec67c35
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml
@@ -0,0 +1,67 @@
+<domain type='kvm'>
+  <name>fedora</name>
+  <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+  <memory unit='KiB'>8192</memory>
+  <currentMemory unit='KiB'>8192</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os firmware='efi'>
+    <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+    <loader secure='no'>/some/path</loader>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+  </features>
+  <clock offset='utc'/>
+  <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='no'/>
+  </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='0x1d' function='0x7'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci1'>
+      <master startport='0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci2'>
+      <master startport='2'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci3'>
+      <master startport='4'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/>
+    </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='dmi-to-pci-bridge'>
+      <model name='i82801b11-bridge'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
+    </controller>
+    <controller type='pci' index='2' model='pci-bridge'>
+      <model name='pci-bridge'/>
+      <target chassisNr='2'/>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </controller>
+    <controller type='pci' index='3' model='pcie-root-port'>
+      <model name='ioh3420'/>
+      <target chassis='3' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.err
new file mode 100644
index 0000000000..2824399628
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.err
@@ -0,0 +1 @@
+XML error: Loader type is not permitted with firmware attribute
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml
new file mode 100644
index 0000000000..9091a2a8ce
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml
@@ -0,0 +1,67 @@
+<domain type='kvm'>
+  <name>fedora</name>
+  <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+  <memory unit='KiB'>8192</memory>
+  <currentMemory unit='KiB'>8192</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os firmware='efi'>
+    <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+    <loader secure='no' type='pflash'/>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+  </features>
+  <clock offset='utc'/>
+  <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='no'/>
+  </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='0x1d' function='0x7'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci1'>
+      <master startport='0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci2'>
+      <master startport='2'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci3'>
+      <master startport='4'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/>
+    </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='dmi-to-pci-bridge'>
+      <model name='i82801b11-bridge'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
+    </controller>
+    <controller type='pci' index='2' model='pci-bridge'>
+      <model name='pci-bridge'/>
+      <target chassisNr='2'/>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </controller>
+    <controller type='pci' index='3' model='pcie-root-port'>
+      <model name='ioh3420'/>
+      <target chassis='3' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.err
new file mode 100644
index 0000000000..866ef34ec4
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.err
@@ -0,0 +1 @@
+XML error: NVRAM template path is not permitted with firmware attribute
diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml
new file mode 100644
index 0000000000..cf77ca5433
--- /dev/null
+++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml
@@ -0,0 +1,68 @@
+<domain type='kvm'>
+  <name>fedora</name>
+  <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid>
+  <memory unit='KiB'>8192</memory>
+  <currentMemory unit='KiB'>8192</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os firmware='efi'>
+    <type arch='x86_64' machine='pc-q35-4.0'>hvm</type>
+    <loader secure='no'/>
+    <nvram template="/some/path">/some/vars</nvram>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+  </features>
+  <clock offset='utc'/>
+  <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='no'/>
+  </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='0x1d' function='0x7'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci1'>
+      <master startport='0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci2'>
+      <master startport='2'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci3'>
+      <master startport='4'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/>
+    </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='dmi-to-pci-bridge'>
+      <model name='i82801b11-bridge'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
+    </controller>
+    <controller type='pci' index='2' model='pci-bridge'>
+      <model name='pci-bridge'/>
+      <target chassisNr='2'/>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+    </controller>
+    <controller type='pci' index='3' model='pcie-root-port'>
+      <model name='ioh3420'/>
+      <target chassis='3' port='0x8'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+    </controller>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 8909dcd064..82105892b0 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3478,7 +3478,10 @@ mymain(void)
 
     DO_TEST_CAPS_LATEST("os-firmware-bios");
     DO_TEST_CAPS_LATEST("os-firmware-efi");
+    DO_TEST_PARSE_ERROR_NOCAPS("os-firmware-efi-bad-loader-path");
+    DO_TEST_PARSE_ERROR_NOCAPS("os-firmware-efi-bad-loader-type");
     DO_TEST_PARSE_ERROR_NOCAPS("os-firmware-efi-bad-nvram-path");
+    DO_TEST_PARSE_ERROR_NOCAPS("os-firmware-efi-bad-nvram-template");
     DO_TEST_CAPS_LATEST("os-firmware-efi-secboot");
     DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys");
     DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64");
-- 
2.34.1




More information about the libvir-list mailing list