diff --git a/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch b/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch new file mode 100644 index 0000000..2b876eb --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch @@ -0,0 +1,415 @@ +From 6f02748897062d40b411177ef752644505189a72 Mon Sep 17 00:00:00 2001 +Message-Id: <6f02748897062d40b411177ef752644505189a72@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:11 +0200 +Subject: [PATCH] conf: introduce support for firmware auto-selection feature + filtering + +When the firmware auto-selection was introduced it always picked first +usable firmware based on the JSON descriptions on the host. It is +possible to add/remove/change the JSON files but it will always be for +the whole host. + +This patch introduces support for configuring the auto-selection per VM +by adding users an option to limit what features they would like to have +available in the firmware. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit cff524af6c5e1ddc11149394ed7f985242ebea0f) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + src/conf/domain_conf.c + - missing following upstream commits: + 0280fc72708b9d0f162a808bcc8d78137a68d58d + 104dadcff6023da676df3905d1ed8688aea15e86 + 2d5f7a49ae0780143566932ab38215433982c89f + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <631e05bc5363abb3e48d8b652a806324801cce16.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 58 +++++++++++++ + docs/schemas/domaincommon.rng | 23 +++++ + src/conf/domain_conf.c | 83 ++++++++++++++++++- + src/conf/domain_conf.h | 10 +++ + ...os-firmware-invalid-type.x86_64-latest.err | 1 + + .../os-firmware-invalid-type.xml | 28 +++++++ + tests/qemuxml2argvtest.c | 1 + + ...aarch64-os-firmware-efi.aarch64-latest.xml | 1 + + .../os-firmware-bios.x86_64-latest.xml | 1 + + .../os-firmware-efi-secboot.x86_64-latest.xml | 1 + + .../os-firmware-efi.x86_64-latest.xml | 1 + + tests/vmx2xmldata/vmx2xml-firmware-efi.xml | 1 + + 12 files changed, 206 insertions(+), 3 deletions(-) + create mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err + create mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index a40bed347b..11f31618af 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -180,6 +180,64 @@ + ESX and VMWare hypervisor drivers, however, + the i686 arch will always be chosen even on an + x86_64 host. Since 0.0.1 ++
firmware
++
++

Since 7.2.0 QEMU/KVM only

++

++ When used together with firmware attribute of ++ os element the type attribute must ++ have the same value. ++

++

++ List of mandatory attributes: ++

    ++
  • ++ type (accepted values are bios ++ and efi) same as the firmware ++ attribute of os element. ++
  • ++
++

++

++ When using firmware auto-selection there are different features ++ enabled in the firmwares. The list of features can be used to ++ limit what firmware should be automatically selected for the VM. ++ The list of features can be specified using zero or more ++ feature elements. Libvirt will take into consideration ++ only the listed features and ignore the rest when selecting the firmware. ++ ++

++
feature
++
++ The list of mandatory attributes: ++ ++
    ++
  • ++ enabled (accepted values are yes ++ and no) is used to tell libvirt if the feature ++ must be enabled or not in the automatically selected firmware ++
  • ++
  • ++ name the name of the feature, the list of the features: ++
      ++
    • ++ enrolled-keys whether the selected nvram template ++ has default certificate enrolled. Firmware with Secure Boot ++ feature but without enrolled keys will successfully boot ++ non-signed binaries as well. Valid only for firmwares with ++ Secure Boot feature. ++
    • ++
    • ++ secure-boot whether the firmware implements ++ UEFI Secure boot feature. ++
    • ++
    ++
  • ++
++
++
++

++
+
loader
+
The optional loader tag refers to a firmware blob, + which is specified by absolute path, +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 6671ef3dfa..b7f6a6b494 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -268,6 +268,29 @@ + + + ++ ++ ++ ++ ++ bios ++ efi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ enrolled-keys ++ secure-boot ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 93a78f8277..28c8d0ecbd 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1240,6 +1240,12 @@ VIR_ENUM_IMPL(virDomainOsDefFirmware, + "efi", + ); + ++VIR_ENUM_IMPL(virDomainOsDefFirmwareFeature, ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST, ++ "enrolled-keys", ++ "secure-boot", ++); ++ + /* Internal mapping: subset of block job types that can be present in + * XML (remaining types are not two-phase). */ + VIR_ENUM_DECL(virDomainBlockJob); +@@ -19382,22 +19388,67 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) + { + g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); ++ g_autofree char *type = virXPathString("string(./os/firmware/@type)", ctxt); ++ g_autofree xmlNodePtr *nodes = NULL; ++ g_autofree int *features = NULL; + int fw = 0; ++ int n = 0; ++ size_t i; + +- if (!firmware) ++ if (!firmware && !type) + return 0; + +- fw = virDomainOsDefFirmwareTypeFromString(firmware); ++ if (firmware && type && STRNEQ(firmware, type)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("firmware attribute and firmware type has to be the same")); ++ return -1; ++ } ++ ++ if (!type) ++ type = g_steal_pointer(&firmware); ++ ++ fw = virDomainOsDefFirmwareTypeFromString(type); + + if (fw <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown firmware value %s"), +- firmware); ++ type); + return -1; + } + + def->os.firmware = fw; + ++ if ((n = virXPathNodeSet("./os/firmware/feature", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (n > 0) ++ features = g_new0(int, VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST); ++ ++ for (i = 0; i < n; i++) { ++ g_autofree char *name = virXMLPropString(nodes[i], "name"); ++ g_autofree char *enabled = virXMLPropString(nodes[i], "enabled"); ++ int feature = virDomainOsDefFirmwareFeatureTypeFromString(name); ++ int val = virTristateBoolTypeFromString(enabled); ++ ++ if (feature < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("invalid firmware feature name '%s'"), ++ name); ++ return -1; ++ } ++ ++ if (val < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("invalid firmware feature enabled value '%s'"), ++ enabled); ++ return -1; ++ } ++ ++ features[feature] = val; ++ } ++ ++ def->os.firmwareFeatures = g_steal_pointer(&features); ++ + return 0; + } + +@@ -28987,6 +29038,32 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + virBufferAsprintf(buf, ">%s\n", + virDomainOSTypeToString(def->os.type)); + ++ if (def->os.firmware) { ++ virBufferAsprintf(buf, "os.firmware)); ++ ++ if (def->os.firmwareFeatures) { ++ virBufferAddLit(buf, ">\n"); ++ ++ virBufferAdjustIndent(buf, 2); ++ ++ for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { ++ if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) ++ continue; ++ ++ virBufferAsprintf(buf, "\n", ++ virTristateBoolTypeToString(def->os.firmwareFeatures[i]), ++ virDomainOsDefFirmwareFeatureTypeToString(i)); ++ } ++ ++ virBufferAdjustIndent(buf, -2); ++ ++ virBufferAddLit(buf, "\n"); ++ } else { ++ virBufferAddLit(buf, "/>\n"); ++ } ++ } ++ + virBufferEscapeString(buf, "%s\n", + def->os.init); + for (i = 0; def->os.initargv && def->os.initargv[i]; i++) +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 3aed1fb22a..1ad77ecac6 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -1967,9 +1967,19 @@ G_STATIC_ASSERT((int)VIR_DOMAIN_OS_DEF_FIRMWARE_LAST == (int)VIR_DOMAIN_LOADER_T + + VIR_ENUM_DECL(virDomainOsDefFirmware); + ++typedef enum { ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS, ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT, ++ ++ VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST ++} virDomainOsDefFirmwareFeature; ++ ++VIR_ENUM_DECL(virDomainOsDefFirmwareFeature); ++ + struct _virDomainOSDef { + int type; + virDomainOsDefFirmware firmware; ++ int *firmwareFeatures; + virArch arch; + char *machine; + size_t nBootDevs; +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err +new file mode 100644 +index 0000000000..c8174b1c8b +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-invalid-type.x86_64-latest.err +@@ -0,0 +1 @@ ++unsupported configuration: firmware attribute and firmware type has to be the same +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +new file mode 100644 +index 0000000000..41360df0f7 +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +@@ -0,0 +1,28 @@ ++ ++ fedora ++ 63840878-0deb-4095-97e6-fc444d9bc9fa ++ 8192 ++ 8192 ++ 1 ++ ++ hvm ++ ++ ++ /var/lib/libvirt/qemu/nvram/fedora_VARS.fd ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ restart ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index a22e3ba157..bc04bea692 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3094,6 +3094,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + + DO_TEST_CAPS_LATEST("vhost-user-vga"); +diff --git a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +index 1e51d55305..3cac8fc5c6 100644 +--- a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml ++++ b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + /aarch64.kernel + /aarch64.initrd + earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait +diff --git a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +index 60d3498765..ef24f2fece 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +index 938da73711..3757191e8e 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +index 97ce8a75c7..f2e6b7f36d 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +@@ -6,6 +6,7 @@ + 1 + + hvm ++ + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +index e21158cebf..375c47d281 100644 +--- a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml ++++ b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +@@ -5,6 +5,7 @@ + 1 + + hvm ++ + + + destroy +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch new file mode 100644 index 0000000..f3d6fd4 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch @@ -0,0 +1,124 @@ +From 7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b Mon Sep 17 00:00:00 2001 +Message-Id: <7ba2905bfcab4dbe4a491ee8587dd4c9ef457c0b@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:09 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootAcpiOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 108cb29c1c7eec7b9089dd431e0bdcd82a0b07f1) + +Conflicts: + src/conf/domain_conf.c + - missing upstream commit d293a556d710754d8aa8d5caac0bb01a365fcbd8 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <5fb7ee0165340ff517b3f7f16ddc542813ac385d.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 71 ++++++++++++++++++++++++------------------ + 1 file changed, 41 insertions(+), 30 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 493700ed6b..f8d8d33245 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19429,13 +19429,51 @@ virDomainDefParseBootLoaderOptions(virDomainDefPtr def, + + + static int +-virDomainDefParseBootOptions(virDomainDefPtr def, +- xmlXPathContextPtr ctxt) ++virDomainDefParseBootAcpiOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) + { + int n; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + ++ if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (n > 1) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Only one acpi table is supported")); ++ return -1; ++ } ++ ++ if (n == 1) { ++ tmp = virXMLPropString(nodes[0], "type"); ++ ++ if (!tmp) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing acpi table type")); ++ return -1; ++ } ++ ++ if (STREQ_NULLABLE(tmp, "slic")) { ++ VIR_FREE(tmp); ++ tmp = virXMLNodeContentString(nodes[0]); ++ def->os.slic_table = virFileSanitizePath(tmp); ++ } else { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Unknown acpi table type: %s"), ++ tmp); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainDefParseBootOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ + /* + * Booting options for different OS types.... + * +@@ -19467,36 +19505,9 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +- if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0) ++ if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) + return -1; + +- if (n > 1) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Only one acpi table is supported")); +- return -1; +- } +- +- if (n == 1) { +- tmp = virXMLPropString(nodes[0], "type"); +- +- if (!tmp) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Missing acpi table type")); +- return -1; +- } +- +- if (STREQ_NULLABLE(tmp, "slic")) { +- VIR_FREE(tmp); +- tmp = virXMLNodeContentString(nodes[0]); +- def->os.slic_table = virFileSanitizePath(tmp); +- } else { +- virReportError(VIR_ERR_XML_ERROR, +- _("Unknown acpi table type: %s"), +- tmp); +- return -1; +- } +- } +- + if (virDomainDefParseBootXML(ctxt, def) < 0) + return -1; + } +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch new file mode 100644 index 0000000..409c3bd --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch @@ -0,0 +1,86 @@ +From 2a019bfa26e697c60893afd09fcc2f0c3218691b Mon Sep 17 00:00:00 2001 +Message-Id: <2a019bfa26e697c60893afd09fcc2f0c3218691b@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:07 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootFirmwareOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit bcf97abfc6b45694f0d789ae2bdf87c8d082fddf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <9a090d9f2a43b261ed1b6db608779a01a7594f4a.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 39 +++++++++++++++++++++++++++------------ + 1 file changed, 27 insertions(+), 12 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 432ad938f9..bb484a57c6 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19377,6 +19377,31 @@ virDomainDefParseBootKernelOptions(virDomainDefPtr def, + } + + ++static int ++virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); ++ int fw = 0; ++ ++ if (!firmware) ++ return 0; ++ ++ fw = virDomainOsDefFirmwareTypeFromString(firmware); ++ ++ if (fw <= 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("unknown firmware value %s"), ++ firmware); ++ return -1; ++ } ++ ++ def->os.firmware = fw; ++ ++ return 0; ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19403,23 +19428,13 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || + def->os.type == VIR_DOMAIN_OSTYPE_HVM || + def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- g_autofree char *firmware = NULL; + xmlNodePtr loader_node; + + virDomainDefParseBootKernelOptions(def, ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && +- (firmware = virXPathString("string(./os/@firmware)", ctxt))) { +- int fw = virDomainOsDefFirmwareTypeFromString(firmware); +- +- if (fw <= 0) { +- virReportError(VIR_ERR_XML_ERROR, +- _("unknown firmware value %s"), +- firmware); ++ if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { ++ if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) + return -1; +- } +- +- def->os.firmware = fw; + } + + if ((loader_node = virXPathNode("./os/loader[1]", ctxt))) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch new file mode 100644 index 0000000..4195af7 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch @@ -0,0 +1,173 @@ +From adafaa880b67f1025c64515352e5e851daa62ae9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:05 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootInitOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit b07116438c96fddfa00bdb57878a707240574b42) + +Conflicts: + src/conf/domain_conf.c + - using VIR_ALLOC in downstream instead of g_new0 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 115 +++++++++++++++++++++++------------------ + 1 file changed, 64 insertions(+), 51 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 444657c9a1..9eb418c7c0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19302,76 +19302,89 @@ virDomainVcpuParse(virDomainDefPtr def, + + + static int +-virDomainDefParseBootOptions(virDomainDefPtr def, +- xmlXPathContextPtr ctxt) ++virDomainDefParseBootInitOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) + { + char *name = NULL; + size_t i; + int n; + g_autofree xmlNodePtr *nodes = NULL; +- g_autofree char *tmp = NULL; + +- /* +- * 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) +- */ ++ def->os.init = virXPathString("string(./os/init[1])", ctxt); ++ def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); ++ def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt); ++ def->os.inituser = virXPathString("string(./os/inituser[1])", ctxt); ++ def->os.initgroup = virXPathString("string(./os/initgroup[1])", ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { +- def->os.init = virXPathString("string(./os/init[1])", ctxt); +- def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt); +- def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt); +- def->os.inituser = virXPathString("string(./os/inituser[1])", ctxt); +- def->os.initgroup = virXPathString("string(./os/initgroup[1])", ctxt); ++ if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0) ++ return -1; + +- if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0) ++ if (VIR_ALLOC_N(def->os.initargv, n+1) < 0) ++ return -1; ++ for (i = 0; i < n; i++) { ++ if (!nodes[i]->children || ++ !nodes[i]->children->content) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("No data supplied for element")); + return -1; ++ } ++ def->os.initargv[i] = g_strdup((const char *)nodes[i]->children->content); ++ } ++ def->os.initargv[n] = NULL; ++ VIR_FREE(nodes); + +- if (VIR_ALLOC_N(def->os.initargv, n+1) < 0) ++ if ((n = virXPathNodeSet("./os/initenv", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (VIR_ALLOC_N(def->os.initenv, n+1) < 0) ++ return -1; ++ for (i = 0; i < n; i++) { ++ if (!(name = virXMLPropString(nodes[i], "name"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("No name supplied for element")); + return -1; +- for (i = 0; i < n; i++) { +- if (!nodes[i]->children || +- !nodes[i]->children->content) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("No data supplied for element")); +- return -1; +- } +- def->os.initargv[i] = g_strdup((const char *)nodes[i]->children->content); + } +- def->os.initargv[n] = NULL; +- VIR_FREE(nodes); + +- if ((n = virXPathNodeSet("./os/initenv", ctxt, &nodes)) < 0) ++ if (!nodes[i]->children || ++ !nodes[i]->children->content) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("No value supplied for element"), ++ name); + return -1; ++ } + +- if (VIR_ALLOC_N(def->os.initenv, n+1) < 0) ++ if (VIR_ALLOC(def->os.initenv[i]) < 0) + return -1; +- for (i = 0; i < n; i++) { +- if (!(name = virXMLPropString(nodes[i], "name"))) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("No name supplied for element")); +- return -1; +- } + +- if (!nodes[i]->children || +- !nodes[i]->children->content) { +- virReportError(VIR_ERR_XML_ERROR, +- _("No value supplied for element"), +- name); +- return -1; +- } ++ def->os.initenv[i]->name = name; ++ def->os.initenv[i]->value = g_strdup((const char *)nodes[i]->children->content); ++ } ++ def->os.initenv[n] = NULL; + +- if (VIR_ALLOC(def->os.initenv[i]) < 0) +- return -1; ++ return 0; ++} + +- def->os.initenv[i]->name = name; +- def->os.initenv[i]->value = g_strdup((const char *)nodes[i]->children->content); +- } +- def->os.initenv[n] = NULL; +- VIR_FREE(nodes); ++ ++static int ++virDomainDefParseBootOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ int n; ++ g_autofree xmlNodePtr *nodes = NULL; ++ g_autofree char *tmp = NULL; ++ ++ /* ++ * 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) ++ */ ++ ++ if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { ++ if (virDomainDefParseBootInitOptions(def, ctxt) < 0) ++ return -1; + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_XEN || +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch new file mode 100644 index 0000000..a418a03 --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch @@ -0,0 +1,60 @@ +From a62075772680bd30ced25d7177048ab26db8ea09 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:06 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootKernelOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit bf9b3f8e573092cc98ea647f25cf116e22bbfe3c) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <936428a5fa6d4104361ac8080639a55111c14965.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9eb418c7c0..432ad938f9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19365,6 +19365,18 @@ virDomainDefParseBootInitOptions(virDomainDefPtr def, + } + + ++static void ++virDomainDefParseBootKernelOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ 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.dtb = virXPathString("string(./os/dtb[1])", ctxt); ++ def->os.root = virXPathString("string(./os/root[1])", ctxt); ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19394,11 +19406,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + g_autofree char *firmware = NULL; + xmlNodePtr loader_node; + +- 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.dtb = virXPathString("string(./os/dtb[1])", ctxt); +- def->os.root = virXPathString("string(./os/root[1])", ctxt); ++ virDomainDefParseBootKernelOptions(def, ctxt); + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && + (firmware = virXPathString("string(./os/@firmware)", ctxt))) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch new file mode 100644 index 0000000..599fbfc --- /dev/null +++ b/SOURCES/libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch @@ -0,0 +1,97 @@ +From 6891ef941e693d86ebbab9e529e908dacf4a7dc6 Mon Sep 17 00:00:00 2001 +Message-Id: <6891ef941e693d86ebbab9e529e908dacf4a7dc6@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:08 +0200 +Subject: [PATCH] conf: introduce virDomainDefParseBootLoaderOptions + +Extract the code to it's own function. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit b8dd70db4ee2f3a5edcbbeb8515830db9652cb59) + +Conflicts: + src/conf/domain_conf.c + - using VIR_ALLOC in downstream instead of g_new0 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++--------------- + 1 file changed, 28 insertions(+), 16 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index bb484a57c6..493700ed6b 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19402,6 +19402,32 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + } + + ++static int ++virDomainDefParseBootLoaderOptions(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt) ++{ ++ xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); ++ const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; ++ ++ if (!loader_node) ++ return 0; ++ ++ if (VIR_ALLOC(def->os.loader) < 0) ++ return -1; ++ ++ if (virDomainLoaderDefParseXML(loader_node, ++ def->os.loader, ++ fwAutoSelect) < 0) ++ return -1; ++ ++ def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt); ++ if (!fwAutoSelect) ++ def->os.loader->templt = virXPathString("string(./os/nvram[1]/@template)", ctxt); ++ ++ return 0; ++} ++ ++ + static int + virDomainDefParseBootOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +@@ -19428,7 +19454,6 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || + def->os.type == VIR_DOMAIN_OSTYPE_HVM || + def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- xmlNodePtr loader_node; + + virDomainDefParseBootKernelOptions(def, ctxt); + +@@ -19437,21 +19462,8 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + return -1; + } + +- if ((loader_node = virXPathNode("./os/loader[1]", ctxt))) { +- const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; +- +- if (VIR_ALLOC(def->os.loader) < 0) +- return -1; +- +- if (virDomainLoaderDefParseXML(loader_node, +- def->os.loader, +- fwAutoSelect) < 0) +- return -1; +- +- def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt); +- if (!fwAutoSelect) +- def->os.loader->templt = virXPathString("string(./os/nvram[1]/@template)", ctxt); +- } ++ if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) ++ return -1; + } + + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch b/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch new file mode 100644 index 0000000..3bc500f --- /dev/null +++ b/SOURCES/libvirt-conf-remove-duplicated-firmware-type-attribute.patch @@ -0,0 +1,317 @@ +From 4ca3f2f590fb860b01f1eb5fec8929ceba702dc6 Mon Sep 17 00:00:00 2001 +Message-Id: <4ca3f2f590fb860b01f1eb5fec8929ceba702dc6@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 May 2021 14:16:14 +0200 +Subject: [PATCH] conf: remove duplicated firmware type attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The + + + + + + + +repeats the firmware attribute twice. This has no functional benefit, as +evidenced by fact that we use a single struct field to store both +attributes, while needlessly introducing an error scenario. The XML can +just be simplified to: + + + + + + + +which also means that we don't need to emit the empty element + for all existing configs too. + +Reviewed-by: Pavel Hrdina +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit a9b1375d7d2f7d240dce09c5f8b62e568e386051) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <299fd16fc3ce632bf25ca55cc4bb65a225437d61.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 15 ------ + docs/schemas/domaincommon.rng | 10 +--- + src/conf/domain_conf.c | 48 ++++++------------- + .../os-firmware-efi-no-enrolled-keys.xml | 2 +- + .../os-firmware-invalid-type.xml | 28 ----------- + tests/qemuxml2argvtest.c | 1 - + ...aarch64-os-firmware-efi.aarch64-latest.xml | 1 - + .../os-firmware-bios.x86_64-latest.xml | 1 - + .../os-firmware-efi-secboot.x86_64-latest.xml | 1 - + .../os-firmware-efi.x86_64-latest.xml | 1 - + tests/vmx2xmldata/vmx2xml-firmware-efi.xml | 1 - + 11 files changed, 18 insertions(+), 91 deletions(-) + delete mode 100644 tests/qemuxml2argvdata/os-firmware-invalid-type.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 11f31618af..79e2e51c54 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -183,21 +183,6 @@ +
firmware
+
+

Since 7.2.0 QEMU/KVM only

+-

+- When used together with firmware attribute of +- os element the type attribute must +- have the same value. +-

+-

+- List of mandatory attributes: +-

    +-
  • +- type (accepted values are bios +- and efi) same as the firmware +- attribute of os element. +-
  • +-
+-

+

+ When using firmware auto-selection there are different features + enabled in the firmwares. The list of features can be used to +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index b7f6a6b494..ec8167e588 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -270,13 +270,7 @@ + + + +- +- +- bios +- efi +- +- +- ++ + + + +@@ -288,7 +282,7 @@ + + + +- ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 2ffa9c8a2a..6806064016 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19389,31 +19389,21 @@ virDomainDefParseBootFirmwareOptions(virDomainDefPtr def, + xmlXPathContextPtr ctxt) + { + g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); +- g_autofree char *type = virXPathString("string(./os/firmware/@type)", ctxt); + g_autofree xmlNodePtr *nodes = NULL; + g_autofree int *features = NULL; + int fw = 0; + int n = 0; + size_t i; + +- if (!firmware && !type) ++ if (!firmware) + return 0; + +- if (firmware && type && STRNEQ(firmware, type)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("firmware attribute and firmware type has to be the same")); +- return -1; +- } +- +- if (!type) +- type = g_steal_pointer(&firmware); +- +- fw = virDomainOsDefFirmwareTypeFromString(type); ++ fw = virDomainOsDefFirmwareTypeFromString(firmware); + + if (fw <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown firmware value %s"), +- type); ++ firmware); + return -1; + } + +@@ -29039,30 +29029,22 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + virBufferAsprintf(buf, ">%s\n", + virDomainOSTypeToString(def->os.type)); + +- if (def->os.firmware) { +- virBufferAsprintf(buf, "os.firmware)); +- +- if (def->os.firmwareFeatures) { +- virBufferAddLit(buf, ">\n"); +- +- virBufferAdjustIndent(buf, 2); ++ if (def->os.firmwareFeatures) { ++ virBufferAddLit(buf, "\n"); ++ virBufferAdjustIndent(buf, 2); + +- for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { +- if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) +- continue; ++ for (i = 0; i < VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST; i++) { ++ if (def->os.firmwareFeatures[i] == VIR_TRISTATE_BOOL_ABSENT) ++ continue; + +- virBufferAsprintf(buf, "\n", +- virTristateBoolTypeToString(def->os.firmwareFeatures[i]), +- virDomainOsDefFirmwareFeatureTypeToString(i)); +- } ++ virBufferAsprintf(buf, "\n", ++ virTristateBoolTypeToString(def->os.firmwareFeatures[i]), ++ virDomainOsDefFirmwareFeatureTypeToString(i)); ++ } + +- virBufferAdjustIndent(buf, -2); ++ virBufferAdjustIndent(buf, -2); + +- virBufferAddLit(buf, "\n"); +- } else { +- virBufferAddLit(buf, "/>\n"); +- } ++ virBufferAddLit(buf, "\n"); + } + + virBufferEscapeString(buf, "%s\n", +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +index 7f8f57a859..4999c4f125 100644 +--- a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +@@ -6,7 +6,7 @@ + 1 + + hvm +- ++ + + + +diff --git a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml b/tests/qemuxml2argvdata/os-firmware-invalid-type.xml +deleted file mode 100644 +index 41360df0f7..0000000000 +--- a/tests/qemuxml2argvdata/os-firmware-invalid-type.xml ++++ /dev/null +@@ -1,28 +0,0 @@ +- +- fedora +- 63840878-0deb-4095-97e6-fc444d9bc9fa +- 8192 +- 8192 +- 1 +- +- hvm +- +- +- /var/lib/libvirt/qemu/nvram/fedora_VARS.fd +- +- +- +- +- +- +- +- +- +- destroy +- restart +- restart +- +- /usr/bin/qemu-system-x86_64 +- +- +- +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 5e16d7fd31..be8054fa6a 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3095,7 +3095,6 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); + DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); +- DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + + DO_TEST_CAPS_LATEST("vhost-user-vga"); +diff --git a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +index 3cac8fc5c6..1e51d55305 100644 +--- a/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml ++++ b/tests/qemuxml2xmloutdata/aarch64-os-firmware-efi.aarch64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + /aarch64.kernel + /aarch64.initrd + earlyprintk console=ttyAMA0,115200n8 rw root=/dev/vda rootwait +diff --git a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +index ef24f2fece..60d3498765 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +index 3757191e8e..938da73711 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +index f2e6b7f36d..97ce8a75c7 100644 +--- a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +@@ -6,7 +6,6 @@ + 1 + + hvm +- + + /var/lib/libvirt/qemu/nvram/fedora_VARS.fd + +diff --git a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +index 375c47d281..e21158cebf 100644 +--- a/tests/vmx2xmldata/vmx2xml-firmware-efi.xml ++++ b/tests/vmx2xmldata/vmx2xml-firmware-efi.xml +@@ -5,7 +5,6 @@ + 1 + + hvm +- + + + destroy +-- +2.31.1 + diff --git a/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch b/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch new file mode 100644 index 0000000..e4a8822 --- /dev/null +++ b/SOURCES/libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch @@ -0,0 +1,89 @@ +From 75470b7c297be9bdd712282b89c48465dbe8d400 Mon Sep 17 00:00:00 2001 +Message-Id: <75470b7c297be9bdd712282b89c48465dbe8d400@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:10 +0200 +Subject: [PATCH] conf: use switch in virDomainDefParseBootOptions + +The original code used a lot of conditions and was not that obvious +when each XML bits are parsed. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 6330be1ba3af5c4d2150fe2b831f7bc5d87c6d2a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <900c870b1720688123ed7b69850548ae308ea9a8.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 42 ++++++++++++++++++++++++++---------------- + 1 file changed, 26 insertions(+), 16 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index f8d8d33245..93a78f8277 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19483,33 +19483,43 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + * - An init script (exe) + */ + +- if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { +- if (virDomainDefParseBootInitOptions(def, ctxt) < 0) +- return -1; +- } +- +- if (def->os.type == VIR_DOMAIN_OSTYPE_XEN || +- def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || +- def->os.type == VIR_DOMAIN_OSTYPE_HVM || +- def->os.type == VIR_DOMAIN_OSTYPE_UML) { +- ++ switch ((virDomainOSType) def->os.type) { ++ case VIR_DOMAIN_OSTYPE_HVM: + virDomainDefParseBootKernelOptions(def, ctxt); + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { +- if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) +- return -1; +- } ++ if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) ++ return -1; + + if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + return -1; +- } + +- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { + if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) + return -1; + + if (virDomainDefParseBootXML(ctxt, def) < 0) + return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_XEN: ++ case VIR_DOMAIN_OSTYPE_XENPVH: ++ case VIR_DOMAIN_OSTYPE_UML: ++ virDomainDefParseBootKernelOptions(def, ctxt); ++ ++ if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) ++ return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_EXE: ++ if (virDomainDefParseBootInitOptions(def, ctxt) < 0) ++ return -1; ++ ++ break; ++ ++ case VIR_DOMAIN_OSTYPE_LINUX: ++ case VIR_DOMAIN_OSTYPE_LAST: ++ break; + } + + return 0; +-- +2.31.1 + diff --git a/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch b/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch new file mode 100644 index 0000000..9114b14 --- /dev/null +++ b/SOURCES/libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch @@ -0,0 +1,47 @@ +From 3398815aa337278fe4085f06f3586b2a1a98ab3d Mon Sep 17 00:00:00 2001 +Message-Id: <3398815aa337278fe4085f06f3586b2a1a98ab3d@dist-git> +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:04 +0200 +Subject: [PATCH] docs: improve description of secure attribute for loader + element + +The original text was not explaining what this attribute actually +controls and could have been interpreted as a control switch for the +Secure boot feature in firmwares. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Kashyap Chamarthy +Reviewed-by: Michal Privoznik +(cherry picked from commit f47d06260b9698f705ab2c079c573f89f832e376) + +Conflicts: + docs/formatdomain.rst + - we still have formatdomain.html.in in downstream + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + docs/formatdomain.html.in | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 7ac9523684..a40bed347b 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -197,7 +197,9 @@ + path points to an UEFI image, type should be + pflash. Moreover, some firmwares may + implement the Secure boot feature. Attribute +- secure can be used then to control it. ++ secure can be used to tell the hypervisor that the ++ firmware is capable of Secure Boot feature. It cannot be used to ++ enable or disable the feature itself in the firmware. + Since 2.1.0

+
nvram
+
Some UEFI firmwares may want to use a non-volatile memory to store +-- +2.31.1 + diff --git a/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch b/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch new file mode 100644 index 0000000..431bb2f --- /dev/null +++ b/SOURCES/libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch @@ -0,0 +1,43 @@ +From 8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5 Mon Sep 17 00:00:00 2001 +Message-Id: <8ad6e3bc6d3e9e55093b546ee886a2a2d9e875f5@dist-git> +From: Michal Privoznik +Date: Fri, 21 May 2021 14:16:13 +0200 +Subject: [PATCH] domain_conf: Don't leak def->os.firmwareFeatures + +The firmwareFeatures member of virDomainOSDef struct is allocated +in virDomainDefParseBootFirmwareOptions() but never freed. + +Signed-off-by: Michal Privoznik +Reviewed-by: Pavel Hrdina +(cherry picked from commit c116b9481426f86188c71f340d5e3db103120bf8) + +Conflicts: + src/conf/domain_conf.c + - missing upstream commits: + 77f8e48fc35eaf867eae4f623e381f87f6e29930 + f9f81f1c8f855b8c21aeae4441abfc877ff2bfc3 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: <82f4beea71e682c43ec10370d5a43a608d1cb411.1621599207.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/conf/domain_conf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 28c8d0ecbd..2ffa9c8a2a 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3431,6 +3431,7 @@ void virDomainDefFree(virDomainDefPtr def) + VIR_FREE(def->idmap.uidmap); + VIR_FREE(def->idmap.gidmap); + ++ VIR_FREE(def->os.firmwareFeatures); + VIR_FREE(def->os.machine); + VIR_FREE(def->os.init); + for (i = 0; def->os.initargv && def->os.initargv[i]; i++) +-- +2.31.1 + diff --git a/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch b/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch new file mode 100644 index 0000000..96deffe --- /dev/null +++ b/SOURCES/libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch @@ -0,0 +1,50 @@ +From bad40f7148a5849e84e9cdc341ff1fa03dc94fc6 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Thomas Huth +Date: Tue, 11 May 2021 14:10:27 +0200 +Subject: [PATCH] hostdev: Update mdev pointer reference after checking device + type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We set the pointer to some garbage packed structure data without +knowing whether we were actually handling the type of device we +expected to be handling. On its own, this was harmless, because we'd +never use the pointer as we'd skip the device if it were not the +expected type. However, it's better to make the logic even more +explicit - we first check the device and only when we're sure we have +the expected type we then update the pointer shortcut. + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 964738cff3d949d90fc5c3317a2618fcd8d217b4) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449 +Signed-off-by: Thomas Huth +Message-Id: <20210511121028.304070-2-thuth@redhat.com> +Reviewed-by: Erik Skultety +--- + src/util/virhostdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c +index 9596482146..b7050e99e4 100644 +--- a/src/util/virhostdev.c ++++ b/src/util/virhostdev.c +@@ -2030,11 +2030,11 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; + +- mdevsrc = &hostdev->source.subsys.u.mdev; +- + if (!virHostdevIsMdevDevice(hostdev)) + continue; + ++ mdevsrc = &hostdev->source.subsys.u.mdev; ++ + if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, + mdevsrc->model))) + continue; +-- +2.31.1 + diff --git a/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch b/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch new file mode 100644 index 0000000..3b68fb0 --- /dev/null +++ b/SOURCES/libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch @@ -0,0 +1,166 @@ +From 9e97e35031572e0f6ace32e2fb094f0f358f0391 Mon Sep 17 00:00:00 2001 +Message-Id: <9e97e35031572e0f6ace32e2fb094f0f358f0391@dist-git> +From: Thomas Huth +Date: Tue, 11 May 2021 14:10:28 +0200 +Subject: [PATCH] hostdev: mdev: Lookup mdevs by sysfs path rather than mdev + struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The lookup didn't do anything apart from comparing the sysfs paths +anyway since that's what makes each mdev unique. +The most ridiculous usage of the old logic was in +virHostdevReAttachMediatedDevices where in order to drop an mdev +hostdev from the list of active devices we first had to create a new +mdev and use it in the lookup call. Why couldn't we have used the +hostdev directly? Because the hostdev and mdev structures are +incompatible. + +The way mdevs are currently removed is via a write to a specific sysfs +attribute. If you do it while the machine which has the mdev assigned +is running, the write call may block (with a new enough kernel, with +older kernels it would return a write error!) until the device +is no longer in use which is when the QEMU process exits. + +The interesting part here comes afterwards when we're cleaning up and +call virHostdevReAttachMediatedDevices. The domain doesn't exist +anymore, so the list of active hostdevs needs to be updated and the +respective hostdevs removed from the list, but remember we had to +create an mdev object in the memory in order to find it in the list +first which will fail because the write to sysfs had already removed +the mdev instance from the host system. +And so the next time you try to start the same domain you'll get: + +"Requested operation is not valid: mediated device is in use by +driver QEMU, domain " + +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/119 + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 49cb59778a4e6c2d04bb9383a9d97fbbc83f9fce) +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940449 +Signed-off-by: Thomas Huth +Message-Id: <20210511121028.304070-3-thuth@redhat.com> +Reviewed-by: Erik Skultety +--- + src/util/virhostdev.c | 10 ++++------ + src/util/virmdev.c | 16 ++++++++-------- + src/util/virmdev.h | 4 ++-- + 3 files changed, 14 insertions(+), 16 deletions(-) + +diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c +index b7050e99e4..392e94307c 100644 +--- a/src/util/virhostdev.c ++++ b/src/util/virhostdev.c +@@ -2025,7 +2025,7 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + + virObjectLock(mgr->activeMediatedHostdevs); + for (i = 0; i < nhostdevs; i++) { +- g_autoptr(virMediatedDevice) mdev = NULL; ++ g_autofree char *sysfspath = NULL; + virMediatedDevicePtr tmp; + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; +@@ -2034,14 +2034,12 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + continue; + + mdevsrc = &hostdev->source.subsys.u.mdev; +- +- if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, +- mdevsrc->model))) +- continue; ++ sysfspath = virMediatedDeviceGetSysfsPath(mdevsrc->uuidstr); + + /* Remove from the list only mdevs assigned to @drv_name/@dom_name */ + +- tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, mdev); ++ tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, ++ sysfspath); + + /* skip inactive devices */ + if (!tmp) +diff --git a/src/util/virmdev.c b/src/util/virmdev.c +index c2499c0a20..bae4a7d2c1 100644 +--- a/src/util/virmdev.c ++++ b/src/util/virmdev.c +@@ -312,7 +312,7 @@ int + virMediatedDeviceListAdd(virMediatedDeviceListPtr list, + virMediatedDevicePtr *dev) + { +- if (virMediatedDeviceListFind(list, *dev)) { ++ if (virMediatedDeviceListFind(list, (*dev)->path)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device %s is already in use"), (*dev)->path); + return -1; +@@ -358,7 +358,7 @@ virMediatedDevicePtr + virMediatedDeviceListSteal(virMediatedDeviceListPtr list, + virMediatedDevicePtr dev) + { +- int idx = virMediatedDeviceListFindIndex(list, dev); ++ int idx = virMediatedDeviceListFindIndex(list, dev->path); + + return virMediatedDeviceListStealIndex(list, idx); + } +@@ -374,13 +374,13 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + size_t i; + + for (i = 0; i < list->count; i++) { +- virMediatedDevicePtr other = list->devs[i]; +- if (STREQ(other->path, dev->path)) ++ virMediatedDevicePtr dev = list->devs[i]; ++ if (STREQ(sysfspath, dev->path)) + return i; + } + return -1; +@@ -389,11 +389,11 @@ virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + int idx; + +- if ((idx = virMediatedDeviceListFindIndex(list, dev)) >= 0) ++ if ((idx = virMediatedDeviceListFindIndex(list, sysfspath)) >= 0) + return list->devs[idx]; + else + return NULL; +@@ -407,7 +407,7 @@ virMediatedDeviceIsUsed(virMediatedDevicePtr dev, + const char *drvname, *domname; + virMediatedDevicePtr tmp = NULL; + +- if ((tmp = virMediatedDeviceListFind(list, dev))) { ++ if ((tmp = virMediatedDeviceListFind(list, dev->path))) { + virMediatedDeviceGetUsedBy(tmp, &drvname, &domname); + virReportError(VIR_ERR_OPERATION_INVALID, + _("mediated device %s is in use by " +diff --git a/src/util/virmdev.h b/src/util/virmdev.h +index e0905a3f6e..3022ab9948 100644 +--- a/src/util/virmdev.h ++++ b/src/util/virmdev.h +@@ -120,11 +120,11 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr dst, +-- +2.31.1 + diff --git a/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch b/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch index aff2f23..f35830d 100644 --- a/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch +++ b/SOURCES/libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch @@ -1,7 +1,7 @@ -From 39a3e7f108cfb5c534bbbc6bc06e416bb93d33fb Mon Sep 17 00:00:00 2001 -Message-Id: <39a3e7f108cfb5c534bbbc6bc06e416bb93d33fb@dist-git> +From 021167719bebe7fb7a0e366c371b6c7057ebed7e Mon Sep 17 00:00:00 2001 +Message-Id: <021167719bebe7fb7a0e366c371b6c7057ebed7e@dist-git> From: Laine Stump -Date: Tue, 11 May 2021 15:48:05 -0400 +Date: Wed, 14 Apr 2021 23:25:34 -0400 Subject: [PATCH] network: force re-creation of iptables private chains on firewalld restart MIME-Version: 1.0 @@ -63,6 +63,9 @@ Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrangé (cherry picked from commit f5418b427e7d2f26803880309478de9103680826) +https://bugzilla.redhat.com/1942805 +(cloned from the RHEL-AV version: https://bugzilla.redhat.com/1813830 ) + Conflicts: src/network/bridge_driver.c: In one place a later commit was backported prior to this commit, @@ -70,10 +73,9 @@ Conflicts: c102bbd3efc35, which was backported for https://bugzilla.redhat.com/1607929 -https://bugzilla.redhat.com/1958301 Signed-off-by: Laine Stump -Message-Id: <20210511194805.365503-3-laine@redhat.com> -Reviewed-by: Michal Privoznik +Message-Id: <20210415032534.723202-3-laine@redhat.com> +Reviewed-by: Pavel Hrdina --- src/network/bridge_driver.c | 16 ++++--- src/network/bridge_driver_linux.c | 69 ++++++++++++++++++---------- diff --git a/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch b/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch index 88d6a74..b07b70d 100644 --- a/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch +++ b/SOURCES/libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch @@ -1,7 +1,7 @@ -From c0b8523ca6cb824f184117f05717a6af6b9b3783 Mon Sep 17 00:00:00 2001 -Message-Id: +From 4792bd80c542f7af373bc939492017bd420a3f3b Mon Sep 17 00:00:00 2001 +Message-Id: <4792bd80c542f7af373bc939492017bd420a3f3b@dist-git> From: Laine Stump -Date: Tue, 11 May 2021 15:48:04 -0400 +Date: Wed, 14 Apr 2021 23:25:33 -0400 Subject: [PATCH] network: make it safe to call networkSetupPrivateChains() multiple times MIME-Version: 1.0 @@ -19,10 +19,10 @@ Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrangé (cherry picked from commit de110f110fb917a31b9f33ad8e4b3c1d3284766a) -https://bugzilla.redhat.com/1958301 -Signed-off-by: Laine Stump -Message-Id: <20210511194805.365503-2-laine@redhat.com> -Reviewed-by: Michal Privoznik +https://bugzilla.redhat.com/1942805 + +Message-Id: <20210415032534.723202-2-laine@redhat.com> +Reviewed-by: Pavel Hrdina --- src/network/bridge_driver_linux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch b/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch new file mode 100644 index 0000000..f780cd6 --- /dev/null +++ b/SOURCES/libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch @@ -0,0 +1,248 @@ +From d1c5d166a891a2abf408a5879b95bded23b45825 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 May 2021 14:16:12 +0200 +Subject: [PATCH] qemu: implement support for firmware auto-selection feature + filtering + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit c91fa273062ec388385bf8cc081117c78c2f7af5) + +Conflicts: + tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args + - missing upstream commits: + d96fb5cb31b870e1539bd8ee95fb27dbe461a357 + 43c9c0859f2d53321ccc646ab905beec0740490b + 88957116c9d3cb4705380c3702c9d4315fb500bb + + tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml + - missing upstream commits: + e88367095f3cad2cf80a687fd599dfaeb3073841 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1929357 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_firmware.c | 40 +++++++++++++++ + ...re-efi-no-enrolled-keys.x86_64-latest.args | 47 ++++++++++++++++++ + .../os-firmware-efi-no-enrolled-keys.xml | 49 +++++++++++++++++++ + tests/qemuxml2argvtest.c | 1 + + ...are-efi-no-enrolled-keys.x86_64-latest.xml | 1 + + tests/qemuxml2xmltest.c | 1 + + 6 files changed, 139 insertions(+) + create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args + create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml + create mode 120000 tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index 8ef515ca57..e875e355c7 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -952,6 +952,10 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + bool supportsS4 = false; + bool requiresSMM = false; + bool supportsSEV = false; ++ bool supportsSecureBoot = false; ++ bool hasEnrolledKeys = false; ++ int reqSecureBoot; ++ int reqEnrolledKeys; + + want = qemuFirmwareOSInterfaceTypeFromOsDefFirmware(def->os.firmware); + +@@ -1001,7 +1005,13 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + break; + + case QEMU_FIRMWARE_FEATURE_SECURE_BOOT: ++ supportsSecureBoot = true; ++ break; ++ + case QEMU_FIRMWARE_FEATURE_ENROLLED_KEYS: ++ hasEnrolledKeys = true; ++ break; ++ + case QEMU_FIRMWARE_FEATURE_VERBOSE_DYNAMIC: + case QEMU_FIRMWARE_FEATURE_VERBOSE_STATIC: + case QEMU_FIRMWARE_FEATURE_NONE: +@@ -1022,6 +1032,36 @@ qemuFirmwareMatchDomain(const virDomainDef *def, + return false; + } + ++ if (def->os.firmwareFeatures) { ++ reqSecureBoot = def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT]; ++ if (reqSecureBoot != VIR_TRISTATE_BOOL_ABSENT) { ++ if (reqSecureBoot == VIR_TRISTATE_BOOL_YES && !supportsSecureBoot) { ++ VIR_DEBUG("User requested Secure Boot, firmware '%s' doesn't support it", ++ path); ++ return false; ++ } ++ ++ if (reqSecureBoot == VIR_TRISTATE_BOOL_NO && supportsSecureBoot) { ++ VIR_DEBUG("User refused Secure Boot, firmware '%s' supports it", path); ++ return false; ++ } ++ } ++ ++ reqEnrolledKeys = def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS]; ++ if (reqEnrolledKeys != VIR_TRISTATE_BOOL_ABSENT) { ++ if (reqEnrolledKeys == VIR_TRISTATE_BOOL_YES && !hasEnrolledKeys) { ++ VIR_DEBUG("User requested Enrolled keys, firmware '%s' doesn't have them", ++ path); ++ return false; ++ } ++ ++ if (reqEnrolledKeys == VIR_TRISTATE_BOOL_NO && hasEnrolledKeys) { ++ VIR_DEBUG("User refused Enrolled keys, firmware '%s' has them", path); ++ return false; ++ } ++ } ++ } ++ + if (def->os.loader && + def->os.loader->secure == VIR_TRISTATE_BOOL_YES && + !requiresSMM) { +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args +new file mode 100644 +index 0000000000..c3c838fb1a +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.args +@@ -0,0 +1,47 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-fedora \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-fedora/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-fedora/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-fedora/.config \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-x86_64 \ ++-name guest=fedora,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-fedora/master-key.aes \ ++-blockdev '{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd",\ ++"node-name":"libvirt-pflash0-storage","auto-read-only":true,\ ++"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,\ ++"driver":"raw","file":"libvirt-pflash0-storage"}' \ ++-blockdev '{"driver":"file",\ ++"filename":"/var/lib/libvirt/qemu/nvram/fedora_VARS.fd",\ ++"node-name":"libvirt-pflash1-storage","auto-read-only":true,\ ++"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,\ ++"driver":"raw","file":"libvirt-pflash1-storage"}' \ ++-machine pc-q35-4.0,accel=kvm,usb=off,dump-guest-core=off,\ ++pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \ ++-cpu qemu64 \ ++-m 8 \ ++-overcommit mem-lock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\ ++addr=0x1 \ ++-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ ++-device qemu-xhci,id=usb,bus=pci.1,addr=0x0 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +new file mode 100644 +index 0000000000..7f8f57a859 +--- /dev/null ++++ b/tests/qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +@@ -0,0 +1,49 @@ ++ ++ fedora ++ 63840878-0deb-4095-97e6-fc444d9bc9fa ++ 8192 ++ 8192 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++ ++
++ ++ ++
++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index bc04bea692..5e16d7fd31 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -3094,6 +3094,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-invalid-type"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); + +diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml +new file mode 120000 +index 0000000000..902ccb783b +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/os-firmware-efi-no-enrolled-keys.x86_64-latest.xml +@@ -0,0 +1 @@ ++../qemuxml2argvdata/os-firmware-efi-no-enrolled-keys.xml +\ No newline at end of file +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 461b5bc68f..9e5747290a 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1122,6 +1122,7 @@ mymain(void) + DO_TEST_CAPS_LATEST("os-firmware-bios"); + DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); ++ DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); + + DO_TEST("aarch64-aavmf-virtio-mmio", + QEMU_CAPS_DEVICE_VIRTIO_MMIO, +-- +2.31.1 + diff --git a/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch b/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch new file mode 100644 index 0000000..6cab919 --- /dev/null +++ b/SOURCES/libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch @@ -0,0 +1,68 @@ +From c8ede44db2e94444e5a8ee38e21eda2b42717879 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Tue, 18 May 2021 15:03:02 +0200 +Subject: [PATCH] qemu_firmware: don't error out for unknown firmware features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When QEMU introduces new firmware features libvirt will fail until we +list that feature in our code as well which doesn't sound right. + +We should simply ignore the new feature until we add a proper support +for it. + +Reported-by: Laszlo Ersek +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 61d95a1073833ec4323c1ef28e71e913c55aa7b9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1961562 + +Signed-off-by: Pavel Hrdina +Message-Id: <8989d70d49d8a720532a8c25e3e73d9b3bf2a495.1621342722.git.phrdina@redhat.com> +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_firmware.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index c84d03f0a8..8ef515ca57 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -570,6 +570,7 @@ qemuFirmwareFeatureParse(const char *path, + virJSONValuePtr featuresJSON; + g_autoptr(qemuFirmwareFeature) features = NULL; + size_t nfeatures; ++ size_t nparsed = 0; + size_t i; + + if (!(featuresJSON = virJSONValueObjectGetArray(doc, "features"))) { +@@ -590,17 +591,16 @@ qemuFirmwareFeatureParse(const char *path, + int tmp; + + if ((tmp = qemuFirmwareFeatureTypeFromString(tmpStr)) <= 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("unknown feature %s"), +- tmpStr); +- return -1; ++ VIR_DEBUG("ignoring unknown QEMU firmware feature '%s'", tmpStr); ++ continue; + } + +- features[i] = tmp; ++ features[nparsed] = tmp; ++ nparsed++; + } + + fw->features = g_steal_pointer(&features); +- fw->nfeatures = nfeatures; ++ fw->nfeatures = nparsed; + return 0; + } + +-- +2.31.1 + diff --git a/SOURCES/libvirt-security-fix-SELinux-label-generation-logic.patch b/SOURCES/libvirt-security-fix-SELinux-label-generation-logic.patch new file mode 100644 index 0000000..d32275b --- /dev/null +++ b/SOURCES/libvirt-security-fix-SELinux-label-generation-logic.patch @@ -0,0 +1,58 @@ +From 0f7c8a271f07b3f9aff07dd814d7bec80ddac362 Mon Sep 17 00:00:00 2001 +Message-Id: <0f7c8a271f07b3f9aff07dd814d7bec80ddac362@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 28 Jul 2021 14:59:00 +0200 +Subject: [PATCH] security: fix SELinux label generation logic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A process can access a file if the set of MCS categories +for the file is equal-to *or* a subset-of, the set of +MCS categories for the process. + +If there are two VMs: + + a) svirt_t:s0:c117 + b) svirt_t:s0:c117,c720 + +Then VM (b) is able to access files labelled for VM (a). + +IOW, we must discard case where the categories are equal +because that is a subset of many other valid category pairs. + +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/153 +CVE-2021-3631 +Reviewed-by: Peter Krempa +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 15073504dbb624d3f6c911e85557019d3620fdb2) +Message-Id: <38c6a7b570b8eb2114d9f1ff0c84a8346e01472f.1627476632.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + src/security/security_selinux.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 985c7eda1a..93fae831ca 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -391,7 +391,15 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr, + VIR_DEBUG("Try cat %s:c%d,c%d", sens, c1 + catMin, c2 + catMin); + + if (c1 == c2) { +- mcs = g_strdup_printf("%s:c%d", sens, catMin + c1); ++ /* ++ * A process can access a file if the set of MCS categories ++ * for the file is equal-to *or* a subset-of, the set of ++ * MCS categories for the process. ++ * ++ * IOW, we must discard case where the categories are equal ++ * because that is a subset of other category pairs. ++ */ ++ continue; + } else { + if (c1 > c2) { + int t = c1; +-- +2.32.0 + diff --git a/SOURCES/libvirt-storage_driver-Unlock-object-on-ACL-fail-in-storagePoolLookupByTargetPath.patch b/SOURCES/libvirt-storage_driver-Unlock-object-on-ACL-fail-in-storagePoolLookupByTargetPath.patch new file mode 100644 index 0000000..370de09 --- /dev/null +++ b/SOURCES/libvirt-storage_driver-Unlock-object-on-ACL-fail-in-storagePoolLookupByTargetPath.patch @@ -0,0 +1,44 @@ +From b794a0e4e657defe9a491eb20adf61eafa443ca3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Wed, 28 Jul 2021 14:59:01 +0200 +Subject: [PATCH] storage_driver: Unlock object on ACL fail in + storagePoolLookupByTargetPath +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +'virStoragePoolObjListSearch' returns a locked and refed object, thus we +must release it on ACL permission failure. + +Fixes: 7aa0e8c0cb8 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1984318 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 447f69dec47e1b0bd15ecd7cd49a9fd3b050fb87) +CVE-2021-3667 +Message-Id: +Reviewed-by: Ján Tomko +--- + src/storage/storage_driver.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c +index 0bb116cf08..4f0b8c1218 100644 +--- a/src/storage/storage_driver.c ++++ b/src/storage/storage_driver.c +@@ -1733,8 +1733,10 @@ storagePoolLookupByTargetPath(virConnectPtr conn, + storagePoolLookupByTargetPathCallback, + cleanpath))) { + def = virStoragePoolObjGetDef(obj); +- if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0) ++ if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0) { ++ virStoragePoolObjEndAPI(&obj); + return NULL; ++ } + + pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); + virStoragePoolObjEndAPI(&obj); +-- +2.32.0 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 870164e..d49212a 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -219,7 +219,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.0.0 -Release: 35.1%{?dist}%{?extra_release} +Release: 37%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -756,6 +756,22 @@ Patch524: libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch Patch525: libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch Patch526: libvirt-network-make-it-safe-to-call-networkSetupPrivateChains-multiple-times.patch Patch527: libvirt-network-force-re-creation-of-iptables-private-chains-on-firewalld-restart.patch +Patch528: libvirt-hostdev-Update-mdev-pointer-reference-after-checking-device-type.patch +Patch529: libvirt-hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-mdev-struct.patch +Patch530: libvirt-qemu_firmware-don-t-error-out-for-unknown-firmware-features.patch +Patch531: libvirt-docs-improve-description-of-secure-attribute-for-loader-element.patch +Patch532: libvirt-conf-introduce-virDomainDefParseBootInitOptions.patch +Patch533: libvirt-conf-introduce-virDomainDefParseBootKernelOptions.patch +Patch534: libvirt-conf-introduce-virDomainDefParseBootFirmwareOptions.patch +Patch535: libvirt-conf-introduce-virDomainDefParseBootLoaderOptions.patch +Patch536: libvirt-conf-introduce-virDomainDefParseBootAcpiOptions.patch +Patch537: libvirt-conf-use-switch-in-virDomainDefParseBootOptions.patch +Patch538: libvirt-conf-introduce-support-for-firmware-auto-selection-feature-filtering.patch +Patch539: libvirt-qemu-implement-support-for-firmware-auto-selection-feature-filtering.patch +Patch540: libvirt-domain_conf-Don-t-leak-def-os.firmwareFeatures.patch +Patch541: libvirt-conf-remove-duplicated-firmware-type-attribute.patch +Patch542: libvirt-security-fix-SELinux-label-generation-logic.patch +Patch543: libvirt-storage_driver-Unlock-object-on-ACL-fail-in-storagePoolLookupByTargetPath.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2532,9 +2548,27 @@ exit 0 %changelog -* Thu Jun 3 2021 Jiri Denemark - 6.0.0-35.1.el8 -- network: make it safe to call networkSetupPrivateChains() multiple times (rhbz#1958301) -- network: force re-creation of iptables private chains on firewalld restart (rhbz#1958301) +* Fri Aug 6 2021 Jiri Denemark - 6.0.0-37 +- security: fix SELinux label generation logic (CVE-2021-3631) +- storage_driver: Unlock object on ACL fail in storagePoolLookupByTargetPath (CVE-2021-3667) + +* Tue Jun 1 2021 Jiri Denemark - 6.0.0-36 +- network: make it safe to call networkSetupPrivateChains() multiple times (rhbz#1942805) +- network: force re-creation of iptables private chains on firewalld restart (rhbz#1942805) +- hostdev: Update mdev pointer reference after checking device type (rhbz#1940449) +- hostdev: mdev: Lookup mdevs by sysfs path rather than mdev struct (rhbz#1940449) +- qemu_firmware: don't error out for unknown firmware features (rhbz#1961562) +- docs: improve description of secure attribute for loader element (rhbz#1929357) +- conf: introduce virDomainDefParseBootInitOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootKernelOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootFirmwareOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootLoaderOptions (rhbz#1929357) +- conf: introduce virDomainDefParseBootAcpiOptions (rhbz#1929357) +- conf: use switch in virDomainDefParseBootOptions (rhbz#1929357) +- conf: introduce support for firmware auto-selection feature filtering (rhbz#1929357) +- qemu: implement support for firmware auto-selection feature filtering (rhbz#1929357) +- domain_conf: Don't leak def->os.firmwareFeatures (rhbz#1929357) +- conf: remove duplicated firmware type attribute (rhbz#1929357) * Thu Mar 4 2021 Jiri Denemark - 6.0.0-35 - vircgroupv2: properly detect placement of running VM (rhbz#1798463)