diff --git a/Don-t-call-qsort-over-NULL.patch b/Don-t-call-qsort-over-NULL.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e866a207d51fc316f522cfaabf099d597698a19 --- /dev/null +++ b/Don-t-call-qsort-over-NULL.patch @@ -0,0 +1,68 @@ +From bfcbf70e99b9fb06468de8135d3a251ef22e0cd3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 14 Jun 2021 12:46:02 +0200 +Subject: [PATCH 094/108] Don't call qsort() over NULL + +In a few places it may happen that the array we want to sort is +still NULL (e.g. because there were no leases found, no paths for +secdriver to lock or no cache banks). However, passing NULL to +qsort() is undefined and even though glibc plays nicely we +shouldn't rely on undefined behaviour. + +Signed-off-by: Michal Privoznik +Reviewed-by: Tim Wiederhake +(cherry picked from commit 1ab5a37c4a70434a1dacebbdababb91baaa29ef1) +--- + src/conf/capabilities.c | 6 ++++-- + src/security/security_manager.c | 3 ++- + tools/nss/libvirt_nss.c | 3 ++- + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index d6ec1f12f4..deb99cecd3 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -1982,8 +1982,10 @@ virCapabilitiesInitCaches(virCapsPtr caps) + /* Sort the array in order for the tests to be predictable. This way we can + * still traverse the directory instead of guessing names (in case there is + * 'index1' and 'index3' but no 'index2'). */ +- qsort(caps->host.cache.banks, caps->host.cache.nbanks, +- sizeof(*caps->host.cache.banks), virCapsHostCacheBankSorter); ++ if (caps->host.cache.banks) { ++ qsort(caps->host.cache.banks, caps->host.cache.nbanks, ++ sizeof(*caps->host.cache.banks), virCapsHostCacheBankSorter); ++ } + + if (virCapabilitiesInitResctrlMemory(caps) < 0) + goto cleanup; +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index 9d5dfec12b..a74b663685 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -1302,7 +1302,8 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED, + * paths in the same order and thus no deadlock can occur. + * Lastly, it makes searching for duplicate paths below + * simpler. */ +- qsort(paths, npaths, sizeof(*paths), cmpstringp); ++ if (paths) ++ qsort(paths, npaths, sizeof(*paths), cmpstringp); + + for (i = 0; i < npaths; i++) { + const char *p = paths[i]; +diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c +index 3b89f72742..265ef236cc 100644 +--- a/tools/nss/libvirt_nss.c ++++ b/tools/nss/libvirt_nss.c +@@ -69,7 +69,8 @@ static void + sortAddr(leaseAddress *tmpAddress, + size_t ntmpAddress) + { +- qsort(tmpAddress, ntmpAddress, sizeof(*tmpAddress), leaseAddressSorter); ++ if (tmpAddress) ++ qsort(tmpAddress, ntmpAddress, sizeof(*tmpAddress), leaseAddressSorter); + } + + +-- +2.33.0 + diff --git a/check-for-NULL-before-calling-g_regex_unref.patch b/check-for-NULL-before-calling-g_regex_unref.patch new file mode 100644 index 0000000000000000000000000000000000000000..bbb2212a8ff4714c859ee046ca6ad6ea931b4db0 --- /dev/null +++ b/check-for-NULL-before-calling-g_regex_unref.patch @@ -0,0 +1,70 @@ +From 61de276ed3cd5692b99ebc6d5b700a21b16ab5e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 8 Sep 2020 14:57:14 +0200 +Subject: [PATCH 014/108] check for NULL before calling g_regex_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +g_regex_unref reports an error if called with a NULL argument. + +We have two cases in the code where we (possibly) call it on a NULL +argument. The interesting one is in virDomainQemuMonitorEventCleanup. + +Based on VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX, we unref +data->regex, which has two problems: + +* On the client side, flags is -1 so the comparison is true even if no + regex was used, reproducible by: + $ virsh qemu-monitor-event --timeout 1 + which results in an ugly error: +(process:1289846): GLib-CRITICAL **: 14:58:42.631: g_regex_unref: assertion 'regex != NULL' failed +* On the server side, we only create the regex if both the flag and the + string are present, so it's possible to trigger this message by: + $ virsh qemu-monitor-event --regex --timeout 1 + +Use a non-NULL comparison instead of the flag to decide whether we need +to unref the regex. And add a non-NULL check to the unref in the +VirtualBox test too. + +Signed-off-by: Ján Tomko +Fixes: 71efb59a4de7c51b1bc889a316f1796ebf55738f +https://bugzilla.redhat.com/show_bug.cgi?id=1876907 +Reviewed-by: Peter Krempa +Reviewed-by: Martin Kletzander +(cherry picked from commit 92b252456ee6d6ffc6e39e62ce1ce6c50113e00e) +--- + src/conf/domain_event.c | 2 +- + tests/vboxsnapshotxmltest.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c +index 33fbf10406..d3acde0236 100644 +--- a/src/conf/domain_event.c ++++ b/src/conf/domain_event.c +@@ -2194,7 +2194,7 @@ virDomainQemuMonitorEventCleanup(void *opaque) + virDomainQemuMonitorEventData *data = opaque; + + VIR_FREE(data->event); +- if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX) ++ if (data->regex) + g_regex_unref(data->regex); + if (data->freecb) + (data->freecb)(data->opaque); +diff --git a/tests/vboxsnapshotxmltest.c b/tests/vboxsnapshotxmltest.c +index 2ea460d8bd..853d930865 100644 +--- a/tests/vboxsnapshotxmltest.c ++++ b/tests/vboxsnapshotxmltest.c +@@ -136,7 +136,8 @@ mymain(void) + DO_TEST("2disks-3snap-brother"); + + cleanup: +- g_regex_unref(testSnapshotXMLVariableLineRegex); ++ if (testSnapshotXMLVariableLineRegex) ++ g_regex_unref(testSnapshotXMLVariableLineRegex); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + +-- +2.33.0 + diff --git a/cmdCheckpointList-Fix-memory-leak.patch b/cmdCheckpointList-Fix-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..89bae2606b58071c557a1fa79e65d0d5493fb135 --- /dev/null +++ b/cmdCheckpointList-Fix-memory-leak.patch @@ -0,0 +1,36 @@ +From dd54dd905f334ee31ebd9d667dc0fd2db9ddeaf0 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 19 Apr 2021 13:54:13 +0200 +Subject: [PATCH 061/108] cmdCheckpointList: Fix memory leak + +Fixes: 3caa28dc50df7ec215713075d669b20bef6473a2 +Signed-off-by: Tim Wiederhake +Reviewed-by: Laine Stump +(cherry picked from commit 8b8c91f487592c6c067847ca59dde405ca17573f) +--- + tools/virsh-checkpoint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-checkpoint.c b/tools/virsh-checkpoint.c +index e82a67f075..1a3a74b2d5 100644 +--- a/tools/virsh-checkpoint.c ++++ b/tools/virsh-checkpoint.c +@@ -720,7 +720,6 @@ cmdCheckpointList(vshControl *ctl, + virDomainCheckpointPtr checkpoint = NULL; + long long creation_longlong; + g_autoptr(GDateTime) then = NULL; +- g_autofree gchar *thenstr = NULL; + bool tree = vshCommandOptBool(cmd, "tree"); + bool name = vshCommandOptBool(cmd, "name"); + bool from = vshCommandOptBool(cmd, "from"); +@@ -803,6 +802,7 @@ cmdCheckpointList(vshControl *ctl, + } + + for (i = 0; i < checkpointlist->nchks; i++) { ++ g_autofree gchar *thenstr = NULL; + const char *chk_name; + + /* free up memory from previous iterations of the loop */ +-- +2.33.0 + diff --git a/cmdSnapshotList-Fix-memory-leak.patch b/cmdSnapshotList-Fix-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..05e9f4ee029f986ab6cc2c2b61f01438794ee669 --- /dev/null +++ b/cmdSnapshotList-Fix-memory-leak.patch @@ -0,0 +1,36 @@ +From 4732cb4a9306ea9b8487b66fa14316caa05428ed Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 19 Apr 2021 13:54:14 +0200 +Subject: [PATCH 062/108] cmdSnapshotList: Fix memory leak + +Fixes: 3caa28dc50df7ec215713075d669b20bef6473a2 +Signed-off-by: Tim Wiederhake +Reviewed-by: Laine Stump +(cherry picked from commit 89ce1ef86b0c8b0e039ae770221376497354f085) +--- + tools/virsh-snapshot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c +index d5e68e4b18..376290d468 100644 +--- a/tools/virsh-snapshot.c ++++ b/tools/virsh-snapshot.c +@@ -1493,7 +1493,6 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + char *state = NULL; + long long creation_longlong; + g_autoptr(GDateTime) then = NULL; +- g_autofree gchar *thenstr = NULL; + bool tree = vshCommandOptBool(cmd, "tree"); + bool name = vshCommandOptBool(cmd, "name"); + bool from = vshCommandOptBool(cmd, "from"); +@@ -1588,6 +1587,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + } + + for (i = 0; i < snaplist->nsnaps; i++) { ++ g_autofree gchar *thenstr = NULL; + const char *snap_name; + + /* free up memory from previous iterations of the loop */ +-- +2.33.0 + diff --git a/conf-Use-unsigned-long-long-for-timer-frequency.patch b/conf-Use-unsigned-long-long-for-timer-frequency.patch new file mode 100644 index 0000000000000000000000000000000000000000..635ad7a3c2d195b240167cfe4a92eff410ce6f8e --- /dev/null +++ b/conf-Use-unsigned-long-long-for-timer-frequency.patch @@ -0,0 +1,81 @@ +From efd4f6469f9f5f6d3a34d250cd80faf59a8dc373 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Wed, 11 Nov 2020 16:50:16 +0100 +Subject: [PATCH 068/108] conf: Use unsigned long long for timer frequency + +Although the code in qemuProcessStartValidateTSC works as if the +timer frequency was already unsigned long long (by using an appropriate +temporary variable), the virDomainTimerDef structure actually defines +frequency as unsigned long, which is not guaranteed to be 64b. + +Fixes support for frequencies higher than 2^32 - 1 on 32b systems. + +Signed-off-by: Jiri Denemark +Reviewed-by: Martin Kletzander +(cherry picked from commit 3c7c7cd4d82c2f9a5a59bbd06673b8cd1eb23ce3) +--- + src/conf/domain_conf.c | 6 +++--- + src/conf/domain_conf.h | 2 +- + src/qemu/qemu_command.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index a33f9144f5..9c83f4e347 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -13951,7 +13951,7 @@ virDomainTimerDefParseXML(xmlNodePtr node, + } + } + +- ret = virXPathULong("string(./@frequency)", ctxt, &def->frequency); ++ ret = virXPathULongLong("string(./@frequency)", ctxt, &def->frequency); + if (ret == -1) { + def->frequency = 0; + } else if (ret < 0) { +@@ -22259,7 +22259,7 @@ virDomainTimerDefCheckABIStability(virDomainTimerDefPtr src, + if (src->name == VIR_DOMAIN_TIMER_NAME_TSC) { + if (src->frequency != dst->frequency) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("Target TSC frequency %lu does not match source %lu"), ++ _("Target TSC frequency %llu does not match source %llu"), + dst->frequency, src->frequency); + return false; + } +@@ -27355,7 +27355,7 @@ virDomainTimerDefFormat(virBufferPtr buf, + + if (def->name == VIR_DOMAIN_TIMER_NAME_TSC) { + if (def->frequency > 0) +- virBufferAsprintf(buf, " frequency='%lu'", def->frequency); ++ virBufferAsprintf(buf, " frequency='%llu'", def->frequency); + + if (def->mode != -1) { + const char *mode +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 15b9e79d69..c0a323d465 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2078,7 +2078,7 @@ struct _virDomainTimerDef { + int track; /* host|guest */ + + /* frequency & mode are only valid for name='tsc' */ +- unsigned long frequency; /* in Hz, unspecified = 0 */ ++ unsigned long long frequency; /* in Hz, unspecified = 0 */ + int mode; /* auto|native|emulate|paravirt */ + }; + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 27b2eef8e5..42f6e10b33 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6761,7 +6761,7 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, + break; + case VIR_DOMAIN_TIMER_NAME_TSC: + if (timer->frequency > 0) +- virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency); ++ virBufferAsprintf(&buf, ",tsc-frequency=%llu", timer->frequency); + break; + case VIR_DOMAIN_TIMER_NAME_ARMVTIMER: + switch (timer->tickpolicy) { +-- +2.33.0 + diff --git a/conf-properly-clear-out-autogenerated-macvtap-names-.patch b/conf-properly-clear-out-autogenerated-macvtap-names-.patch new file mode 100644 index 0000000000000000000000000000000000000000..74d94991972e64a6b63d93706e4a2e7b6ba3d570 --- /dev/null +++ b/conf-properly-clear-out-autogenerated-macvtap-names-.patch @@ -0,0 +1,110 @@ +From a5ec03f25b225408a9e7ebbf7b9fc9e3e2f15166 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Sat, 22 Aug 2020 23:42:52 -0400 +Subject: [PATCH 049/108] conf: properly clear out autogenerated macvtap names + when formatting/parsing + +Back when macvtap support was added in commit 315baab9443 in Feb. 2010 +(libvirt-0.7.7), it was setup to autogenerate a name for the device if +one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"), +similar to the way an unspecified standard tap device name will lead +to an autogenerated "vnet%d". + +As a matter of fact, in commit ca1b7cc8e45 added in May 2010, the code +was changed to *always* ignore a supplied device name for macvtap +interfaces by deleting *any* name immediately during the +parsing (this was intended to prevent one domain which had failed to +completely start from deleting the macvtap device of another domain +which had subsequently been provided the same device name (this will +seem mildly ironic later). This was later fixed to only clear the +device name when inactive XML was being parsed. HOWEVER - this was +only done if the xml was - autogenerated +names were not cleared for (which could +also result in a macvtap device). + +Although the names of "vnetX" tap devices had always been +automatically cleared when parsing (see commit d1304583d +from July 2008 (!)), at the time macvtap support was added, both vnetX +and macvtapX device names were always included when formatting the +XML. + +Then in commit a8be259d0cc (July 2011, libvirt-0.9.4), +formatting was changed to also clear out "vnetX" device names during +XML formatting as well. However the same treatment wasn't given to +"macvtapX". + +Now in 2020, there has been a report that a failed migration leads to +the macvtap device of some other unrelated guest on the destination +host losing its network connectivity. It was determined that this was +due to the domain XML in the migration containing a macvtap device +name, e.g. "macvtap0", that was already in use by the other guest on +the destination. Normally this wouldn't be a problem, because libvirt +would see that the device was already in use, and then find a +different unused name. But in this case, other external problems were +causing the migration to fail prior to selecting a macvtap device and +successfully opening it, and during error recovery, qemuProcessStop() +was called, which went through all def->nets objects and (if they were +macvtap) deleted the device specified in net->ifname; since libvirt +hadn't gotten to the point of replacing the incoming "macvtap0" with +the name of a device it actually created for this guest, that meant +that "macvtap0" was deleted, *even though it was currently in use by a +different guest*! + +Whew! + +So, it turns out that when formatting "migratable" XML, "vnetX" +devices are omitted, just as when formatting "inactive" XML. By making +the code in both interface parsing and formatting consistent for +"vnetX", "macvtapX", and "macvlanX", we can thus make sure that the +autogenerated (and unneeded / completely *not* wanted) macvtap device +name will not be sent with the migration XML. This way when a +migration fails, net->ifname will be NULL, and libvirt won't have any +device to try and (erroneously) delete. + +Signed-off-by: Laine Stump +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994) +--- + src/conf/domain_conf.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 54228a2151..d3565ececf 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -12357,14 +12357,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + } + + def->data.direct.linkdev = g_steal_pointer(&dev); +- +- if (ifname && +- flags & VIR_DOMAIN_DEF_PARSE_INACTIVE && +- (STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || +- STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) { +- VIR_FREE(ifname); +- } +- + break; + + case VIR_DOMAIN_NET_TYPE_HOSTDEV: +@@ -12410,6 +12402,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + if (def->managed_tap != VIR_TRISTATE_BOOL_NO && ifname && + (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && + (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(ifname, prefix)))) { + /* An auto-generated target name, blank it out */ + VIR_FREE(ifname); +@@ -26263,6 +26257,8 @@ virDomainNetDefFormat(virBufferPtr buf, + (def->managed_tap == VIR_TRISTATE_BOOL_NO || + !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) && + (STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(def->ifname, prefix)))))) { + /* Skip auto-generated target names for inactive config. */ + virBufferEscapeString(&attrBuf, " dev='%s'", def->ifname); +-- +2.33.0 + diff --git a/cpu_map-Fix-Icelake-Server-model-number.patch b/cpu_map-Fix-Icelake-Server-model-number.patch new file mode 100644 index 0000000000000000000000000000000000000000..0261661c3459f6750598e8b6e95c4e75f1822926 --- /dev/null +++ b/cpu_map-Fix-Icelake-Server-model-number.patch @@ -0,0 +1,45 @@ +From a70f3b2d8b707063c63fb3b43751651e5fedebb9 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Wed, 2 Dec 2020 11:38:22 +0100 +Subject: [PATCH 012/108] cpu_map: Fix Icelake Server model number + +See arch/x86/include/asm/intel-family.h in the Kernel: + #define INTEL_FAM6_ICELAKE_X 0x6A + +Signed-off-by: Tim Wiederhake +Reviewed-by: Jiri Denemark +(cherry picked from commit 1278ac6265589cd83cc2e661056c860e98105507) +--- + src/cpu_map/x86_Icelake-Server-noTSX.xml | 2 +- + src/cpu_map/x86_Icelake-Server.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu_map/x86_Icelake-Server-noTSX.xml b/src/cpu_map/x86_Icelake-Server-noTSX.xml +index 2fd6906406..34a0f7c18c 100644 +--- a/src/cpu_map/x86_Icelake-Server-noTSX.xml ++++ b/src/cpu_map/x86_Icelake-Server-noTSX.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +diff --git a/src/cpu_map/x86_Icelake-Server.xml b/src/cpu_map/x86_Icelake-Server.xml +index 367ade7240..1ee4ea9cd4 100644 +--- a/src/cpu_map/x86_Icelake-Server.xml ++++ b/src/cpu_map/x86_Icelake-Server.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +-- +2.33.0 + diff --git a/disk-storage-fix-allocation-size-for-pool-format-dos.patch b/disk-storage-fix-allocation-size-for-pool-format-dos.patch new file mode 100644 index 0000000000000000000000000000000000000000..061ba4fd1f83fe10d80ce84412829831f10e7903 --- /dev/null +++ b/disk-storage-fix-allocation-size-for-pool-format-dos.patch @@ -0,0 +1,42 @@ +From 9e4751b3a9c0435c4cb199c353144acb55458473 Mon Sep 17 00:00:00 2001 +From: Sebastian Mitterle +Date: Sat, 29 Aug 2020 00:49:07 +0000 +Subject: [PATCH 027/108] disk storage: fix allocation size for pool format dos + +The changed condition was always false because the function was always +called with boundary values 0. + +Use the free extent's start value to get its start offset from the +cylinder boundary and determine if the needed size for allocation +needs to be expanded too in case the offset doesn't fit within extra +bytes for alignment. + +This fixes an issue where vol-create-from will call qemu-img convert +to create a destination volume of same capacity as the source volume +and qemu-img will error 'Cannot grow device files' due to the partition +being too small for the source although both destination partition and +source volume have the same capacity. + +Signed-off-by: Sebastian Mitterle +Reviewed-by: Michal Privoznik +(cherry picked from commit 653fdf48e352814efdbff72aa5421f65385088ac) +--- + src/storage/storage_backend_disk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c +index eae23ec24a..da06357b90 100644 +--- a/src/storage/storage_backend_disk.c ++++ b/src/storage/storage_backend_disk.c +@@ -691,7 +691,7 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObjPtr pool, + if (def->source.format == VIR_STORAGE_POOL_DISK_DOS) { + /* align to cylinder boundary */ + neededSize += extraBytes; +- if ((*start % cylinderSize) > extraBytes) { ++ if ((dev->freeExtents[i].start % cylinderSize) > extraBytes) { + /* add an extra cylinder if the offset can't fit within + the extra bytes we have */ + neededSize += cylinderSize; +-- +2.33.0 + diff --git a/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch b/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..db0eadb4379d4681fc3dd7a997b25f8544077e39 --- /dev/null +++ b/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch @@ -0,0 +1,121 @@ +From 11073a79e7c7275436a43a43dd6b6e772b05588f Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 18 Nov 2020 11:58:01 +0100 +Subject: [PATCH 066/108] domain_capabilities: Assert enums fit into unsigned + int bitmask + +The way our domain capabilities work currently, is that we have +virDomainCapsEnum struct which contains 'unsigned int values' +member which serves as a bitmask. More complicated structs are +composed from this struct, giving us whole virDomainCaps +eventually. + +Whenever we want to report that a certain value is supported, the +'1 << value' bit is set in the corresponding unsigned int member. +This works as long as the resulting value after bitshift does not +overflow unsigned int. There is a check inside +virDomainCapsEnumSet() which ensures exactly this, but no caller +really checks whether virDomainCapsEnumSet() succeeded. Also, +checking at runtime is a bit too late. + +Fortunately, we know the largest value we want to store in each +member, because each enum of ours ends with _LAST member. +Therefore, we can check at build time whether an overflow can +occur. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 912421e7b63a358d552b79fac62a5518ec58f4e5) +--- + src/conf/domain_capabilities.h | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index 9f4a23d015..0345c84855 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -36,6 +36,9 @@ struct _virDomainCapsEnum { + unsigned int values; /* Bitmask of values supported in the corresponding enum */ + }; + ++#define STATIC_ASSERT_ENUM(last) \ ++ G_STATIC_ASSERT(last <= sizeof(unsigned int) * CHAR_BIT) ++ + typedef struct _virDomainCapsStringValues virDomainCapsStringValues; + typedef virDomainCapsStringValues *virDomainCapsStringValuesPtr; + struct _virDomainCapsStringValues { +@@ -43,6 +46,8 @@ struct _virDomainCapsStringValues { + size_t nvalues; /* number of strings */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_LOADER_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_TRISTATE_BOOL_LAST); + typedef struct _virDomainCapsLoader virDomainCapsLoader; + typedef virDomainCapsLoader *virDomainCapsLoaderPtr; + struct _virDomainCapsLoader { +@@ -53,6 +58,7 @@ struct _virDomainCapsLoader { + virDomainCapsEnum secure; /* Info about secure:virTristateBool */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_OS_DEF_FIRMWARE_LAST); + typedef struct _virDomainCapsOS virDomainCapsOS; + typedef virDomainCapsOS *virDomainCapsOSPtr; + struct _virDomainCapsOS { +@@ -61,6 +67,9 @@ struct _virDomainCapsOS { + virDomainCapsLoader loader; /* Info about virDomainLoaderDef */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_DEVICE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_BUS_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_MODEL_LAST); + typedef struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk; + typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr; + struct _virDomainCapsDeviceDisk { +@@ -71,6 +80,7 @@ struct _virDomainCapsDeviceDisk { + /* add new fields here */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_GRAPHICS_TYPE_LAST); + typedef struct _virDomainCapsDeviceGraphics virDomainCapsDeviceGraphics; + typedef virDomainCapsDeviceGraphics *virDomainCapsDeviceGraphicsPtr; + struct _virDomainCapsDeviceGraphics { +@@ -78,6 +88,7 @@ struct _virDomainCapsDeviceGraphics { + virDomainCapsEnum type; /* virDomainGraphicsType */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_VIDEO_TYPE_LAST); + typedef struct _virDomainCapsDeviceVideo virDomainCapsDeviceVideo; + typedef virDomainCapsDeviceVideo *virDomainCapsDeviceVideoPtr; + struct _virDomainCapsDeviceVideo { +@@ -85,6 +96,11 @@ struct _virDomainCapsDeviceVideo { + virDomainCapsEnum modelType; /* virDomainVideoType */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_MODE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_STARTUP_POLICY_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST); + typedef struct _virDomainCapsDeviceHostdev virDomainCapsDeviceHostdev; + typedef virDomainCapsDeviceHostdev *virDomainCapsDeviceHostdevPtr; + struct _virDomainCapsDeviceHostdev { +@@ -97,6 +113,8 @@ struct _virDomainCapsDeviceHostdev { + /* add new fields here */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_RNG_MODEL_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_RNG_BACKEND_LAST); + typedef struct _virDomainCapsDeviceRNG virDomainCapsDeviceRNG; + typedef virDomainCapsDeviceRNG *virDomainCapsDeviceRNGPtr; + struct _virDomainCapsDeviceRNG { +@@ -105,6 +123,7 @@ struct _virDomainCapsDeviceRNG { + virDomainCapsEnum backendModel; /* virDomainRNGBackend */ + }; + ++STATIC_ASSERT_ENUM(VIR_GIC_VERSION_LAST); + typedef struct _virDomainCapsFeatureGIC virDomainCapsFeatureGIC; + typedef virDomainCapsFeatureGIC *virDomainCapsFeatureGICPtr; + struct _virDomainCapsFeatureGIC { +-- +2.33.0 + diff --git a/domain_cgroup.c-update-domain-after-setting-blkio.we.patch b/domain_cgroup.c-update-domain-after-setting-blkio.we.patch new file mode 100644 index 0000000000000000000000000000000000000000..c7e8c4d3a4a5a108b0ec9343e159dbb5dcea01bd --- /dev/null +++ b/domain_cgroup.c-update-domain-after-setting-blkio.we.patch @@ -0,0 +1,48 @@ +From da99b4e69fab6a14f55873a0b27f962ed6ed5f11 Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Mon, 22 Mar 2021 16:28:59 -0300 +Subject: [PATCH 091/108] domain_cgroup.c: update domain after setting + blkio.weight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit ac87d3520ad5 consolidated common cgroup code between the QEMU and +lxc drivers in domain_cgroup.c. In this process, in +virDomainCgroupSetupDomainBlkioParameters(), a call to +virCgroupGetBlkioWeight() went missing. + +The result is that 'virsh blkiotune' is setting the blkio.weight for the +guest in the host cgroup, but not on the domain XML, because +virCgroupGetBlkioWeight() is also used to write the blkio.weight value +in the domain object. + +Fix it by adding the virCgroupGetBlkioWeight() call in the +virDomainCgroupSetupDomainBlkioParameters() helper. + +Fixes: ac87d3520ad542d558854a72b0ae0a81fddc6747 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1941407 +Reviewed-by: Ján Tomko +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit e2602f2bb186da100116a5668d95ca829b7f2767) +--- + src/hypervisor/domain_cgroup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c +index eb4fa20a9e..05e3aa7e6a 100644 +--- a/src/hypervisor/domain_cgroup.c ++++ b/src/hypervisor/domain_cgroup.c +@@ -104,7 +104,8 @@ virDomainCgroupSetupDomainBlkioParameters(virCgroupPtr cgroup, + virTypedParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { +- if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0) ++ if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0 || ++ virCgroupGetBlkioWeight(cgroup, &def->blkio.weight) < 0) + ret = -1; + } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) || + STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) || +-- +2.33.0 + diff --git a/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch b/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch new file mode 100644 index 0000000000000000000000000000000000000000..8806010b31d6ad9da25f7d173c10072c02d0b32f --- /dev/null +++ b/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch @@ -0,0 +1,40 @@ +From 5862d4429c3c3b813b46c32830800df34c6dafe0 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Wed, 11 Mar 2020 13:25:59 +0100 +Subject: [PATCH 074/108] domain_conf: fix NULL dereference on error in + virDomainObjCopyPersistentDef + +The issue was introduced together with the function itself by commit +. Calling +`virDomainObjGetPersistentDef` may return NULL which is later passed +to `virDomainDefFormat` where the `def` attribute is marked as NONNULL +and later in `virDomainDefFormatInternalSetRootName` it is actually +defererenced without any other check. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit b96174d9f2dcf0197bb6e58eea3fbbda17043478) +--- + src/conf/domain_conf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9c83f4e347..b60b9d31a1 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -30074,6 +30074,12 @@ virDomainObjCopyPersistentDef(virDomainObjPtr dom, + virDomainDefPtr cur; + + cur = virDomainObjGetPersistentDef(xmlopt, dom, parseOpaque); ++ if (!cur) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to get persistent definition object")); ++ return NULL; ++ } ++ + return virDomainDefCopy(cur, xmlopt, parseOpaque, false); + } + +-- +2.33.0 + diff --git a/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch b/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch new file mode 100644 index 0000000000000000000000000000000000000000..084a3f74aad798dad60275c2b890e474f3412c5f --- /dev/null +++ b/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch @@ -0,0 +1,65 @@ +From fbb537ad89c6820e8763a57722cebc5a3db363e0 Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Thu, 19 Nov 2020 13:57:43 -0300 +Subject: [PATCH 067/108] domain_conf.c: do not leak 'video' in + virDomainDefParseXML() + +The 'video' pointer is only being freed on error path, meaning +that we're leaking it after each loop restart. + +There are more opportunities for auto cleanups of virDomainVideoDef +pointers, so let's register AUTOPTR_CLEANUP_FUNC for it to use +g_autoptr() later on. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit 18d29844c616fb633f7042dbe4cf80819cdd2f1d) +--- + src/conf/domain_conf.c | 4 +--- + src/conf/domain_conf.h | 1 + + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index d3565ececf..a33f9144f5 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -21631,7 +21631,7 @@ virDomainDefParseXML(xmlDocPtr xml, + if (n && VIR_ALLOC_N(def->videos, n) < 0) + goto error; + for (i = 0; i < n; i++) { +- virDomainVideoDefPtr video; ++ g_autoptr(virDomainVideoDef) video = NULL; + ssize_t insertAt = -1; + + if (!(video = virDomainVideoDefParseXML(xmlopt, nodes[i], +@@ -21640,7 +21640,6 @@ virDomainDefParseXML(xmlDocPtr xml, + + if (video->primary) { + if (def->nvideos != 0 && def->videos[0]->primary) { +- virDomainVideoDefFree(video); + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only one primary video device is supported")); + goto error; +@@ -21652,7 +21651,6 @@ virDomainDefParseXML(xmlDocPtr xml, + insertAt, + def->nvideos, + video) < 0) { +- virDomainVideoDefFree(video); + goto error; + } + } +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index e057c384c6..15b9e79d69 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2938,6 +2938,7 @@ void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def); + void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); + virDomainVideoDefPtr virDomainVideoDefNew(virDomainXMLOptionPtr xmlopt); + void virDomainVideoDefFree(virDomainVideoDefPtr def); ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree); + void virDomainVideoDefClear(virDomainVideoDefPtr def); + virDomainHostdevDefPtr virDomainHostdevDefNew(void); + void virDomainHostdevDefClear(virDomainHostdevDefPtr def); +-- +2.33.0 + diff --git a/hostdev-Update-mdev-pointer-reference-after-checking.patch b/hostdev-Update-mdev-pointer-reference-after-checking.patch new file mode 100644 index 0000000000000000000000000000000000000000..b49c96d049b659c076a8697f382ece6039791ae4 --- /dev/null +++ b/hostdev-Update-mdev-pointer-reference-after-checking.patch @@ -0,0 +1,45 @@ +From 24ae6a276d538a31f42feb5e988d15b08b444b4a Mon Sep 17 00:00:00 2001 +From: Erik Skultety +Date: Thu, 7 Jan 2021 16:48:40 +0100 +Subject: [PATCH 078/108] 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) +--- + src/hypervisor/virhostdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c +index 9017cc3be8..c88c8bee0e 100644 +--- a/src/hypervisor/virhostdev.c ++++ b/src/hypervisor/virhostdev.c +@@ -1986,11 +1986,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.33.0 + diff --git a/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch b/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch new file mode 100644 index 0000000000000000000000000000000000000000..44953b358ff2e9759e1e680251a21b0be83c3573 --- /dev/null +++ b/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch @@ -0,0 +1,161 @@ +From 7b752336bd26048514d55bb222531c0b0183fa9c Mon Sep 17 00:00:00 2001 +From: Erik Skultety +Date: Thu, 7 Jan 2021 16:53:21 +0100 +Subject: [PATCH 079/108] 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) +--- + src/hypervisor/virhostdev.c | 10 ++++------ + src/util/virmdev.c | 16 ++++++++-------- + src/util/virmdev.h | 4 ++-- + 3 files changed, 14 insertions(+), 16 deletions(-) + +diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c +index c88c8bee0e..4057f7b25f 100644 +--- a/src/hypervisor/virhostdev.c ++++ b/src/hypervisor/virhostdev.c +@@ -1981,7 +1981,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]; +@@ -1990,14 +1990,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 51f7f608a2..1d97f7d44f 100644 +--- a/src/util/virmdev.h ++++ b/src/util/virmdev.h +@@ -119,11 +119,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.33.0 + diff --git a/leaseshelper-Report-errors-on-failure.patch b/leaseshelper-Report-errors-on-failure.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb4ea48078246f32b8d928f0048cdfbc4138602a --- /dev/null +++ b/leaseshelper-Report-errors-on-failure.patch @@ -0,0 +1,51 @@ +From 75d4ed800f297532a7b3ac2b8f8a94c049959e3b Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 18 Dec 2020 16:09:08 +0100 +Subject: [PATCH 024/108] leaseshelper: Report errors on failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If leasehelper fails all that we are left with is a simple error +message produced by dnsmasq: + + lease-init script returned exit code 1 + +This is because the leasehelper did not write any message to +stderr. According to dnsmasq's manpage, whenever it's invoking +leasehelper the stderr is kept open: + + All file descriptors are closed except stdin, which is open to + /dev/null, and stdout and stderr which capture output for + logging by dnsmasq. + +As debugging leasehelper is not trivial (because dnsmasq invokes +it with plenty of env vars set - that's how data is passed onto +helper), let's print an error into stderr if exiting with an +error. And since we are not calling public APIs, we have to call +virDispatchError() explicitly and since we don't have any +connection open, we have to pass NULL. + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit c14bd64f3eba9838af8ab1cac369d51abfeb21b9) +--- + src/network/leaseshelper.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index 2b5fc0f442..fdd7fd3e80 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -253,6 +253,8 @@ main(int argc, char **argv) + rv = EXIT_SUCCESS; + + cleanup: ++ if (rv != EXIT_SUCCESS) ++ virDispatchError(NULL); + if (pid_file_fd != -1) + virPidFileReleasePath(pid_file, pid_file_fd); + +-- +2.33.0 + diff --git a/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch b/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch new file mode 100644 index 0000000000000000000000000000000000000000..68964c3c8d92eecd15e78b96596c0977c8b0b78e --- /dev/null +++ b/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch @@ -0,0 +1,39 @@ +From fe9f75a69b6dac1dec4f77d8b17ec2406415d89d Mon Sep 17 00:00:00 2001 +From: Matt Coleman +Date: Mon, 21 Sep 2020 22:01:46 -0400 +Subject: [PATCH 037/108] libvirt: ensure defresult is used in + virConnectAuthCallbackDefault +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A previous change to this function's password handling broke the use of +default values for credential types other than VIR_CRED_PASSPHRASE and +VIR_CRED_NOECHOPROMPT. + +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Neal Gompa +Signed-off-by: Matt Coleman +(cherry picked from commit 1bb9f872a02f8be50c8f98b0ad13de62d2986fa9) +--- + src/libvirt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/libvirt.c b/src/libvirt.c +index 76bf1fa677..b11a15d7fe 100644 +--- a/src/libvirt.c ++++ b/src/libvirt.c +@@ -146,7 +146,9 @@ virConnectAuthCallbackDefault(virConnectCredentialPtr cred, + len = strlen(buf); + if (len != 0 && buf[len-1] == '\n') + buf[len-1] = '\0'; +- bufptr = g_strdup(buf); ++ ++ if (strlen(buf) > 0) ++ bufptr = g_strdup(buf); + break; + + case VIR_CRED_PASSPHRASE: +-- +2.33.0 + diff --git a/libvirt.spec b/libvirt.spec index 205a868fb743b0d3c4560b3d05a0382c6acb80a4..b5331f08bf893ed4527d6f6087d399f9a5fc4fef 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 42 +Release: 43 License: LGPLv2+ URL: https://libvirt.org/ @@ -252,6 +252,114 @@ Patch0139: src-workaround-warning-triggered-in-glib-2.69.patch Patch0140: nwfilter-fix-crash-when-counting-number-of-network-f.patch Patch0141: apibuild-Fix-self.waring-method-call.patch Patch0142: qemu-Add-missing-lock-in-qemuProcessHandleMonitorEOF.patch +Patch0143: util-avoid-race-in-releasing-the-GSource-in-event-th.patch +Patch0144: test-Fix-memory-leak-in-testParseXMLDocFromFile.patch +Patch0145: lxc-Fix-memory-leak-in-virLXCControllerPopulateDevic.patch +Patch0146: util-Fix-memory-leak-in-virAuthConfigLookup.patch +Patch0147: util-Fix-memory-leak-in-virAuthGetCredential.patch +Patch0148: qemu_security-Complete-renaming-of-virSecurityManage.patch +Patch0149: virSecurityManagerMetadataLock-Ignore-RO-filesystem.patch +Patch0150: virSecurityManagerMetadataLock-Clarify-directory-loc.patch +Patch0151: qemu-Use-qemuSecurityDomainSetPathLabel-to-set-secla.patch +Patch0152: qemu-Drop-unused-qemuSecuritySetSavedStateLabel.patch +Patch0153: qemu-don-t-shutdown-event-thread-in-monitor-EOF-call.patch +Patch0154: cpu_map-Fix-Icelake-Server-model-number.patch +Patch0155: rpc-avoid-crash-when-system-time-jump-back.patch +Patch0156: check-for-NULL-before-calling-g_regex_unref.patch +Patch0157: qemu_monitor-Document-qemuMonitorUnregister.patch +Patch0158: storageBackendProbeTarget-Don-t-fail-if-backing-stor.patch +Patch0159: virPipeImpl-Don-t-overwrite-error.patch +Patch0160: virBufferAdd-Ensure-that-the-buffer-is-initialized-a.patch +Patch0161: qemuMigrationSrcRun-Don-t-jump-to-exit_monitor-from-.patch +Patch0162: util-Fix-error-reporting-in-virnetlink.patch +Patch0163: locking-Resolve-mem-leak-in-virLockDaemonPreExecRest.patch +Patch0164: qemu_conf-Fix-double-free-problem-for-cfg-firmwares.patch +Patch0165: qemuDomainCheckpointLoad-Don-t-align-disks-when-rest.patch +Patch0166: leaseshelper-Report-errors-on-failure.patch +Patch0167: networkGetDHCPLeases-Use-VIR_APPEND_ELEMENT-instead-.patch +Patch0168: qemuFirmwareFillDomain-Fill-NVRAM-template-on-migrat.patch +Patch0169: disk-storage-fix-allocation-size-for-pool-format-dos.patch +Patch0170: qemu-qemuDomainPMSuspendAgent-Don-t-assign-to-ret-in.patch +Patch0171: tests-avoid-close-of-bad-file-handle-in-commandtest.patch +Patch0172: util-event-check-return-value-of-virInitialize.patch +Patch0173: rpc-socket-properly-call-virSetCloseExec.patch +Patch0174: virsh-do-not-return-bool-in-virshNetworkPortUUIDComp.patch +Patch0175: logging-fix-endless-loop-on-EOF.patch +Patch0176: vircommand.c-write-child-pidfile-before-process-tuni.patch +Patch0177: virsocketaddr-Zero-netmask-in-virSocketAddrPrefixToN.patch +Patch0178: logging-read-all-bytes-on-EOF-in-event-handler.patch +Patch0179: libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch +Patch0180: qemu-firmware-check-virJSONValueObjectGet-return-val.patch +Patch0181: qemu-qemuDomainPMSuspendForDuration-Check-availabili.patch +Patch0182: virNodeDevPCICapSRIOVVirtualParseXML-fix-memleak-of-.patch +Patch0183: qemu-snapshot-Collect-query-named-block-nodes-prior-.patch +Patch0184: virsh-completer-use-signed-variable-for-XPathNodeSet.patch +Patch0185: virt-login-shell-correctly-calculate-string-length.patch +Patch0186: qemu-avoid-maybe-uninitialized-warning-by-GCC-10.patch +Patch0187: tools-avoid-potential-null-pointer-dereference-by-GC.patch +Patch0188: storage-avoid-maybe-uninitialized-warning-by-GCC-10.patch +Patch0189: virnuma-Don-t-work-around-numa_node_to_cpus-for-non-.patch +Patch0190: virsh-guest-agent-timeout-set-default-value-for-opti.patch +Patch0191: conf-properly-clear-out-autogenerated-macvtap-names-.patch +Patch0192: storage_util-fix-qemu-img-sparse-allocation.patch +Patch0193: vahDeinit-Fix-memory-leak.patch +Patch0194: virnetdevbridge-Ignore-EEXIST-when-adding-an-entry-t.patch +Patch0195: securityselinuxhelper-Fix-retval-of-setcon_raw-and-s.patch +Patch0196: virCapabilitiesHostNUMAInitReal-Free-cpus-properly.patch +Patch0197: vsh-fix-memory-leak-in-vshCommandParse.patch +Patch0198: qemu_interface-Fix-cfg-refcounting-in-qemuInterfaceP.patch +Patch0199: qemuBlockJobProcessEventCompletedPull-Avoid-dangling.patch +Patch0200: qemuBlockJobProcessEventCompletedPull-Add-backingSto.patch +Patch0201: nodedev-Signal-initCond-with-driver-locked.patch +Patch0202: nodedev-Mark-device-initialization-complete-even-in-.patch +Patch0203: cmdCheckpointList-Fix-memory-leak.patch +Patch0204: cmdSnapshotList-Fix-memory-leak.patch +Patch0205: virshCheckpointListCollect-Do-not-pass-NULL-to-qsort.patch +Patch0206: qemu-blockjob-Transition-into-ready-state-only-from-.patch +Patch0207: qemu-fix-crash-in-qemuDomainSetBlkioParameters-witho.patch +Patch0208: domain_capabilities-Assert-enums-fit-into-unsigned-i.patch +Patch0209: domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch +Patch0210: conf-Use-unsigned-long-long-for-timer-frequency.patch +Patch0211: parthelper-Don-t-leak-canonical_path.patch +Patch0212: parthelper-Initialize-error-object.patch +Patch0213: qemu-fix-qemuMigrationSrcCleanup-to-use-qemuMigratio.patch +Patch0214: util-Avoid-double-free-in-virProcessSetAffinity.patch +Patch0215: util-fix-very-old-bug-typo-in-virNetDevParseVfInfo.patch +Patch0216: domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch +Patch0217: testutils-call-va_end-before-return.patch +Patch0218: qemu-Don-t-cache-domCaps-in-virQEMUDriverGetDomainCa.patch +Patch0219: network-Introduce-mutex-for-bridge-name-generation.patch +Patch0220: hostdev-Update-mdev-pointer-reference-after-checking.patch +Patch0221: hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch +Patch0222: util-new-function-virSkipToDigit.patch +Patch0223: util-Skip-over-any-extra-verbiage-preceding-version-.patch +Patch0224: qemuMigrationSrcNBDStorageCopyReady-Use-ready-state-.patch +Patch0225: qemuBlockJobEventProcess-Always-clear-mirrorState-wh.patch +Patch0226: qemu-Fix-memstat-for-non-transitional-memballoon.patch +Patch0227: virsh-Fix-XPATH-in-virshDomainDeviceAliasCompleter.patch +Patch0228: virsh-domain-Fix-error-handling-of-pthread_sigmask.patch +Patch0229: qemu_driver-increase-recorded-counter-for-disk-block.patch +Patch0230: qemu_capabilities-Don-t-leak-str-in-virQEMUCapsLoadM.patch +Patch0231: qemu_process-Release-domain-seclabel-later-in-qemuPr.patch +Patch0232: nodedev-Don-t-crash-when-exiting-before-init-is-done.patch +Patch0233: domain_cgroup.c-update-domain-after-setting-blkio.we.patch +Patch0234: virCPUDefFindFeature-Make-first-argument-const-ptr.patch +Patch0235: qemuOpenFileAs-Move-into-util-virqemu.c.patch +Patch0236: Don-t-call-qsort-over-NULL.patch +Patch0237: virFileReadLimFD-Cast-maxlen-to-size_t-before-adding.patch +Patch0238: virnuma-Use-numa_nodes_ptr-when-checking-available-N.patch +Patch0239: testutils-Don-t-leak-testBitmap-and-failedTests.patch +Patch0240: tests-Don-t-leak-cpu-defs.patch +Patch0241: virsh-snapshot-Don-t-leak-then-in-cmdSnapshotList.patch +Patch0242: util-virIdentitySetCurrent-only-unref-the-old-identi.patch +Patch0243: vireventglib-Remove-handles-with-the-highest-priorit.patch +Patch0244: qemu-Do-not-pass-negative-ncpus-to-virCapabilitiesCl.patch +Patch0245: qemu_agent-Rework-domain-object-locking-when-opening.patch +Patch0246: util-virExec-may-blocked-by-reading-pipe-if-grandchi.patch +Patch0247: util-fix-cache-invalidation-of-swtpm-capabilities.patch +Patch0248: virnettlscontext-Drop-gnutls_dh_set_prime_bits.patch +Patch0249: virnettlscontext-Don-t-pass-static-key-length-to-gnu.patch +Patch0250: rpc-Fix-memory-leak-of-fds.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1986,6 +2094,9 @@ exit 0 %changelog +* Tue Oct 11 2022 wengyu - 6.2.0-43 +- libvirt: Synchronize upstream patches according to issue I5OLYY + * Thu Aug 25 2022 yezengruan - 6.2.0-42 - qemu: Add missing lock in qemuProcessHandleMonitorEOF (CVE-2021-3975) diff --git a/locking-Resolve-mem-leak-in-virLockDaemonPreExecRest.patch b/locking-Resolve-mem-leak-in-virLockDaemonPreExecRest.patch new file mode 100644 index 0000000000000000000000000000000000000000..71d944dd1ac07110d6305028ba36cbca717eed42 --- /dev/null +++ b/locking-Resolve-mem-leak-in-virLockDaemonPreExecRest.patch @@ -0,0 +1,56 @@ +From 3542d88e097199e80419ebcb1a82b68cc71d3e2b Mon Sep 17 00:00:00 2001 +From: John Ferlan +Date: Wed, 2 Dec 2020 07:43:20 -0500 +Subject: [PATCH 021/108] locking: Resolve mem leak in + virLockDaemonPreExecRestart +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Initialize and free @magic since virJSONValueObjectAppendString +does not free it for us eventually. + +Signed-off-by: John Ferlan +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +(cherry picked from commit 6f0418173b5567d17dba43247efc058f0318485b) +--- + src/locking/lock_daemon.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c +index 3d33995beb..9bf505c939 100644 +--- a/src/locking/lock_daemon.c ++++ b/src/locking/lock_daemon.c +@@ -722,7 +722,7 @@ virLockDaemonPreExecRestart(const char *state_file, + char *state = NULL; + int ret = -1; + virJSONValuePtr object = virJSONValueNewObject(); +- char *magic; ++ char *magic = NULL; + virHashKeyValuePairPtr pairs = NULL, tmp; + virJSONValuePtr lockspaces; + +@@ -770,10 +770,8 @@ virLockDaemonPreExecRestart(const char *state_file, + if (!(magic = virLockDaemonGetExecRestartMagic())) + goto cleanup; + +- if (virJSONValueObjectAppendString(object, "magic", magic) < 0) { +- VIR_FREE(magic); ++ if (virJSONValueObjectAppendString(object, "magic", magic) < 0) + goto cleanup; +- } + + if (!(state = virJSONValueToString(object, true))) + goto cleanup; +@@ -797,6 +795,7 @@ virLockDaemonPreExecRestart(const char *state_file, + abort(); /* This should be impossible to reach */ + + cleanup: ++ VIR_FREE(magic); + VIR_FREE(pairs); + VIR_FREE(state); + virJSONValueFree(object); +-- +2.33.0 + diff --git a/logging-fix-endless-loop-on-EOF.patch b/logging-fix-endless-loop-on-EOF.patch new file mode 100644 index 0000000000000000000000000000000000000000..789433e71524837d5b3a0e430a3f4424e407894c --- /dev/null +++ b/logging-fix-endless-loop-on-EOF.patch @@ -0,0 +1,31 @@ +From 8a4f9cab7d08bf13ac794fa2800a37c59ac14728 Mon Sep 17 00:00:00 2001 +From: Nikolay Shirokovskiy +Date: Thu, 24 Sep 2020 15:54:24 +0300 +Subject: [PATCH 033/108] logging: fix endless loop on EOF + +On EOF condition we always have POLLHUP event and read returns +0 thus we never break loop in virLogHandlerDomainLogFileDrain. + +Signed-off-by: Nikolay Shirokovskiy +Reviewed-by: Michal Privoznik +(cherry picked from commit bde9e2c6c018f79d8e3b0bd30ea7aa80dcc9e435) +--- + src/logging/log_handler.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/logging/log_handler.c b/src/logging/log_handler.c +index 87748d96d1..3cc197a396 100644 +--- a/src/logging/log_handler.c ++++ b/src/logging/log_handler.c +@@ -464,6 +464,8 @@ virLogHandlerDomainLogFileDrain(virLogHandlerLogFilePtr file) + if (errno == EINTR) + continue; + return; ++ } else if (len == 0) { ++ return; + } + + if (virRotatingFileWriterAppend(file->file, buf, len) != len) +-- +2.33.0 + diff --git a/logging-read-all-bytes-on-EOF-in-event-handler.patch b/logging-read-all-bytes-on-EOF-in-event-handler.patch new file mode 100644 index 0000000000000000000000000000000000000000..b9784eaa6156c98ebab7acb6685bdfa850adffdc --- /dev/null +++ b/logging-read-all-bytes-on-EOF-in-event-handler.patch @@ -0,0 +1,50 @@ +From f2f21f4f7a5f0fdf43fa957f0628045ed373a025 Mon Sep 17 00:00:00 2001 +From: Nikolay Shirokovskiy +Date: Thu, 24 Sep 2020 15:47:09 +0300 +Subject: [PATCH 036/108] logging: read all bytes on EOF in event handler + +If writing side writes enough bytes to the pipe and closes writing +end then we got both VIR_EVENT_HANDLE_HANGUP and VIR_EVENT_HANDLE_READ +in handler. Currently in this situation handler reads 1024 bytes +and finish reading leaving unread data in pipe. + +Signed-off-by: Nikolay Shirokovskiy +Reviewed-by: Michal Privoznik +(cherry picked from commit 7c0e1a8631773788a96702252931541290288ef6) +--- + src/logging/log_handler.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/logging/log_handler.c b/src/logging/log_handler.c +index 3cc197a396..00fca7b653 100644 +--- a/src/logging/log_handler.c ++++ b/src/logging/log_handler.c +@@ -138,7 +138,7 @@ virLogHandlerGetLogFileFromWatch(virLogHandlerPtr handler, + static void + virLogHandlerDomainLogFileEvent(int watch, + int fd, +- int events, ++ int events G_GNUC_UNUSED, + void *opaque) + { + virLogHandlerPtr handler = opaque; +@@ -168,14 +168,13 @@ virLogHandlerDomainLogFileEvent(int watch, + virReportSystemError(errno, "%s", + _("Unable to read from log pipe")); + goto error; ++ } else if (len == 0) { ++ goto error; + } + + if (virRotatingFileWriterAppend(logfile->file, buf, len) != len) + goto error; + +- if (events & VIR_EVENT_HANDLE_HANGUP) +- goto error; +- + cleanup: + virObjectUnlock(handler); + return; +-- +2.33.0 + diff --git a/lxc-Fix-memory-leak-in-virLXCControllerPopulateDevic.patch b/lxc-Fix-memory-leak-in-virLXCControllerPopulateDevic.patch new file mode 100644 index 0000000000000000000000000000000000000000..2ac1dbac162cdd4774008e5f107135b43208c656 --- /dev/null +++ b/lxc-Fix-memory-leak-in-virLXCControllerPopulateDevic.patch @@ -0,0 +1,43 @@ +From 39baaf38c00b4ff78100bf3d1b378140678e9dfb Mon Sep 17 00:00:00 2001 +From: John Ferlan +Date: Tue, 16 Jun 2020 08:07:04 -0400 +Subject: [PATCH 003/108] lxc: Fix memory leak in + virLXCControllerPopulateDevices + +Since 5b82f7f3, @path should have been placed inside the for loop +since it'd need to be free'd for each pass through the loop; otherwise, +we'd leak like a sieve. + +Found by Coverity. + +Signed-off-by: John Ferlan +Reviewed-by: Peter Krempa +(cherry picked from commit 52e3c2b4801c4ef3d8be5c1398de1884e93a1f52) +--- + src/lxc/lxc_controller.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c +index 453b435dd6..7a3a79a9a0 100644 +--- a/src/lxc/lxc_controller.c ++++ b/src/lxc/lxc_controller.c +@@ -1490,7 +1490,6 @@ static int virLXCControllerSetupDev(virLXCControllerPtr ctrl) + static int virLXCControllerPopulateDevices(virLXCControllerPtr ctrl) + { + size_t i; +- g_autofree char *path = NULL; + const struct { + int maj; + int min; +@@ -1510,6 +1509,8 @@ static int virLXCControllerPopulateDevices(virLXCControllerPtr ctrl) + + /* Populate /dev/ with a few important bits */ + for (i = 0; i < G_N_ELEMENTS(devs); i++) { ++ g_autofree char *path = NULL; ++ + path = g_strdup_printf("/%s/%s.dev/%s", LXC_STATE_DIR, ctrl->def->name, + devs[i].path); + +-- +2.33.0 + diff --git a/network-Introduce-mutex-for-bridge-name-generation.patch b/network-Introduce-mutex-for-bridge-name-generation.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d6729a6bbe4134f8a8b80716eb0b6781ac5bf37 --- /dev/null +++ b/network-Introduce-mutex-for-bridge-name-generation.patch @@ -0,0 +1,71 @@ +From b85da76baeebccdb35c12bbc16f82692c42a7372 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 7 Jan 2021 15:51:02 +0100 +Subject: [PATCH 077/108] network: Introduce mutex for bridge name generation + +When defining/creating a network the bridge name may be filled in +automatically by libvirt (if none provided in the input XML or +the one provided is a pattern, e.g. "virbr%d"). During the +bridge name generation process a candidate name is generated +which is then checked with the rest of already defined/running +networks for collisions. + +Problem is, that there is no mutex guarding this critical section +and thus if two threads line up so that they both generate the +same candidate they won't find any collision and the same name is +then stored. + +Resolves: https://gitlab.com/libvirt/libvirt/-/issues/78 +Signed-off-by: Michal Privoznik +Reviewed-by: Laine Stump +(cherry picked from commit ea0cfa115307ecb9fe05dd1953ec7ddd8dd39d72) +--- + src/network/bridge_driver.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index 21d02dd304..ce61ff483a 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -74,6 +74,8 @@ + #define VIR_FROM_THIS VIR_FROM_NETWORK + #define MAX_BRIDGE_ID 256 + ++static virMutex bridgeNameValidateMutex = VIR_MUTEX_INITIALIZER; ++ + /** + * VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX: + * +@@ -3255,20 +3257,27 @@ static int + networkBridgeNameValidate(virNetworkObjListPtr nets, + virNetworkDefPtr def) + { ++ virMutexLock(&bridgeNameValidateMutex); ++ + if (def->bridge && !strstr(def->bridge, "%d")) { + if (virNetworkObjBridgeInUse(nets, def->bridge, def->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("bridge name '%s' already in use."), + def->bridge); +- return -1; ++ goto error; + } + } else { + /* Allocate a bridge name */ + if (networkFindUnusedBridgeName(nets, def) < 0) +- return -1; ++ goto error; + } + ++ virMutexUnlock(&bridgeNameValidateMutex); + return 0; ++ ++ error: ++ virMutexUnlock(&bridgeNameValidateMutex); ++ return -1; + } + + +-- +2.33.0 + diff --git a/networkGetDHCPLeases-Use-VIR_APPEND_ELEMENT-instead-.patch b/networkGetDHCPLeases-Use-VIR_APPEND_ELEMENT-instead-.patch new file mode 100644 index 0000000000000000000000000000000000000000..54ab3bf514bf59b7d6eacd00868473567509abbb --- /dev/null +++ b/networkGetDHCPLeases-Use-VIR_APPEND_ELEMENT-instead-.patch @@ -0,0 +1,36 @@ +From 9c6ee47619deb2553dafd498ba03aff29a484069 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 18 Dec 2020 16:09:13 +0100 +Subject: [PATCH 025/108] networkGetDHCPLeases: Use VIR_APPEND_ELEMENT() + instead of VIR_INSERT_ELEMENT() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This function is misusing VIR_INSERT_ELEMENT() to behave like +VIR_APPEND_ELEMENT(). Use the latter to make it explicit what we +are trying to achieve. + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit ee93656c40467fa614e999a146a56011a9c500e3) +--- + src/network/bridge_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index f06099297a..21d02dd304 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -4322,7 +4322,7 @@ networkGetDHCPLeases(virNetworkPtr net, + lease->clientid = g_strdup(virJSONValueObjectGetString(lease_tmp, "client-id")); + lease->hostname = g_strdup(virJSONValueObjectGetString(lease_tmp, "hostname")); + +- if (VIR_INSERT_ELEMENT(leases_ret, nleases, nleases, lease) < 0) ++ if (VIR_APPEND_ELEMENT(leases_ret, nleases, lease) < 0) + goto error; + + } else { +-- +2.33.0 + diff --git a/nodedev-Don-t-crash-when-exiting-before-init-is-done.patch b/nodedev-Don-t-crash-when-exiting-before-init-is-done.patch new file mode 100644 index 0000000000000000000000000000000000000000..31c0961c6c5063d2efe01cd7c22a0363425d0f52 --- /dev/null +++ b/nodedev-Don-t-crash-when-exiting-before-init-is-done.patch @@ -0,0 +1,99 @@ +From 7ff49868cf6a80d14f83a064b6524de233f5b6b0 Mon Sep 17 00:00:00 2001 +From: Jonathon Jongsma +Date: Tue, 16 Mar 2021 17:27:25 -0500 +Subject: [PATCH 090/108] nodedev: Don't crash when exiting before init is done + +If libvirtd is terminated before the node driver finishes +initialization, it can crash with a backtrace similar to the following: + + Stack trace of thread 1922933: + #0 0x00007f8515178774 g_hash_table_find (libglib-2.0.so.0) + #1 0x00007f851593ea98 virHashSearch (libvirt.so.0) + #2 0x00007f8515a1dd83 virNodeDeviceObjListSearch (libvirt.so.0) + #3 0x00007f84cceb40a1 udevAddOneDevice (libvirt_driver_nodedev.so) + #4 0x00007f84cceb5fae nodeStateInitializeEnumerate (libvirt_driver_nodedev.so) + #5 0x00007f85159840cb virThreadHelper (libvirt.so.0) + #6 0x00007f8511c7d14a start_thread (libpthread.so.0) + #7 0x00007f851442bdb3 __clone (libc.so.6) + + Stack trace of thread 1922863: + #0 0x00007f851442651d syscall (libc.so.6) + #1 0x00007f85159842d4 virThreadSelfID (libvirt.so.0) + #2 0x00007f851594e240 virLogFormatString (libvirt.so.0) + #3 0x00007f851596635d vir_object_finalize (libvirt.so.0) + #4 0x00007f8514efe8e9 g_object_unref (libgobject-2.0.so.0) + #5 0x00007f85159667f8 virObjectUnref (libvirt.so.0) + #6 0x00007f851517755f g_hash_table_remove_all_nodes.part.0 (libglib-2.0.so.0) + #7 0x00007f8515177e62 g_hash_table_unref (libglib-2.0.so.0) + #8 0x00007f851596637e vir_object_finalize (libvirt.so.0) + #9 0x00007f8514efe8e9 g_object_unref (libgobject-2.0.so.0) + #10 0x00007f85159667f8 virObjectUnref (libvirt.so.0) + #11 0x00007f84cceb2b42 nodeStateCleanup (libvirt_driver_nodedev.so) + #12 0x00007f8515b37950 virStateCleanup (libvirt.so.0) + #13 0x00005648085348e8 main (libvirtd) + #14 0x00007f8514352493 __libc_start_main (libc.so.6) + #15 0x00005648085350fe _start (libvirtd) + +This is because the initial population of the device list is done in a +separate initialization thread. If we attempt to exit libvirtd before +this init thread has completed, we'll try to free the device list while +accessing it from the other thread. In order to guarantee that this +init thread is not accessing the device list when we're cleaning up the +nodedev driver, make it joinable and wait for it to finish before +proceding with the cleanup. This is similar to how we handle the udev +event handler thread. + +The separate initialization thread was added in commit +9f0ae0b1. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1836865 + +Signed-off-by: Jonathon Jongsma +Reviewed-by: Michal Privoznik +(cherry picked from commit caf23cdc9b628ae3acd89478fbace093b23649b8) +--- + src/node_device/node_device_udev.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index e65979c1b6..94e8469dcb 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -66,6 +66,9 @@ struct _udevEventData { + virCond threadCond; + bool threadQuit; + bool dataReady; ++ ++ /* init thread */ ++ virThread initThread; + }; + + static virClassPtr udevEventDataClass; +@@ -1467,6 +1470,7 @@ nodeStateCleanup(void) + priv->threadQuit = true; + virCondSignal(&priv->threadCond); + virObjectUnlock(priv); ++ virThreadJoin(&priv->initThread); + virThreadJoin(&priv->th); + } + +@@ -1799,7 +1803,6 @@ nodeStateInitialize(bool privileged, + { + udevEventDataPtr priv = NULL; + struct udev *udev = NULL; +- virThread enumThread; + + if (root != NULL) { + virReportError(VIR_ERR_INVALID_ARG, "%s", +@@ -1908,7 +1911,7 @@ nodeStateInitialize(bool privileged, + if (udevSetupSystemDev() != 0) + goto cleanup; + +- if (virThreadCreateFull(&enumThread, false, nodeStateInitializeEnumerate, ++ if (virThreadCreateFull(&priv->initThread, true, nodeStateInitializeEnumerate, + "nodedev-init", false, udev) < 0) { + virReportSystemError(errno, "%s", + _("failed to create udev enumerate thread")); +-- +2.33.0 + diff --git a/nodedev-Mark-device-initialization-complete-even-in-.patch b/nodedev-Mark-device-initialization-complete-even-in-.patch new file mode 100644 index 0000000000000000000000000000000000000000..57c4d5bdbe4525b15f4c33466c599a758dc5cd98 --- /dev/null +++ b/nodedev-Mark-device-initialization-complete-even-in-.patch @@ -0,0 +1,48 @@ +From 557fe55a1c0c6f913cfa41c0b42b7d2fbb70c55a Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 13 Apr 2021 10:45:24 +0200 +Subject: [PATCH 060/108] nodedev: Mark device initialization complete even in + case of an error + +To speed up nodedev driver initialization, the device enumeration +is done in a separate thread. Once finished, the thread sets a +boolean variable that allows public APIs to be called (instead of +waiting for the thread to finish). + +However, if there's an error in the device enumeration thread +then the control jumps over at the 'error' label and the boolean +is never set. This means, that any virNodeDev*() API is stuck +forever. Mark the initialization as complete (the thread is +quitting anyway) and let the APIs proceed. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 54d97f020b6349b9e3e1cb966078625dcdd964a8) +--- + src/node_device/node_device_udev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index 000494f9e3..e65979c1b6 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1747,6 +1747,7 @@ nodeStateInitializeEnumerate(void *opaque) + if (udevEnumerateDevices(udev) != 0) + goto error; + ++ cleanup: + nodeDeviceLock(); + driver->initialized = true; + virCondBroadcast(&driver->initCond); +@@ -1761,6 +1762,8 @@ nodeStateInitializeEnumerate(void *opaque) + priv->threadQuit = true; + virCondSignal(&priv->threadCond); + virObjectUnlock(priv); ++ ++ goto cleanup; + } + + +-- +2.33.0 + diff --git a/nodedev-Signal-initCond-with-driver-locked.patch b/nodedev-Signal-initCond-with-driver-locked.patch new file mode 100644 index 0000000000000000000000000000000000000000..e83c1c14c21591dcf213deaaf69fbbc1b2c83407 --- /dev/null +++ b/nodedev-Signal-initCond-with-driver-locked.patch @@ -0,0 +1,44 @@ +From f5b37c4f1768df3464a7666255975f7c7f2d14b3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 13 Apr 2021 10:52:07 +0200 +Subject: [PATCH 059/108] nodedev: Signal initCond with driver locked + +This is more academic dispute than a real bug, but this is taken +from pthread_cond_broadcast(3p) man: + + The pthread_cond_broadcast() or pthread_cond_signal() functions + may be called by a thread whether or not it currently owns the + mutex that threads calling pthread_cond_wait() or + pthread_cond_timedwait() have associated with the condition + variable during their waits; however, if predictable scheduling + behavior is required, then that mutex shall be locked by the + thread calling pthread_cond_broadcast() or + pthread_cond_signal(). + +Therefore, broadcast the initCond while the nodedev driver is +still locked. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 5b56a288cab097896832dc9d4acb7f23dfca377c) +--- + src/node_device/node_device_udev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index a1391fb0de..000494f9e3 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1749,8 +1749,8 @@ nodeStateInitializeEnumerate(void *opaque) + + nodeDeviceLock(); + driver->initialized = true; +- nodeDeviceUnlock(); + virCondBroadcast(&driver->initCond); ++ nodeDeviceUnlock(); + + return; + +-- +2.33.0 + diff --git a/parthelper-Don-t-leak-canonical_path.patch b/parthelper-Don-t-leak-canonical_path.patch new file mode 100644 index 0000000000000000000000000000000000000000..61ec541a221dad0b710b0ab3223ea63353bd9acf --- /dev/null +++ b/parthelper-Don-t-leak-canonical_path.patch @@ -0,0 +1,36 @@ +From 87376268b3baf188e85095c5429d707d9a5e59a4 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 22 Oct 2020 12:55:40 +0200 +Subject: [PATCH 069/108] parthelper: Don't leak @canonical_path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The @canonical_path variable holds canonicalized path passed as +argv[1]. The canonicalized path is obtained either via +virFileResolveLink() or plain g_strdup(). Nevertheless, in both +cases it must be freed. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit db8e747af98df732aff67eca9fb67514310359bf) +--- + src/storage/parthelper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/storage/parthelper.c b/src/storage/parthelper.c +index 812e90d3cb..8278ddf31e 100644 +--- a/src/storage/parthelper.c ++++ b/src/storage/parthelper.c +@@ -62,7 +62,7 @@ int main(int argc, char **argv) + PedPartition *part; + int cmd = DISK_LAYOUT; + const char *path; +- char *canonical_path; ++ g_autofree char *canonical_path = NULL; + const char *partsep; + bool devmap_partsep = false; + +-- +2.33.0 + diff --git a/parthelper-Initialize-error-object.patch b/parthelper-Initialize-error-object.patch new file mode 100644 index 0000000000000000000000000000000000000000..3419a94df36fb782680e366cb44aa8302368387c --- /dev/null +++ b/parthelper-Initialize-error-object.patch @@ -0,0 +1,38 @@ +From 164e4821d0333812b32f9ce9e64133df31dd6443 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 22 Oct 2020 12:49:44 +0200 +Subject: [PATCH 070/108] parthelper: Initialize error object +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some functions called from parthelper can report an error. But +that means that the error object must be initialized otherwise +virResetError() (which happens as a part of virReportError()) +will free random pointers. + +Reported-by: Katerina Koukiou +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 3b8deb9603fb2a393a28fe4750aba91626619305) +--- + src/storage/parthelper.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/storage/parthelper.c b/src/storage/parthelper.c +index 8278ddf31e..caa2e8fa62 100644 +--- a/src/storage/parthelper.c ++++ b/src/storage/parthelper.c +@@ -66,7 +66,8 @@ int main(int argc, char **argv) + const char *partsep; + bool devmap_partsep = false; + +- if (virGettextInitialize() < 0) ++ if (virGettextInitialize() < 0 || ++ virErrorInitialize() < 0) + exit(EXIT_FAILURE); + + if (argc == 3 && STREQ(argv[2], "-g")) { +-- +2.33.0 + diff --git a/qemu-Do-not-pass-negative-ncpus-to-virCapabilitiesCl.patch b/qemu-Do-not-pass-negative-ncpus-to-virCapabilitiesCl.patch new file mode 100644 index 0000000000000000000000000000000000000000..aadb9a2864543150de891ed05a7236c7b2f5042f --- /dev/null +++ b/qemu-Do-not-pass-negative-ncpus-to-virCapabilitiesCl.patch @@ -0,0 +1,31 @@ +From 95d8d2662b91263f75c0b3813bd23d2b9f89f704 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Thu, 4 Nov 2021 19:49:36 +0100 +Subject: [PATCH 102/108] qemu: Do not pass negative ncpus to + virCapabilitiesClearHostNUMACellCPUTopology + +It won't cause any harm as cpus is NULL when we pass a negative ncpus, +but doing so when the function expects unsigned value is not right. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 6cb5464ab4697acbc56341732a15519234edfef0) +--- + src/conf/capabilities.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index deb99cecd3..12c8c3a324 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -1650,6 +1650,7 @@ virCapabilitiesHostNUMAInitReal(virCapsHostNUMAPtr caps) + if (ncpus == -2) + continue; + ++ ncpus = 0; + goto cleanup; + } + +-- +2.33.0 + diff --git a/qemu-Don-t-cache-domCaps-in-virQEMUDriverGetDomainCa.patch b/qemu-Don-t-cache-domCaps-in-virQEMUDriverGetDomainCa.patch new file mode 100644 index 0000000000000000000000000000000000000000..e497a3534845019a2b168afc929f8853db42ab4b --- /dev/null +++ b/qemu-Don-t-cache-domCaps-in-virQEMUDriverGetDomainCa.patch @@ -0,0 +1,80 @@ +From 1fecad527ab391c045551f7b0d472bc2925683b3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 13 Nov 2020 21:09:33 +0100 +Subject: [PATCH 076/108] qemu: Don't cache domCaps in + virQEMUDriverGetDomainCapabilities() + +Currently, whenever a domain capabilities is needed (fortunately, +after cleanup done by previous commits it is now only in +virConnectGetDomainCapabilities()), the object is stored in a +cache. But there is no invalidation mechanism for the cache +(except the implicit one - the cache is part of qemuCaps and thus +share its lifetime, but that is not enough). Therefore, if +something changes - for instance new firmware files are +installed, or old are removed these changes are not reflected in +the virConnectGetDomainCapabilities() output. + +Originally, the caching was there because domCaps were used +during device XML validation and they were used a lot from our +test suite. But this is no longer the case. And therefore, we +don't need the cache and can construct fresh domCaps on each +virConnectGetDomainCapabilities() call. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1807198 + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 7db61843b05a6e4295b1d2e27a3d86f162ef04a0) +--- + src/qemu/qemu_conf.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index da2a1bdfe4..28319a1baf 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1397,11 +1397,8 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, + /** + * virQEMUDriverGetDomainCapabilities: + * +- * Get a reference to the virDomainCapsPtr instance from the virQEMUCapsPtr +- * domCapsCache. If there's no domcaps in the cache, create a new instance, +- * add it to the cache, and return a reference. +- * +- * The caller must release the reference with virObjetUnref ++ * Get a reference to the virDomainCapsPtr instance. The caller ++ * must release the reference with virObjetUnref(). + * + * Returns: a reference to a virDomainCapsPtr instance or NULL + */ +@@ -1413,15 +1410,19 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriverPtr driver, + virDomainVirtType virttype) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); ++ g_autoptr(virDomainCaps) domCaps = NULL; ++ const char *path = virQEMUCapsGetBinary(qemuCaps); ++ ++ if (!(domCaps = virDomainCapsNew(path, machine, arch, virttype))) ++ return NULL; ++ ++ if (virQEMUCapsFillDomainCaps(qemuCaps, driver->hostarch, ++ domCaps, driver->privileged, ++ cfg->firmwares, ++ cfg->nfirmwares) < 0) ++ return NULL; + +- return virQEMUCapsGetDomainCapsCache(qemuCaps, +- machine, +- arch, +- virttype, +- driver->hostarch, +- driver->privileged, +- cfg->firmwares, +- cfg->nfirmwares); ++ return g_steal_pointer(&domCaps); + } + + +-- +2.33.0 + diff --git a/qemu-Drop-unused-qemuSecuritySetSavedStateLabel.patch b/qemu-Drop-unused-qemuSecuritySetSavedStateLabel.patch new file mode 100644 index 0000000000000000000000000000000000000000..416120eca9ba9336a8546bd7087faf5cc1d1eb3f --- /dev/null +++ b/qemu-Drop-unused-qemuSecuritySetSavedStateLabel.patch @@ -0,0 +1,75 @@ +From 11481239cc36aa9076a1eb44b4dbaa2968c248cb Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 17 Jun 2020 11:10:49 +0200 +Subject: [PATCH 010/108] qemu: Drop unused qemuSecuritySetSavedStateLabel() + +After previous commit this function is used no more. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 3cc557c7faeeaf503ca22dac8e9c7bb9c43740e0) +--- + src/qemu/qemu_security.c | 31 ------------------------------- + src/qemu/qemu_security.h | 4 ---- + 2 files changed, 35 deletions(-) + +diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c +index e7f38cb69b..5cfbcbd592 100644 +--- a/src/qemu/qemu_security.c ++++ b/src/qemu/qemu_security.c +@@ -607,37 +607,6 @@ qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, + } + + +-int +-qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver, +- virDomainObjPtr vm, +- const char *savefile) +-{ +- qemuDomainObjPrivatePtr priv = vm->privateData; +- pid_t pid = -1; +- int ret = -1; +- +- if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) +- pid = vm->pid; +- +- if (virSecurityManagerTransactionStart(driver->securityManager) < 0) +- goto cleanup; +- +- if (virSecurityManagerSetSavedStateLabel(driver->securityManager, +- vm->def, +- savefile) < 0) +- goto cleanup; +- +- if (virSecurityManagerTransactionCommit(driver->securityManager, +- pid, priv->rememberOwner) < 0) +- goto cleanup; +- +- ret = 0; +- cleanup: +- virSecurityManagerTransactionAbort(driver->securityManager); +- return ret; +-} +- +- + int + qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver, + virDomainObjPtr vm, +diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h +index 89dca61c3a..738c6b2ab7 100644 +--- a/src/qemu/qemu_security.h ++++ b/src/qemu/qemu_security.h +@@ -101,10 +101,6 @@ int qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, + const char *path, + bool allowSubtree); + +-int qemuSecuritySetSavedStateLabel(virQEMUDriverPtr driver, +- virDomainObjPtr vm, +- const char *savefile); +- + int qemuSecurityRestoreSavedStateLabel(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *savefile); +-- +2.33.0 + diff --git a/qemu-Fix-memstat-for-non-transitional-memballoon.patch b/qemu-Fix-memstat-for-non-transitional-memballoon.patch new file mode 100644 index 0000000000000000000000000000000000000000..542f13fc76fa6b1c49556f62e88590344d6d6027 --- /dev/null +++ b/qemu-Fix-memstat-for-non-transitional-memballoon.patch @@ -0,0 +1,55 @@ +From b7993fb89518de145d41a631040900b42cf97858 Mon Sep 17 00:00:00 2001 +From: Andrea Bolognani +Date: Tue, 12 Jan 2021 17:17:44 +0100 +Subject: [PATCH 084/108] qemu: Fix memstat for (non-)transitional memballoon + +Depending on the memballoon model, the corresponding QOM node +will have a different type and we need to account for this +when searching for it in the QOM tree. + +https://bugzilla.redhat.com/show_bug.cgi?id=1911786 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Michal Privoznik +(cherry picked from commit 0a6cb05e953d315b7a05103d707cff4d36221211) +--- + src/qemu/qemu_monitor.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index c98edbd254..8f6261ace2 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1031,7 +1031,27 @@ qemuMonitorInitBalloonObjectPath(qemuMonitorPtr mon, + + switch (balloon->info.type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: +- name = "virtio-balloon-pci"; ++ switch ((virDomainMemballoonModel) balloon->model) { ++ case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO: ++ name = "virtio-balloon-pci"; ++ break; ++ case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_TRANSITIONAL: ++ name = "virtio-balloon-pci-transitional"; ++ break; ++ case VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO_NON_TRANSITIONAL: ++ name = "virtio-balloon-pci-non-transitional"; ++ break; ++ case VIR_DOMAIN_MEMBALLOON_MODEL_XEN: ++ case VIR_DOMAIN_MEMBALLOON_MODEL_NONE: ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("invalid model for virtio-balloon-pci")); ++ return; ++ case VIR_DOMAIN_MEMBALLOON_MODEL_LAST: ++ default: ++ virReportEnumRangeError(virDomainMemballoonModel, ++ balloon->model); ++ return; ++ } + break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + name = "virtio-balloon-ccw"; +-- +2.33.0 + diff --git a/qemu-Use-qemuSecurityDomainSetPathLabel-to-set-secla.patch b/qemu-Use-qemuSecurityDomainSetPathLabel-to-set-secla.patch new file mode 100644 index 0000000000000000000000000000000000000000..acb2c04f6b43ebd89518ec7ae6d431955f7e9f0d --- /dev/null +++ b/qemu-Use-qemuSecurityDomainSetPathLabel-to-set-secla.patch @@ -0,0 +1,49 @@ +From e6b532333a0f7dcd3c1466b941b5ce8317a70d62 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 17 Jun 2020 11:01:05 +0200 +Subject: [PATCH 009/108] qemu: Use qemuSecurityDomainSetPathLabel() to set + seclabes on not saved state files + +There are two places within qemu driver that misuse +qemuSecuritySetSavedStateLabel() to set seclabels on tempfiles +that are not state files: qemuDomainScreenshot() and +qemuDomainMemoryPeek(). They are doing so because of lack of +qemuSecurityDomainSetPathLabel() at the time of their +introduction. + +In all three secdrivers (well, four if you count NOP driver) the +implementation of .domainSetSavedStateLabel and +.domainSetPathLabel callbacks is the same anyway. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 8c6257942425c36e6f6d96629d334fb09a94da28) +--- + src/qemu/qemu_driver.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index e7166e4af3..196b301751 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -4083,7 +4083,7 @@ qemuDomainScreenshot(virDomainPtr dom, + } + unlink_tmp = true; + +- qemuSecuritySetSavedStateLabel(driver, vm, tmp); ++ qemuSecurityDomainSetPathLabel(driver, vm, tmp, false); + + qemuDomainObjEnterMonitor(driver, vm); + if (qemuMonitorScreendump(priv->mon, videoAlias, screen, tmp) < 0) { +@@ -11699,7 +11699,7 @@ qemuDomainMemoryPeek(virDomainPtr dom, + goto endjob; + } + +- qemuSecuritySetSavedStateLabel(driver, vm, tmp); ++ qemuSecurityDomainSetPathLabel(driver, vm, tmp, false); + + priv = vm->privateData; + qemuDomainObjEnterMonitor(driver, vm); +-- +2.33.0 + diff --git a/qemu-avoid-maybe-uninitialized-warning-by-GCC-10.patch b/qemu-avoid-maybe-uninitialized-warning-by-GCC-10.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f0cb2982a138e6781d14403672b467a28818678 --- /dev/null +++ b/qemu-avoid-maybe-uninitialized-warning-by-GCC-10.patch @@ -0,0 +1,41 @@ +From 9175d3c2891632e6497faf6f8320440c4f2bd41d Mon Sep 17 00:00:00 2001 +From: Boris Fiuczynski +Date: Thu, 13 Aug 2020 16:03:44 +0200 +Subject: [PATCH 044/108] qemu: avoid maybe-uninitialized warning by GCC 10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +GCC 10 complains about "well_formed_uri" may be used uninitialzed. +Even though it is a false positive, we can easily avoid it. + +Avoiding + ../src/qemu/qemu_migration.c: In function ‘qemuMigrationDstPrepareDirect’: + ../src/qemu/qemu_migration.c:2920:16: error: ‘well_formed_uri’ may be used uninitialized in this function [-Werror=maybe-uninitialized] + 2920 | if (well_formed_uri) { + | ^ + +Signed-off-by: Boris Fiuczynski +Reviewed-by: Marc Hartmayer +Reviewed-by: Erik Skultety +(cherry picked from commit d96d359a032cda609f9adf3caafdf8425d8aa4ac) +--- + src/qemu/qemu_migration.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 30b92dfb87..32be433e93 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2896,7 +2896,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, + + *uri_out = g_strdup_printf(incFormat, "tcp", hostname, port); + } else { +- bool well_formed_uri; ++ bool well_formed_uri = false; + + if (!(uri = qemuMigrationAnyParseURI(uri_in, &well_formed_uri))) + goto cleanup; +-- +2.33.0 + diff --git a/qemu-blockjob-Transition-into-ready-state-only-from-.patch b/qemu-blockjob-Transition-into-ready-state-only-from-.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f67ec4643929ab930f76d4980d952eaf5603a2a --- /dev/null +++ b/qemu-blockjob-Transition-into-ready-state-only-from-.patch @@ -0,0 +1,105 @@ +From 3fba88d137292cb4468693c932842805ddd13f37 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Tue, 20 Apr 2021 12:58:28 +0200 +Subject: [PATCH 064/108] qemu: blockjob: Transition into 'ready' state only + from expected states + +In certain rare occasions qemu can transition a block job which was +already 'ready' into 'standby' and then back. If this happens in the +following order libvirt will get confused about the actual job state: + +1) the block copy job is 'ready' (job->state == QEMU_BLOCKJOB_STATE_READY) + +2) user calls qemuDomainBlockJobAbort with VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT + flag but without VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC + +3) the block job is switched to synchronous event handling + +4) the block job blips to 'standby' and back to 'ready', the event is + not processed since the blockjob is in sync mode for now + +5) qemuDomainBlockJobPivot is called: + 5.1) 'job-complete' QMP command is issued + 5.2) job->state is set to QEMU_BLOCKJOB_STATE_PIVOTING + +6) code for synchronous-wait for the job completion in qemuDomainBlockJobAbort + is invoked + +7) the waiting loop calls qemuBlockJobUpdate: + + 7.1) job->newstate is QEMU_BLOCKJOB_STATE_READY due to 4) + 7.2) qemuBlockJobEventProcess is called + 7.3) the handler for QEMU_BLOCKJOB_STATE_READY overwrites + job->state from QEMU_BLOCKJOB_STATE_PIVOTING to QEMU_BLOCKJOB_STATE_READY + +8) qemuDomainBlockJobAbort is looking for a finished job, so waits again + +9) qemu finishes the blockjob and transitions it into 'concluded' state + +10) qemuBlockJobUpdate is triggered again, this time finalizing the job. + 10.1) job->newstate is = QEMU_BLOCKJOB_STATE_CONCLUDED + job->state is = QEMU_BLOCKJOB_STATE_READY + 10.2) qemuBlockJobEventProcessConcluded is called, the function + checks whether there was an error with the blockjob. Since + there was no error job->newstate becomes + QEMU_BLOCKJOB_STATE_COMPLETED. + 10.3) qemuBlockJobEventProcessConcludedTransition selects the action + for the appropriate block job type where we have: + + case QEMU_BLOCKJOB_TYPE_COPY: + if (job->state == QEMU_BLOCKJOB_STATE_PIVOTING && success) + qemuBlockJobProcessEventConcludedCopyPivot(driver, vm, job, asyncJob); + else + qemuBlockJobProcessEventConcludedCopyAbort(driver, vm, job, asyncJob); + break; + + Since job->state is QEMU_BLOCKJOB_STATE_READY, + qemuBlockJobProcessEventConcludedCopyAbort is called. + +This patch forbids transitions to QEMU_BLOCKJOB_STATE_READY if the +previous job state isn't QEMU_BLOCKJOB_STATE_RUNNING or +QEMU_BLOCKJOB_STATE_NEW. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1951507 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 81e770c2f152635219cec76585c770fb9f6ce030) +--- + src/qemu/qemu_blockjob.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c +index ea82ce95eb..b4431b54f5 100644 +--- a/src/qemu/qemu_blockjob.c ++++ b/src/qemu/qemu_blockjob.c +@@ -1638,14 +1638,21 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, + break; + + case QEMU_BLOCKJOB_STATE_READY: +- /* mirror may be NULL for copy job corresponding to migration */ +- if (job->disk) { +- job->disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY; +- qemuBlockJobEmitEvents(driver, vm, job->disk, job->type, job->newstate); ++ /* in certain cases qemu can blip out and back into 'ready' state for ++ * a blockjob. In cases when we already are past RUNNING the job such ++ * as when pivoting/aborting this could reset the internally set job ++ * state, thus we ignore it if the job isn't in expected state */ ++ if (job->state == QEMU_BLOCKJOB_STATE_NEW || ++ job->state == QEMU_BLOCKJOB_STATE_RUNNING) { ++ /* mirror may be NULL for copy job corresponding to migration */ ++ if (job->disk) { ++ job->disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY; ++ qemuBlockJobEmitEvents(driver, vm, job->disk, job->type, job->newstate); ++ } ++ job->state = job->newstate; ++ qemuDomainSaveStatus(vm); + } +- job->state = job->newstate; + job->newstate = -1; +- qemuDomainSaveStatus(vm); + break; + + case QEMU_BLOCKJOB_STATE_NEW: +-- +2.33.0 + diff --git a/qemu-don-t-shutdown-event-thread-in-monitor-EOF-call.patch b/qemu-don-t-shutdown-event-thread-in-monitor-EOF-call.patch new file mode 100644 index 0000000000000000000000000000000000000000..56202bacefd59b68a48c4b87337b0eeef6aa4848 --- /dev/null +++ b/qemu-don-t-shutdown-event-thread-in-monitor-EOF-call.patch @@ -0,0 +1,46 @@ +From 30121d9c7797f6bbd60caba5feaeed90b3602cce Mon Sep 17 00:00:00 2001 +From: Nikolay Shirokovskiy +Date: Thu, 23 Jul 2020 10:10:26 +0300 +Subject: [PATCH 011/108] qemu: don't shutdown event thread in monitor EOF + callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This hunk was introduced in [1] in order to avoid loosing +events from monitor on stopping qemu process. But as explained +in [2] on destroy we won't get neither EOF nor any other +events as monitor is just closed. In case of crash/shutdown +we won't get any more events as well and qemuDomainObjStopWorker +will be called by qemuProcessStop eventually. Thus let's +remove qemuDomainObjStopWorker from qemuProcessHandleMonitorEOF +as it is not useful anymore. + +[1] e6afacb0f: qemu: start/stop an event loop thread for domains +[2] d2954c072: qemu: ensure domain event thread is always stopped + +Signed-off-by: Nikolay Shirokovskiy +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 5c0cd375d1d1659ae3a5db0ce3e26e5570123dff) +--- + src/qemu/qemu_process.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 74bb9613bc..890603f66b 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -325,9 +325,6 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon, + qemuDomainDestroyNamespace(driver, vm); + + cleanup: +- /* Now we got EOF we're not expecting more I/O, so we +- * can finally kill the event thread */ +- qemuDomainObjStopWorker(vm); + virObjectUnlock(vm); + } + +-- +2.33.0 + diff --git a/qemu-firmware-check-virJSONValueObjectGet-return-val.patch b/qemu-firmware-check-virJSONValueObjectGet-return-val.patch new file mode 100644 index 0000000000000000000000000000000000000000..3345929a2ddb66ec84f75be8de2f2475e41fbedf --- /dev/null +++ b/qemu-firmware-check-virJSONValueObjectGet-return-val.patch @@ -0,0 +1,46 @@ +From b57ac69c89f0e591e74029f7fded5177fe6452c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 22 Sep 2020 23:22:06 +0200 +Subject: [PATCH 038/108] qemu: firmware: check virJSONValueObjectGet return + value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the mapping is not present, we should not try to +access its elements. + +Signed-off-by: Ján Tomko +Fixes: 8b5b80f4c5f7342eedce0747469223387ab709ef +Reviewed-by: Peter Krempa +(cherry picked from commit 8e12a0b8fac6b9662e5c9e17afdcedb5df944eb0) +--- + src/qemu/qemu_firmware.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index 0d2439bba1..595e93fe19 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -434,10 +434,17 @@ qemuFirmwareMappingParse(const char *path, + virJSONValuePtr doc, + qemuFirmwarePtr fw) + { +- virJSONValuePtr mapping = virJSONValueObjectGet(doc, "mapping"); ++ virJSONValuePtr mapping; + const char *deviceStr; + int tmp; + ++ if (!(mapping = virJSONValueObjectGet(doc, "mapping"))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("missing mapping in '%s'"), ++ path); ++ return -1; ++ } ++ + if (!(deviceStr = virJSONValueObjectGetString(mapping, "device"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing device type in '%s'"), +-- +2.33.0 + diff --git a/qemu-fix-crash-in-qemuDomainSetBlkioParameters-witho.patch b/qemu-fix-crash-in-qemuDomainSetBlkioParameters-witho.patch new file mode 100644 index 0000000000000000000000000000000000000000..74ad8df35366cc0cefd0a2d2ce5150e835d45ea2 --- /dev/null +++ b/qemu-fix-crash-in-qemuDomainSetBlkioParameters-witho.patch @@ -0,0 +1,44 @@ +From a5fc7d4f76779c242d78ecf78317ff68c330b78b Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Tue, 11 Aug 2020 15:56:54 +0200 +Subject: [PATCH 065/108] qemu: fix crash in qemuDomainSetBlkioParameters + without cgroups +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we don't have cgroups available and user tries to update blkio +parameters for running VM it will crash. + +It should have been protected by the virCgroupHasController() check but +it was never called if the API was executed without any flags. + +We call virDomainObjGetDefs() which sets `def` and `persistentDef` based +on the flags and these two variables should be used to figure out if we +need to update LIVE, CONFIG or both states. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1808293 + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit a6886aafacaf25d1ce667ae961264ae1eb69900f) +--- + src/qemu/qemu_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 508d246146..41e9bff17b 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -9380,7 +9380,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, + if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0) + goto endjob; + +- if (flags & VIR_DOMAIN_AFFECT_LIVE) { ++ if (def) { + if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("blkio cgroup isn't mounted")); +-- +2.33.0 + diff --git a/qemu-fix-qemuMigrationSrcCleanup-to-use-qemuMigratio.patch b/qemu-fix-qemuMigrationSrcCleanup-to-use-qemuMigratio.patch new file mode 100644 index 0000000000000000000000000000000000000000..f262bb6bcafd8fc9a9b35dff6b955ba9b4843595 --- /dev/null +++ b/qemu-fix-qemuMigrationSrcCleanup-to-use-qemuMigratio.patch @@ -0,0 +1,43 @@ +From ba60a52c9d6ca7b3729ebf22bb72f6156a02b3b4 Mon Sep 17 00:00:00 2001 +From: Nikolay Shirokovskiy +Date: Tue, 18 Aug 2020 11:01:40 +0300 +Subject: [PATCH 071/108] qemu: fix qemuMigrationSrcCleanup to use + qemuMigrationJobFinish + +qemuMigrationSrcCleanup uses qemuDomainObjDiscardAsyncJob currently. But +discard does not reduce jobs_queued counter so it leaks. Also discard does not +notify other threads that job condition is available. Discard does reset nested +job but nested job is not possible in this conditions. + +Signed-off-by: Nikolay Shirokovskiy +Reviewed-by: Jiri Denemark +(cherry picked from commit 7e34d9a9e076ea0bd550268ad4830f53a8466f3e) +--- + src/qemu/qemu_migration.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 32be433e93..c461156075 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2022,7 +2022,7 @@ qemuMigrationSrcCleanup(virDomainObjPtr vm, + switch ((qemuMigrationJobPhase) priv->job.phase) { + case QEMU_MIGRATION_PHASE_BEGIN3: + /* just forget we were about to migrate */ +- qemuDomainObjDiscardAsyncJob(driver, vm); ++ qemuMigrationJobFinish(driver, vm); + break; + + case QEMU_MIGRATION_PHASE_PERFORM3_DONE: +@@ -2032,7 +2032,7 @@ qemuMigrationSrcCleanup(virDomainObjPtr vm, + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams, priv->job.apiFlags); + /* clear the job and let higher levels decide what to do */ +- qemuDomainObjDiscardAsyncJob(driver, vm); ++ qemuMigrationJobFinish(driver, vm); + break; + + case QEMU_MIGRATION_PHASE_PERFORM3: +-- +2.33.0 + diff --git a/qemu-qemuDomainPMSuspendAgent-Don-t-assign-to-ret-in.patch b/qemu-qemuDomainPMSuspendAgent-Don-t-assign-to-ret-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..4544b924ddb159f2ea8ad1f7a0d2b2f9fecae383 --- /dev/null +++ b/qemu-qemuDomainPMSuspendAgent-Don-t-assign-to-ret-in.patch @@ -0,0 +1,34 @@ +From dadf7e1307010e426a79f5c7133ad4d654f377f6 Mon Sep 17 00:00:00 2001 +From: Erik Skultety +Date: Fri, 11 Sep 2020 14:44:27 +0200 +Subject: [PATCH 028/108] qemu: qemuDomainPMSuspendAgent: Don't assign to 'ret' + in a conditional + +When the guest agent isn't running, we still report success on a PM +suspend action even though we logged an error correctly, this is because +we poisoned the 'ret' value a few lines above. + +Fixes: a663a860819287e041c3de672aad1d8543098ecc + +Signed-off-by: Erik Skultety +(cherry picked from commit 9824a82198d97c40ff0e8f423888a7b9ccf5b301) +--- + src/qemu/qemu_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 7be84c88b2..25ca453d76 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -19893,7 +19893,7 @@ qemuDomainPMSuspendAgent(virQEMUDriverPtr driver, + if (qemuDomainObjBeginAgentJob(driver, vm, QEMU_AGENT_JOB_MODIFY) < 0) + return -1; + +- if ((ret = virDomainObjCheckActive(vm)) < 0) ++ if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (!qemuDomainAgentAvailable(vm, true)) +-- +2.33.0 + diff --git a/qemu-qemuDomainPMSuspendForDuration-Check-availabili.patch b/qemu-qemuDomainPMSuspendForDuration-Check-availabili.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c4bcae4c2a89defc47a6cd7f5a3cd564363aa00 --- /dev/null +++ b/qemu-qemuDomainPMSuspendForDuration-Check-availabili.patch @@ -0,0 +1,37 @@ +From 77e9a026af8db5641ed200cd6d111f2d6901b14f Mon Sep 17 00:00:00 2001 +From: Lin Ma +Date: Fri, 11 Sep 2020 15:06:08 +0800 +Subject: [PATCH 039/108] qemu: qemuDomainPMSuspendForDuration: Check + availability of agent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It requires a guest agent configured and running in the domain's guest +OS, So check qemu agent during qemuDomainPMSuspendForDuration(). + +Signed-off-by: Lin Ma +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +(cherry picked from commit 308ec831bb153e69035850e0a45346fb417da913) +--- + src/qemu/qemu_driver.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 25ca453d76..e53ba2bc93 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -19943,6 +19943,9 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom, + if (virDomainPMSuspendForDurationEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + ++ if (!qemuDomainAgentAvailable(vm, true)) ++ goto cleanup; ++ + /* + * The case we want to handle here is when QEMU has the API (i.e. + * QEMU_CAPS_QUERY_CURRENT_MACHINE is set). Otherwise, do not interfere +-- +2.33.0 + diff --git a/qemu-snapshot-Collect-query-named-block-nodes-prior-.patch b/qemu-snapshot-Collect-query-named-block-nodes-prior-.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7fb39407dfccd90973e9098fb26bc544bc51c09 --- /dev/null +++ b/qemu-snapshot-Collect-query-named-block-nodes-prior-.patch @@ -0,0 +1,94 @@ +From 4187eb187649c95038325b39a5132c578d8ab820 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Fri, 31 Jul 2020 15:23:56 +0200 +Subject: [PATCH 041/108] qemu: snapshot: Collect 'query-named-block-nodes' + prior to memory migration + +When doing an external snapshot we migrate memory to a file as a form of +taking the memory state. This creates a problem as qemu deactivates all +active bitmaps after a successful migration. This means that calling +'query-named-block-nodes' will return an empty list of bitmaps for +devices. We use the bitmap list to propagate the active bitmaps into the +overlay files being created which is required for backups to work after +a snapshot. Since we wouldn't propagate anything a subsequent backup +will fail with: + +invalid argument: missing or broken bitmap 'testchck' for disk 'vda' + +To fix this, we can simply collect the bitmap list prior to the +migration. + +https://bugzilla.redhat.com/show_bug.cgi?id=1862472 + +Signed-off-by: Peter Krempa +Reviewed-by: Eric Blake +(cherry picked from commit 00bb850eb065eca0c65dda212c039bc76774453f) +--- + src/qemu/qemu_driver.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index e53ba2bc93..508d246146 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -15416,6 +15416,7 @@ static int + qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainMomentObjPtr snap, ++ virHashTablePtr blockNamedNodeData, + unsigned int flags, + virQEMUDriverConfigPtr cfg, + qemuDomainAsyncJob asyncJob) +@@ -15429,17 +15430,12 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, + qemuDomainSnapshotDiskDataPtr diskdata = NULL; + size_t ndiskdata = 0; + bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV); +- g_autoptr(virHashTable) blockNamedNodeData = NULL; + + if (virDomainObjCheckActive(vm) < 0) + return -1; + + actions = virJSONValueNewArray(); + +- if (blockdev && +- !(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob))) +- return -1; +- + /* prepare a list of objects to use in the vm definition so that we don't + * have to roll back later */ + if (qemuDomainSnapshotDiskPrepare(driver, vm, snap, cfg, reuse, blockdev, +@@ -15506,6 +15502,7 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver, + int compressed; + g_autoptr(virCommand) compressor = NULL; + virQEMUSaveDataPtr data = NULL; ++ g_autoptr(virHashTable) blockNamedNodeData = NULL; + + /* If quiesce was requested, then issue a freeze command, and a + * counterpart thaw command when it is actually sent to agent. +@@ -15560,6 +15557,13 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver, + } + } + ++ /* We need to collect reply from 'query-named-block-nodes' prior to the ++ * migration step as qemu deactivates bitmaps after migration so the result ++ * would be wrong */ ++ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV) && ++ !(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_SNAPSHOT))) ++ goto cleanup; ++ + /* do the memory snapshot if necessary */ + if (memory) { + /* check if migration is possible */ +@@ -15604,7 +15608,8 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver, + + /* the domain is now paused if a memory snapshot was requested */ + +- if ((ret = qemuDomainSnapshotCreateDiskActive(driver, vm, snap, flags, cfg, ++ if ((ret = qemuDomainSnapshotCreateDiskActive(driver, vm, snap, ++ blockNamedNodeData, flags, cfg, + QEMU_ASYNC_JOB_SNAPSHOT)) < 0) + goto cleanup; + +-- +2.33.0 + diff --git a/qemuBlockJobEventProcess-Always-clear-mirrorState-wh.patch b/qemuBlockJobEventProcess-Always-clear-mirrorState-wh.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b79936eb43453d08679643fdf75219326f84091 --- /dev/null +++ b/qemuBlockJobEventProcess-Always-clear-mirrorState-wh.patch @@ -0,0 +1,38 @@ +From 7f41d4ce90e7bdb26388a8ce98c20a229acc5cc9 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 11 Jan 2021 10:42:15 +0100 +Subject: [PATCH 083/108] qemuBlockJobEventProcess: Always clear 'mirrorState' + when a job finishes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a block job is terminated we should clear the 'mirrorState' and +'mirrorJob' variables so that stale values are not present prior to a +new job. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 202d61db4870468a02817e64fefb5ede06b8a59a) +--- + src/qemu/qemu_blockjob.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c +index b4431b54f5..bac064b53a 100644 +--- a/src/qemu/qemu_blockjob.c ++++ b/src/qemu/qemu_blockjob.c +@@ -1634,6 +1634,10 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, + case QEMU_BLOCKJOB_STATE_FAILED: + case QEMU_BLOCKJOB_STATE_CANCELLED: + case QEMU_BLOCKJOB_STATE_CONCLUDED: ++ if (job->disk) { ++ job->disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE; ++ job->disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN; ++ } + qemuBlockJobEventProcessConcluded(job, driver, vm, asyncJob); + break; + +-- +2.33.0 + diff --git a/qemuBlockJobProcessEventCompletedPull-Add-backingSto.patch b/qemuBlockJobProcessEventCompletedPull-Add-backingSto.patch new file mode 100644 index 0000000000000000000000000000000000000000..9113a4b4286e1b62e2ad7c221b60f60b89061182 --- /dev/null +++ b/qemuBlockJobProcessEventCompletedPull-Add-backingSto.patch @@ -0,0 +1,69 @@ +From 6c7c9aab6d5dd9fd836e19990bb63d5ef47871c2 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 12 Apr 2021 17:42:23 +0200 +Subject: [PATCH 058/108] qemuBlockJobProcessEventCompletedPull: Add + backingStore terminators if base is NULL + +When doing a blockpull with NULL base the full contents of the disk are +pulled into the topmost image which then becomes fully self-contained. + +qemuBlockJobProcessEventCompletedPull doesn't install the backing chain +terminators though, although it's guaranteed that there will be no +backing chain behind disk->src. + +Add the terminators for completness and for disabling backing chain +detection on further boots. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit b4d020790642fa4d7b8a6783b81d5d9d73cbe3d9) +--- + src/qemu/qemu_blockjob.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c +index 049afdd71a..ea82ce95eb 100644 +--- a/src/qemu/qemu_blockjob.c ++++ b/src/qemu/qemu_blockjob.c +@@ -958,6 +958,7 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, + qemuBlockJobDataPtr job, + qemuDomainAsyncJob asyncJob) + { ++ virStorageSource *base = NULL; + virStorageSourcePtr baseparent = NULL; + virDomainDiskDefPtr cfgdisk = NULL; + virStorageSourcePtr cfgbase = NULL; +@@ -979,8 +980,11 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, + return; + + if (job->data.pull.base) { ++ base = job->data.pull.base; ++ + if (cfgdisk) + cfgbase = cfgdisk->src->backingStore; ++ + for (n = job->disk->src->backingStore; n && n != job->data.pull.base; n = n->backingStore) { + /* find the image on top of 'base' */ + +@@ -991,10 +995,17 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, + + baseparent = n; + } ++ } else { ++ /* create terminators for the chain; since we are pulling everything ++ * into the top image the chain is automatically considered terminated */ ++ base = virStorageSourceNew(); ++ ++ if (cfgdisk) ++ cfgbase = virStorageSourceNew(); + } + + tmp = job->disk->src->backingStore; +- job->disk->src->backingStore = job->data.pull.base; ++ job->disk->src->backingStore = base; + if (baseparent) + baseparent->backingStore = NULL; + qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, tmp); +-- +2.33.0 + diff --git a/qemuBlockJobProcessEventCompletedPull-Avoid-dangling.patch b/qemuBlockJobProcessEventCompletedPull-Avoid-dangling.patch new file mode 100644 index 0000000000000000000000000000000000000000..a3c5104f387f0aee75601f310515982792b079b0 --- /dev/null +++ b/qemuBlockJobProcessEventCompletedPull-Avoid-dangling.patch @@ -0,0 +1,58 @@ +From 86bc1ce2b3518c375eaba5d838709af8f52c4165 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 12 Apr 2021 17:24:22 +0200 +Subject: [PATCH 057/108] qemuBlockJobProcessEventCompletedPull: Avoid dangling + pointer after blockpull + +When doing a full block pull job (base == NULL) and the config XML +contains a compatible disk, the completer function would leave a +dangling pointer in 'cfgdisk->src->backingStore' as cfgdisk->src would +be set to the value of 'cfgbase' which was always set to +'cfgdisk->src->backingStore'. + +This is wrong though since for the live definition XML we set the +respective counterpart to 'job->data.pull.base' which is NULL in the +above scenario. + +This leads to a invalid pointer read when saving the config XML and may +end up in a crash. + +Resolve it by setting 'cfgbase' only when 'job->data.pull.base' is +non-NULL. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1946918 +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 46e748aa02cbd5923fa4b500352f528de35dc665) +--- + src/qemu/qemu_blockjob.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c +index 21a043d369..049afdd71a 100644 +--- a/src/qemu/qemu_blockjob.c ++++ b/src/qemu/qemu_blockjob.c +@@ -971,10 +971,7 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, + if (!job->disk) + return; + +- if ((cfgdisk = qemuBlockJobGetConfigDisk(vm, job->disk, job->data.pull.base))) +- cfgbase = cfgdisk->src->backingStore; +- +- if (!cfgdisk) ++ if (!(cfgdisk = qemuBlockJobGetConfigDisk(vm, job->disk, job->data.pull.base))) + qemuBlockJobClearConfigChain(vm, job->disk); + + /* when pulling if 'base' is right below the top image we don't have to modify it */ +@@ -982,6 +979,8 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, + return; + + if (job->data.pull.base) { ++ if (cfgdisk) ++ cfgbase = cfgdisk->src->backingStore; + for (n = job->disk->src->backingStore; n && n != job->data.pull.base; n = n->backingStore) { + /* find the image on top of 'base' */ + +-- +2.33.0 + diff --git a/qemuDomainCheckpointLoad-Don-t-align-disks-when-rest.patch b/qemuDomainCheckpointLoad-Don-t-align-disks-when-rest.patch new file mode 100644 index 0000000000000000000000000000000000000000..c57589283a04e7e37328aebf703de97e463a01d5 --- /dev/null +++ b/qemuDomainCheckpointLoad-Don-t-align-disks-when-rest.patch @@ -0,0 +1,51 @@ +From cbf2d9410c289757cc0607ece2aafd5ea8e6c219 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Tue, 8 Dec 2020 16:16:08 +0100 +Subject: [PATCH 023/108] qemuDomainCheckpointLoad: Don't align disks when + restoring config from disk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The alignment step is not really necessary once we've done it already +since we fully populate the definition. In case of checkpoints it was a +relic necessary for populating the 'idx' to match checkpoint disk to +definition disk, but that was already removed. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit f40a72a32e47c248d5002a765913fa8f547960de) +--- + src/qemu/qemu_driver.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 196b301751..7be84c88b2 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -539,18 +539,11 @@ qemuDomainCheckpointLoad(virDomainObjPtr vm, + continue; + } + +- def = virDomainCheckpointDefParseString(xmlStr, +- qemu_driver->xmlopt, +- priv->qemuCaps, +- flags); +- if (!def || virDomainCheckpointAlignDisks(def) < 0) { +- /* Nothing we can do here, skip this one */ +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Failed to parse checkpoint XML from file '%s'"), +- fullpath); +- virObjectUnref(def); ++ if (!(def = virDomainCheckpointDefParseString(xmlStr, ++ qemu_driver->xmlopt, ++ priv->qemuCaps, ++ flags))) + continue; +- } + + chk = virDomainCheckpointAssignDef(vm->checkpoints, def); + if (chk == NULL) +-- +2.33.0 + diff --git a/qemuFirmwareFillDomain-Fill-NVRAM-template-on-migrat.patch b/qemuFirmwareFillDomain-Fill-NVRAM-template-on-migrat.patch new file mode 100644 index 0000000000000000000000000000000000000000..56ef0d3b885e2fde236505282dd14d2943857ef2 --- /dev/null +++ b/qemuFirmwareFillDomain-Fill-NVRAM-template-on-migrat.patch @@ -0,0 +1,63 @@ +From 44943efe8465f60315d3fb54a935d1ea190ee4fb Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 8 Sep 2020 17:42:09 +0200 +Subject: [PATCH 026/108] qemuFirmwareFillDomain: Fill NVRAM template on + migration too + +In 8e1804f9f66 I've tried to fix the following use case: domain +is started with path to UEFI only and relies on libvirt to figure +out corresponding NVRAM template to create a per-domain copy +from. The fix consisted of having a check tailored exactly for +this use case and if it's hit then using FW autoselection to +figure it out. Unfortunately, the NVRAM template is not saved in +the inactive XML (well, the domain might be transient anyway). +Then, as a part of that check we see whether the per-domain copy +doesn't exist already and if it does then no template is looked +up hence no template will appear in the live XML. + +This works, until the domain is migrated. At the destination, the +per-domain copy will not exist so we need to know the template to +create the per-domain copy from. But we don't even get to the +check because we are not starting a fresh new domain and thus the +qemuFirmwareFillDomain() function quits early. + +The solution is to switch order of these two checks. That is +evaluate the check for the old style before checking flags. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852910 +Signed-off-by: Michal Privoznik +Reviewed-by: Andrea Bolognani +(cherry picked from commit c43622f06e295edcb9cedf33583f0bd18fb04b10) +--- + src/qemu/qemu_firmware.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index bd251c05fc..0d2439bba1 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -1229,9 +1229,6 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver, + size_t i; + int ret = -1; + +- if (!(flags & VIR_QEMU_PROCESS_START_NEW)) +- return 0; +- + /* Fill in FW paths if either os.firmware is enabled, or + * loader path was provided with no nvram varstore. */ + if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { +@@ -1247,6 +1244,11 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver, + /* ... then we want to consult JSON FW descriptors first, + * but we don't want to fail if we haven't found a match. */ + needResult = false; ++ } else { ++ /* Domain has FW autoselection enabled => do nothing if ++ * we are not starting it from scratch. */ ++ if (!(flags & VIR_QEMU_PROCESS_START_NEW)) ++ return 0; + } + + if ((nfirmwares = qemuFirmwareFetchParsedConfigs(driver->privileged, +-- +2.33.0 + diff --git a/qemuMigrationSrcNBDStorageCopyReady-Use-ready-state-.patch b/qemuMigrationSrcNBDStorageCopyReady-Use-ready-state-.patch new file mode 100644 index 0000000000000000000000000000000000000000..6343e2777357763594a98ef5627beef4a23e8007 --- /dev/null +++ b/qemuMigrationSrcNBDStorageCopyReady-Use-ready-state-.patch @@ -0,0 +1,46 @@ +From b82b8815939b3704f28ece92d056e68eac92ab28 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 11 Jan 2021 10:40:43 +0100 +Subject: [PATCH 082/108] qemuMigrationSrcNBDStorageCopyReady: Use ready-state + of mirror from qemuBlockJobData +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use the per-job state to determine when the non-shared-storage mirror is +complete rather than the per-disk definition one. The qemuBlockJobData +is a newer approach and is always cleared after the blockjob is +terminated while the 'mirrorState' variable in the definition of the +disk may be left over. In such case the disk mirror would be considered +complete prematurely. + +https://bugzilla.redhat.com/show_bug.cgi?id=1889131 + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit a09c421e3e5969582ed0a5cf9a132ecbfd9794d2) +--- + src/qemu/qemu_migration.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index c461156075..d86325881e 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -539,10 +539,10 @@ qemuMigrationSrcNBDStorageCopyReady(virDomainObjPtr vm, + return -1; + } + +- virObjectUnref(job); +- +- if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY) ++ if (job->state != VIR_DOMAIN_BLOCK_JOB_READY) + notReady++; ++ ++ virObjectUnref(job); + } + + if (notReady) { +-- +2.33.0 + diff --git a/qemuMigrationSrcRun-Don-t-jump-to-exit_monitor-from-.patch b/qemuMigrationSrcRun-Don-t-jump-to-exit_monitor-from-.patch new file mode 100644 index 0000000000000000000000000000000000000000..41b196983c6d81c3b1e9e390ada348a94ceb8f99 --- /dev/null +++ b/qemuMigrationSrcRun-Don-t-jump-to-exit_monitor-from-.patch @@ -0,0 +1,32 @@ +From 2885ef9779a57a964b5d9212702ec06d0ba5573b Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 1 Mar 2021 14:52:03 +0100 +Subject: [PATCH 019/108] qemuMigrationSrcRun: Don't jump to 'exit_monitor' + from outside of the monitor + +Failure of 'qemuMigrationSetDBusVMState' would jump to 'exit_monitor' +but the function isn't called inside of the monitor context. + +Signed-off-by: Peter Krempa +Reviewed-by: Jiri Denemark +(cherry picked from commit 568d7358ab2c106cefc7b42cd80fb9155d4bb72a) +--- + src/qemu/qemu_migration.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index cd40a886e3..30b92dfb87 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -3637,7 +3637,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, + } + + if (qemuMigrationSetDBusVMState(driver, vm) < 0) +- goto exit_monitor; ++ goto error; + + /* Before EnterMonitor, since already qemuProcessStopCPUs does that */ + if (!(flags & VIR_MIGRATE_LIVE) && +-- +2.33.0 + diff --git a/qemuOpenFileAs-Move-into-util-virqemu.c.patch b/qemuOpenFileAs-Move-into-util-virqemu.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..dca1f1971001de903197a6407a26d38969431030 --- /dev/null +++ b/qemuOpenFileAs-Move-into-util-virqemu.c.patch @@ -0,0 +1,366 @@ +From 0e2911af2a1d9022c3ad9eeb9df78a27bf35474e Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 16 Jul 2020 10:51:21 +0200 +Subject: [PATCH 093/108] qemuOpenFileAs: Move into util/virqemu.c + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 43620689794507308fbd3def6992a68ee2f8fa97) +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_driver.c | 138 ++------------------------------------- + src/util/virqemu.c | 130 ++++++++++++++++++++++++++++++++++++ + src/util/virqemu.h | 7 ++ + 4 files changed, 144 insertions(+), 132 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 4d54c5e42f..14ad7ecde3 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2906,6 +2906,7 @@ virQEMUBuildCommandLineJSONArrayNumbered; + virQEMUBuildDriveCommandlineFromJSON; + virQEMUBuildNetdevCommandlineFromJSON; + virQEMUBuildQemuImgKeySecretOpts; ++virQEMUFileOpenAs; + + + # util/virrandom.h +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 5f6543d8e8..13fc6e034d 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -148,11 +148,6 @@ static int qemuDomainObjStart(virConnectPtr conn, + static int qemuDomainManagedSaveLoad(virDomainObjPtr vm, + void *opaque); + +-static int qemuOpenFileAs(uid_t fallback_uid, gid_t fallback_gid, +- bool dynamicOwnership, +- const char *path, int oflags, +- bool *needUnlink); +- + static virQEMUDriverPtr qemu_driver; + + /* Looks up the domain object from snapshot and unlocks the +@@ -3066,129 +3061,8 @@ qemuOpenFile(virQEMUDriverPtr driver, + (virParseOwnershipIds(seclabel->label, &user, &group) < 0)) + return -1; + +- return qemuOpenFileAs(user, group, dynamicOwnership, +- path, oflags, needUnlink); +-} +- +-static int +-qemuOpenFileAs(uid_t fallback_uid, gid_t fallback_gid, +- bool dynamicOwnership, +- const char *path, int oflags, +- bool *needUnlink) +-{ +- struct stat sb; +- bool is_reg = true; +- bool need_unlink = false; +- unsigned int vfoflags = 0; +- int fd = -1; +- int path_shared = virFileIsSharedFS(path); +- uid_t uid = geteuid(); +- gid_t gid = getegid(); +- +- /* path might be a pre-existing block dev, in which case +- * we need to skip the create step, and also avoid unlink +- * in the failure case */ +- if (oflags & O_CREAT) { +- need_unlink = true; +- +- /* Don't force chown on network-shared FS +- * as it is likely to fail. */ +- if (path_shared <= 0 || dynamicOwnership) +- vfoflags |= VIR_FILE_OPEN_FORCE_OWNER; +- +- if (stat(path, &sb) == 0) { +- /* It already exists, we don't want to delete it on error */ +- need_unlink = false; +- +- is_reg = !!S_ISREG(sb.st_mode); +- /* If the path is regular file which exists +- * already and dynamic_ownership is off, we don't +- * want to change its ownership, just open it as-is */ +- if (is_reg && !dynamicOwnership) { +- uid = sb.st_uid; +- gid = sb.st_gid; +- } +- } +- } +- +- /* First try creating the file as root */ +- if (!is_reg) { +- if ((fd = open(path, oflags & ~O_CREAT)) < 0) { +- fd = -errno; +- goto error; +- } +- } else { +- if ((fd = virFileOpenAs(path, oflags, S_IRUSR | S_IWUSR, uid, gid, +- vfoflags | VIR_FILE_OPEN_NOFORK)) < 0) { +- /* If we failed as root, and the error was permission-denied +- (EACCES or EPERM), assume it's on a network-connected share +- where root access is restricted (eg, root-squashed NFS). If the +- qemu user is non-root, just set a flag to +- bypass security driver shenanigans, and retry the operation +- after doing setuid to qemu user */ +- if ((fd != -EACCES && fd != -EPERM) || fallback_uid == geteuid()) +- goto error; +- +- /* On Linux we can also verify the FS-type of the directory. */ +- switch (path_shared) { +- case 1: +- /* it was on a network share, so we'll continue +- * as outlined above +- */ +- break; +- +- case -1: +- virReportSystemError(-fd, oflags & O_CREAT +- ? _("Failed to create file " +- "'%s': couldn't determine fs type") +- : _("Failed to open file " +- "'%s': couldn't determine fs type"), +- path); +- goto cleanup; +- +- case 0: +- default: +- /* local file - log the error returned by virFileOpenAs */ +- goto error; +- } +- +- /* If we created the file above, then we need to remove it; +- * otherwise, the next attempt to create will fail. If the +- * file had already existed before we got here, then we also +- * don't want to delete it and allow the following to succeed +- * or fail based on existing protections +- */ +- if (need_unlink) +- unlink(path); +- +- /* Retry creating the file as qemu user */ +- +- /* Since we're passing different modes... */ +- vfoflags |= VIR_FILE_OPEN_FORCE_MODE; +- +- if ((fd = virFileOpenAs(path, oflags, +- S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, +- fallback_uid, fallback_gid, +- vfoflags | VIR_FILE_OPEN_FORK)) < 0) { +- virReportSystemError(-fd, oflags & O_CREAT +- ? _("Error from child process creating '%s'") +- : _("Error from child process opening '%s'"), +- path); +- goto cleanup; +- } +- } +- } +- cleanup: +- if (needUnlink) +- *needUnlink = need_unlink; +- return fd; +- +- error: +- virReportSystemError(-fd, oflags & O_CREAT +- ? _("Failed to create file '%s'") +- : _("Failed to open file '%s'"), +- path); +- goto cleanup; ++ return virQEMUFileOpenAs(user, group, dynamicOwnership, ++ path, oflags, needUnlink); + } + + +@@ -3251,9 +3125,9 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver, + } + } + +- fd = qemuOpenFileAs(cfg->user, cfg->group, false, path, +- O_WRONLY | O_TRUNC | O_CREAT | directFlag, +- &needUnlink); ++ fd = virQEMUFileOpenAs(cfg->user, cfg->group, false, path, ++ O_WRONLY | O_TRUNC | O_CREAT | directFlag, ++ &needUnlink); + if (fd < 0) + goto cleanup; + +@@ -3829,7 +3703,7 @@ doCoreDump(virQEMUDriverPtr driver, + /* Core dumps usually imply last-ditch analysis efforts are + * desired, so we intentionally do not unlink even if a file was + * created. */ +- if ((fd = qemuOpenFileAs(cfg->user, cfg->group, false, path, ++ if ((fd = virQEMUFileOpenAs(cfg->user, cfg->group, false, path, + O_CREAT | O_TRUNC | O_WRONLY | directFlag, + NULL)) < 0) + goto cleanup; +diff --git a/src/util/virqemu.c b/src/util/virqemu.c +index c331443b00..6afafa9c3c 100644 +--- a/src/util/virqemu.c ++++ b/src/util/virqemu.c +@@ -22,12 +22,18 @@ + + #include + ++#include ++#include ++#include ++#include ++ + #include "virbuffer.h" + #include "virerror.h" + #include "virlog.h" + #include "virqemu.h" + #include "virstring.h" + #include "viralloc.h" ++#include "virfile.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -408,3 +414,127 @@ virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf, + virBufferAddLit(buf, ","); + } + } ++ ++ ++int ++virQEMUFileOpenAs(uid_t fallback_uid, ++ gid_t fallback_gid, ++ bool dynamicOwnership, ++ const char *path, ++ int oflags, ++ bool *needUnlink) ++{ ++ struct stat sb; ++ bool is_reg = true; ++ bool need_unlink = false; ++ unsigned int vfoflags = 0; ++ int fd = -1; ++ int path_shared = virFileIsSharedFS(path); ++ uid_t uid = geteuid(); ++ gid_t gid = getegid(); ++ ++ /* path might be a pre-existing block dev, in which case ++ * we need to skip the create step, and also avoid unlink ++ * in the failure case */ ++ if (oflags & O_CREAT) { ++ need_unlink = true; ++ ++ /* Don't force chown on network-shared FS ++ * as it is likely to fail. */ ++ if (path_shared <= 0 || dynamicOwnership) ++ vfoflags |= VIR_FILE_OPEN_FORCE_OWNER; ++ ++ if (stat(path, &sb) == 0) { ++ /* It already exists, we don't want to delete it on error */ ++ need_unlink = false; ++ ++ is_reg = !!S_ISREG(sb.st_mode); ++ /* If the path is regular file which exists ++ * already and dynamic_ownership is off, we don't ++ * want to change its ownership, just open it as-is */ ++ if (is_reg && !dynamicOwnership) { ++ uid = sb.st_uid; ++ gid = sb.st_gid; ++ } ++ } ++ } ++ ++ /* First try creating the file as root */ ++ if (!is_reg) { ++ if ((fd = open(path, oflags & ~O_CREAT)) < 0) { ++ fd = -errno; ++ goto error; ++ } ++ } else { ++ if ((fd = virFileOpenAs(path, oflags, S_IRUSR | S_IWUSR, uid, gid, ++ vfoflags | VIR_FILE_OPEN_NOFORK)) < 0) { ++ /* If we failed as root, and the error was permission-denied ++ (EACCES or EPERM), assume it's on a network-connected share ++ where root access is restricted (eg, root-squashed NFS). If the ++ qemu user is non-root, just set a flag to ++ bypass security driver shenanigans, and retry the operation ++ after doing setuid to qemu user */ ++ if ((fd != -EACCES && fd != -EPERM) || fallback_uid == geteuid()) ++ goto error; ++ ++ /* On Linux we can also verify the FS-type of the directory. */ ++ switch (path_shared) { ++ case 1: ++ /* it was on a network share, so we'll continue ++ * as outlined above ++ */ ++ break; ++ ++ case -1: ++ virReportSystemError(-fd, oflags & O_CREAT ++ ? _("Failed to create file " ++ "'%s': couldn't determine fs type") ++ : _("Failed to open file " ++ "'%s': couldn't determine fs type"), ++ path); ++ goto cleanup; ++ ++ case 0: ++ default: ++ /* local file - log the error returned by virFileOpenAs */ ++ goto error; ++ } ++ ++ /* If we created the file above, then we need to remove it; ++ * otherwise, the next attempt to create will fail. If the ++ * file had already existed before we got here, then we also ++ * don't want to delete it and allow the following to succeed ++ * or fail based on existing protections ++ */ ++ if (need_unlink) ++ unlink(path); ++ ++ /* Retry creating the file as qemu user */ ++ ++ /* Since we're passing different modes... */ ++ vfoflags |= VIR_FILE_OPEN_FORCE_MODE; ++ ++ if ((fd = virFileOpenAs(path, oflags, ++ S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, ++ fallback_uid, fallback_gid, ++ vfoflags | VIR_FILE_OPEN_FORK)) < 0) { ++ virReportSystemError(-fd, oflags & O_CREAT ++ ? _("Error from child process creating '%s'") ++ : _("Error from child process opening '%s'"), ++ path); ++ goto cleanup; ++ } ++ } ++ } ++ cleanup: ++ if (needUnlink) ++ *needUnlink = need_unlink; ++ return fd; ++ ++ error: ++ virReportSystemError(-fd, oflags & O_CREAT ++ ? _("Failed to create file '%s'") ++ : _("Failed to open file '%s'"), ++ path); ++ goto cleanup; ++} +diff --git a/src/util/virqemu.h b/src/util/virqemu.h +index 963ca03576..b545598e2c 100644 +--- a/src/util/virqemu.h ++++ b/src/util/virqemu.h +@@ -60,3 +60,10 @@ void virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf, + virStorageEncryptionInfoDefPtr enc, + const char *alias) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ++ ++int virQEMUFileOpenAs(uid_t fallback_uid, ++ gid_t fallback_gid, ++ bool dynamicOwnership, ++ const char *path, ++ int oflags, ++ bool *needUnlink); +-- +2.33.0 + diff --git a/qemu_agent-Rework-domain-object-locking-when-opening.patch b/qemu_agent-Rework-domain-object-locking-when-opening.patch new file mode 100644 index 0000000000000000000000000000000000000000..4de850ad281b24385ea9e71e1d89f20b952d2458 --- /dev/null +++ b/qemu_agent-Rework-domain-object-locking-when-opening.patch @@ -0,0 +1,67 @@ +From 72585ff4f5b94de910b27ff22780aa1736d1770e Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 27 Oct 2021 13:38:05 +0200 +Subject: [PATCH 103/108] qemu_agent: Rework domain object locking when opening + agent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Just like qemuMonitorOpen(), hold the domain object locked +throughout the whole time of qemuConnectAgent() and unlock it +only for a brief time of actual connect() (because this is the +only part that has a potential of blocking). + +The reason is that qemuAgentOpen() does access domain object +(well, its privateData) AND also at least one argument (@context) +depends on domain object. Accessing these without the lock is +potentially dangerous. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1845468#c12 +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 108e131a3df529ff4e0f3a33a30b37cea7a62e26) +--- + src/qemu/qemu_agent.c | 3 +++ + src/qemu/qemu_process.c | 4 ---- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index 31d3268d42..1cd745c88e 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -709,7 +709,10 @@ qemuAgentOpen(virDomainObjPtr vm, + goto cleanup; + } + ++ virObjectUnlock(vm); + agent->fd = qemuAgentOpenUnix(config->data.nix.path); ++ virObjectLock(vm); ++ + if (agent->fd == -1) + goto cleanup; + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index bf5375bcde..360c4fcbb1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -234,16 +234,12 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm) + * deleted while the agent is active */ + virObjectRef(vm); + +- virObjectUnlock(vm); +- + agent = qemuAgentOpen(vm, + config->source, + virEventThreadGetContext(priv->eventThread), + &agentCallbacks, + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE)); + +- virObjectLock(vm); +- + if (agent == NULL) + virObjectUnref(vm); + +-- +2.33.0 + diff --git a/qemu_capabilities-Don-t-leak-str-in-virQEMUCapsLoadM.patch b/qemu_capabilities-Don-t-leak-str-in-virQEMUCapsLoadM.patch new file mode 100644 index 0000000000000000000000000000000000000000..01383ee73080b12a1dab1676130c545fd1b167fe --- /dev/null +++ b/qemu_capabilities-Don-t-leak-str-in-virQEMUCapsLoadM.patch @@ -0,0 +1,48 @@ +From 0069becf07a5a9751b5ee202af928e4398c7fca9 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 9 Feb 2021 16:29:39 +0100 +Subject: [PATCH 088/108] qemu_capabilities: Don't leak @str in + virQEMUCapsLoadMachines() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If parsing "maxCpus" attribute of element fails an +error is printed but the corresponding string is not freed. While +it is very unlikely to happen (parsed XML is not user provided +and we are the ones generating it), it is possible. Instead of +freeing the variable in the error path explicitly, let's declare +it as g_autofree. And while I'm at it, let's bring it into the +loop where it's used. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 71609477a21c100d7ce6ef00c97c11093f3405bc) +--- + src/qemu/qemu_capabilities.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 2931d0c190..790b67add3 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3936,7 +3936,6 @@ virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps, + { + g_autofree char *xpath = g_strdup_printf("./machine[@type='%s']", typeStr); + g_autofree xmlNodePtr *nodes = NULL; +- char *str = NULL; + size_t i; + int n; + +@@ -3954,6 +3953,8 @@ virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps, + return -1; + + for (i = 0; i < n; i++) { ++ g_autofree char *str = NULL; ++ + if (!(caps->machineTypes[i].name = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing machine name in QEMU capabilities cache")); +-- +2.33.0 + diff --git a/qemu_conf-Fix-double-free-problem-for-cfg-firmwares.patch b/qemu_conf-Fix-double-free-problem-for-cfg-firmwares.patch new file mode 100644 index 0000000000000000000000000000000000000000..981acc4e6af64b2d67d035b9d62974b8941cc61a --- /dev/null +++ b/qemu_conf-Fix-double-free-problem-for-cfg-firmwares.patch @@ -0,0 +1,37 @@ +From e3a594f1a3914d545d51413801516e9d75450fa6 Mon Sep 17 00:00:00 2001 +From: Tuguoyi +Date: Tue, 24 Nov 2020 03:12:00 +0000 +Subject: [PATCH 022/108] qemu_conf: Fix double free problem for cfg->firmwares +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cfg->firmwares still points to the original memory address after being +freed by virFirmwareFreeList(). As cfg get freed, it will be freed again +even if cfg->nfirmwares=0 which eventually lead to crash. + +The patch fix it by setting cfg->firmwares to NULL explicitly after +virFirmwareFreeList() returns + +Signed-off-by: Guoyi Tu +Reviewed-by: Ján Tomko +(cherry picked from commit c4f4e195a14c86b7daff2c45f1cbfd23ac16aaa8) +--- + src/qemu/qemu_conf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index bd96ccb78e..da2a1bdfe4 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -811,6 +811,7 @@ virQEMUDriverConfigLoadNVRAMEntry(virQEMUDriverConfigPtr cfg, + VIR_AUTOSTRINGLIST fwList = NULL; + + virFirmwareFreeList(cfg->firmwares, cfg->nfirmwares); ++ cfg->firmwares = NULL; + + if (qemuFirmwareFetchConfigs(&fwList, privileged) < 0) + return -1; +-- +2.33.0 + diff --git a/qemu_driver-increase-recorded-counter-for-disk-block.patch b/qemu_driver-increase-recorded-counter-for-disk-block.patch new file mode 100644 index 0000000000000000000000000000000000000000..89da739d8ed792a45da40fc342a4f2ea9efe8075 --- /dev/null +++ b/qemu_driver-increase-recorded-counter-for-disk-block.patch @@ -0,0 +1,41 @@ +From e50bf97d633e467750cae0f573bd1d1b398c8bc0 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Wed, 3 Feb 2021 16:28:40 +0100 +Subject: [PATCH 087/108] qemu_driver: increase recorded counter for disk block + stats + +Commit <318d807a0bd3372b634d1952b559c5c627ccfa5b> added a fix to skip +most of the block stat code to not log error message for missing storage +sources but forgot to increase the recordnr counter. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 02ffd9909cf432b2aa52e5ae81beb188a372901d) +--- + src/qemu/qemu_driver.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 41e9bff17b..5f6543d8e8 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -21510,8 +21510,14 @@ qemuDomainGetStatsBlockExportDisk(virDomainDiskDefPtr disk, + VIR_INFO("optional disk '%s' source file is missing, " + "skip getting stats", disk->dst); + +- return qemuDomainGetStatsBlockExportHeader(disk, disk->src, *recordnr, +- params); ++ if (qemuDomainGetStatsBlockExportHeader(disk, disk->src, *recordnr, ++ params) < 0) { ++ return -1; ++ } ++ ++ (*recordnr)++; ++ ++ return 0; + } + + for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { +-- +2.33.0 + diff --git a/qemu_interface-Fix-cfg-refcounting-in-qemuInterfaceP.patch b/qemu_interface-Fix-cfg-refcounting-in-qemuInterfaceP.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5fb32c7b07fb5cc6ea831a75aba9e131fd4b389 --- /dev/null +++ b/qemu_interface-Fix-cfg-refcounting-in-qemuInterfaceP.patch @@ -0,0 +1,34 @@ +From 2edb23f8ce178fc3c8e166854ef056cbf2caeda6 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 4 Sep 2020 08:55:39 +0200 +Subject: [PATCH 056/108] qemu_interface: Fix @cfg refcounting in + qemuInterfacePrepareSlirp() + +In the qemuInterfacePrepareSlirp() function, the qemu driver +config is obtained (via virQEMUDriverGetConfig()), but it is +never unrefed leading to mangled refcounter. + +Fixes: 9145b3f1cc334e946b3f9ea45d6c24c868301e6f +Signed-off-by: Michal Privoznik +Reviewed-by: Laine Stump +(cherry picked from commit 5befe4ee184d137b7fa8a7efee83aa4a03d7d293) +--- + src/qemu/qemu_interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c +index 2b24c73d65..77c890a165 100644 +--- a/src/qemu/qemu_interface.c ++++ b/src/qemu/qemu_interface.c +@@ -634,7 +634,7 @@ qemuSlirpPtr + qemuInterfacePrepareSlirp(virQEMUDriverPtr driver, + virDomainNetDefPtr net) + { +- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); ++ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autoptr(qemuSlirp) slirp = NULL; + size_t i; + +-- +2.33.0 + diff --git a/qemu_monitor-Document-qemuMonitorUnregister.patch b/qemu_monitor-Document-qemuMonitorUnregister.patch new file mode 100644 index 0000000000000000000000000000000000000000..72180b927ef355712870012e862752592e94f7c4 --- /dev/null +++ b/qemu_monitor-Document-qemuMonitorUnregister.patch @@ -0,0 +1,36 @@ +From 2f1767779710fbc82479ee1d2bc9fce4c49e7c8b Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 24 Feb 2021 13:55:33 +0100 +Subject: [PATCH 015/108] qemu_monitor: Document qemuMonitorUnregister() + +The most important bit is that the caller is expected to pass +locked monitor. + +Signed-off-by: Michal Privoznik +Reviewed-by: Andrea Bolognani +(cherry picked from commit 6458b9d94a1d5da62e46ac0b10f92aca103c27ab) +--- + src/qemu/qemu_monitor.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index ec79fa6368..c98edbd254 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -842,6 +842,13 @@ qemuMonitorRegister(qemuMonitorPtr mon) + } + + ++/** ++ * qemuMonitorUnregister: ++ * @mon: monitor object ++ * ++ * Unregister monitor from the event loop. The monitor object ++ * must be locked before calling this function. ++ */ + void + qemuMonitorUnregister(qemuMonitorPtr mon) + { +-- +2.33.0 + diff --git a/qemu_process-Release-domain-seclabel-later-in-qemuPr.patch b/qemu_process-Release-domain-seclabel-later-in-qemuPr.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cfe8a661f62e8a9efcf9699cb6adde8610f8952 --- /dev/null +++ b/qemu_process-Release-domain-seclabel-later-in-qemuPr.patch @@ -0,0 +1,62 @@ +From 667ac7026fdf98ab9fe4158aa101026fb9dc40c8 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 9 Dec 2020 11:06:29 +0100 +Subject: [PATCH 089/108] qemu_process: Release domain seclabel later in + qemuProcessStop() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some secdrivers (typically SELinux driver) generate unique +dynamic seclabel for each domain (unless a static one is +requested in domain XML). This is achieved by calling +qemuSecurityGenLabel() from qemuProcessPrepareDomain() which +allocates unique seclabel and stores it in domain def->seclabels. +The counterpart is qemuSecurityReleaseLabel() which releases the +label and removes it from def->seclabels. Problem is, that with +current code the qemuProcessStop() may still want to use the +seclabel after it was released, e.g. when it wants to restore the +label of a disk mirror. + +What is happening now, is that in qemuProcessStop() the +qemuSecurityReleaseLabel() is called, which removes the SELinux +seclabel from def->seclabels, yada yada yada and eventually +qemuSecurityRestoreImageLabel() is called. This bubbles down to +virSecuritySELinuxRestoreImageLabelSingle() which find no SELinux +seclabel (using virDomainDefGetSecurityLabelDef()) and this +returns early doing nothing. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1751664 +Fixes: 8fa0374c5b8e834fcbdeae674cc6cc9e6bf9019f +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 5ac2439a831037c2a861566cad1980b0a2f2907f) +--- + src/qemu/qemu_process.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 890603f66b..bf5375bcde 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7449,8 +7449,6 @@ void qemuProcessStop(virQEMUDriverPtr driver, + qemuSecurityRestoreAllLabel(driver, vm, + !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED)); + +- qemuSecurityReleaseLabel(driver->securityManager, vm->def); +- + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDeviceDef dev; + virDomainDiskDefPtr disk = vm->def->disks[i]; +@@ -7625,6 +7623,8 @@ void qemuProcessStop(virQEMUDriverPtr driver, + } + } + ++ qemuSecurityReleaseLabel(driver->securityManager, vm->def); ++ + /* clear all private data entries which are no longer needed */ + qemuDomainObjPrivateDataClear(priv); + +-- +2.33.0 + diff --git a/qemu_security-Complete-renaming-of-virSecurityManage.patch b/qemu_security-Complete-renaming-of-virSecurityManage.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b8b0ef315b27f37bfd6a1d2fc2fbfb1ff1ba93a --- /dev/null +++ b/qemu_security-Complete-renaming-of-virSecurityManage.patch @@ -0,0 +1,55 @@ +From ab52cf0ea29a263db426fec813946daab2ad9b27 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 30 Jun 2020 22:02:19 +0200 +Subject: [PATCH 006/108] qemu_security: Complete renaming of + virSecurityManagerSetAllLabel() argument + +Just like in the previous commit, the stdin_path argument of +virSecurityManagerSetAllLabel() is renamed to incomingPath. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 77ef11845696ee971d4a285eb344136113b1e6f2) +--- + src/qemu/qemu_security.c | 4 ++-- + src/qemu/qemu_security.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c +index 484fc34552..e7f38cb69b 100644 +--- a/src/qemu/qemu_security.c ++++ b/src/qemu/qemu_security.c +@@ -32,7 +32,7 @@ VIR_LOG_INIT("qemu.qemu_process"); + int + qemuSecuritySetAllLabel(virQEMUDriverPtr driver, + virDomainObjPtr vm, +- const char *stdin_path, ++ const char *incomingPath, + bool migrated) + { + int ret = -1; +@@ -47,7 +47,7 @@ qemuSecuritySetAllLabel(virQEMUDriverPtr driver, + + if (virSecurityManagerSetAllLabel(driver->securityManager, + vm->def, +- stdin_path, ++ incomingPath, + priv->chardevStdioLogd, + migrated) < 0) + goto cleanup; +diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h +index c8516005ac..89dca61c3a 100644 +--- a/src/qemu/qemu_security.h ++++ b/src/qemu/qemu_security.h +@@ -26,7 +26,7 @@ + + int qemuSecuritySetAllLabel(virQEMUDriverPtr driver, + virDomainObjPtr vm, +- const char *stdin_path, ++ const char *incomingPath, + bool migrated); + + void qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver, +-- +2.33.0 + diff --git a/rpc-Fix-memory-leak-of-fds.patch b/rpc-Fix-memory-leak-of-fds.patch new file mode 100644 index 0000000000000000000000000000000000000000..bd806121016f436a203d4cdc0bce99cca125b193 --- /dev/null +++ b/rpc-Fix-memory-leak-of-fds.patch @@ -0,0 +1,33 @@ +From 88ddb9ae6bc020c5ce64f98a6a8e5823f48c885a Mon Sep 17 00:00:00 2001 +From: Peng Liang +Date: Wed, 2 Mar 2022 17:22:05 +0800 +Subject: [PATCH 108/108] rpc: Fix memory leak of fds + +In virSystemdActivationClaimFDs, the memory of ent->fds has been stolen +and stored in fds, but fds is never freed, which causes a memory leak. +Fix it by declaring fds as g_autofree. + +Reported-by: Jie Tang +Signed-off-by: Peng Liang +Reviewed-by: Michal Privoznik +(cherry picked from commit 8a1915c4d6c33669dcb390d0708cb6e5d651770d) +--- + src/rpc/virnetserver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c +index 242052754f..26f3a5ec31 100644 +--- a/src/rpc/virnetserver.c ++++ b/src/rpc/virnetserver.c +@@ -683,7 +683,7 @@ virNetServerAddServiceActivation(virNetServerPtr srv, + size_t max_queued_clients, + size_t nrequests_client_max) + { +- int *fds; ++ g_autofree int *fds = NULL; + size_t nfds; + + if (act == NULL) +-- +2.33.0 + diff --git a/rpc-avoid-crash-when-system-time-jump-back.patch b/rpc-avoid-crash-when-system-time-jump-back.patch new file mode 100644 index 0000000000000000000000000000000000000000..45e90f47becfc5951404261c4a383338bd65e514 --- /dev/null +++ b/rpc-avoid-crash-when-system-time-jump-back.patch @@ -0,0 +1,125 @@ +From b5b384c02c67cde982e97e9de14093605f6e10ec Mon Sep 17 00:00:00 2001 +From: BiaoXiang Ye +Date: Wed, 10 Feb 2021 05:58:05 +0000 +Subject: [PATCH 013/108] rpc: avoid crash when system time jump back +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + Setting the system time backward would lead to a + multiplication overflow in function virKeepAliveStart. + The function virKeepAliveTimerInternal got the same bug too. + + Backtrace below: + #0 0x0000ffffae898470 in raise () from /usr/lib64/libc.so.6 + #1 0x0000ffffae89981c in abort () from /usr/lib64/libc.so.6 + #2 0x0000ffffaf9a36a8 in __mulvsi3 () from /usr/lib64/libvirt.so.0 + #3 0x0000ffffaf8fd9e8 in virKeepAliveStart (ka=0xaaaaf954ce10, interval=interval entry=0, + count=count entry=0) at ../../src/rpc/virkeepalive.c:283 + #4 0x0000ffffaf908560 in virNetServerClientStartKeepAlive (client=0xaaaaf954cbe0) + at ../../src/rpc/virnetserverclient.c:1628 + #5 0x0000aaaac57eb6dc in remoteDispatchConnectSupportsFeature (server=0xaaaaf95309d0, + msg=0xaaaaf9549d90, ret=0xffff8c007fc0, args=0xffff8c002e70, rerr=0xffff9ea054a0, + client=0xaaaaf954cbe0) at ../../src/remote/remote_daemon_dispatch.c:5063 + #6 remoteDispatchConnectSupportsFeatureHelper (server=0xaaaaf95309d0, client=0xaaaaf954cbe0, + msg=0xaaaaf9549d90, rerr=0xffff9ea054a0, args=0xffff8c002e70, ret=0xffff8c007fc0) + at ./remote/remote_daemon_dispatch_stubs.h:3503 + #7 0x0000ffffaf9053a4 in virNetServerProgramDispatchCall(msg=0xaaaaf9549d90, client=0xaaaaf954cbe0, + server=0x0, prog=0xaaaaf953a170) at ../../src/rpc/virnetserverprogram.c:451 + #8 virNetServerProgramDispatch (prog=0xaaaaf953a170, server=0x0, server entry=0xaaaaf95309d0, + client=0xaaaaf954cbe0, msg=0xaaaaf9549d90) at ../../src/rpc/virnetserverprogram.c:306 + #9 0x0000ffffaf90a6bc in virNetServerProcessMsg (msg=, prog=, + client=, srv=0xaaaaf95309d0) at ../../src/rpc/virnetserver.c:137 + #10 virNetServerHandleJob (jobOpaque=0xaaaaf950df80, opaque=0xaaaaf95309d0) + at ../../src/rpc/virnetserver.c:154 + #11 0x0000ffffaf812e14 in virThreadPoolWorker (opaque=) + at ../../src/util/virthreadpool.c:163 + #12 0x0000ffffaf81237c in virThreadHelper (data=) at ../../src/util/virthread.c:246 + #13 0x0000ffffaea327ac in ?? () from /usr/lib64/libpthread.so.0 + #14 0x0000ffffae93747c in ?? () from /usr/lib64/libc.so.6 + (gdb) frame 3 + #3 0x0000ffffaf8fd9e8 in virKeepAliveStart (ka=0xaaaaf954ce10, interval=interval entry=0, + count=count entry=0) at ../../src/rpc/virkeepalive.c:283 + 283 timeout = ka->interval - delay; + (gdb) list + 278 now = time(NULL); + 279 delay = now - ka->lastPacketReceived; <='delay' got a negative value + 280 if (delay > ka->interval) + 281 timeout = 0; + 282 else + 283 timeout = ka->interval - delay; + 284 ka->intervalStart = now - (ka->interval - timeout); + 285 ka->timer = virEventAddTimeout(timeout * 1000, virKeepAliveTimer, <= multiplication overflow + 286 ka, virObjectFreeCallback); + 287 if (ka->timer < 0) + (gdb) p now + $2 = 18288001 + (gdb) p ka->lastPacketReceived + $3 = 1609430405 + +Signed-off-by: BiaoXiang Ye +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +(cherry picked from commit 613e994af0e7b93dfc641aae1aa9ccaad0c837f3) +--- + src/rpc/virkeepalive.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c +index 860b91b6b1..119427eb03 100644 +--- a/src/rpc/virkeepalive.c ++++ b/src/rpc/virkeepalive.c +@@ -40,8 +40,8 @@ struct _virKeepAlive { + int interval; + unsigned int count; + unsigned int countToDeath; +- time_t lastPacketReceived; +- time_t intervalStart; ++ gint64 lastPacketReceived; ++ gint64 intervalStart; + int timer; + + virKeepAliveSendFunc sendCB; +@@ -113,7 +113,7 @@ static bool + virKeepAliveTimerInternal(virKeepAlivePtr ka, + virNetMessagePtr *msg) + { +- time_t now = time(NULL); ++ gint64 now = g_get_monotonic_time() / G_USEC_PER_SEC; + int timeval; + + if (ka->interval <= 0 || ka->intervalStart == 0) +@@ -231,9 +231,9 @@ virKeepAliveStart(virKeepAlivePtr ka, + unsigned int count) + { + int ret = -1; +- time_t delay; ++ gint64 delay; + int timeout; +- time_t now; ++ gint64 now; + + virObjectLock(ka); + +@@ -270,7 +270,7 @@ virKeepAliveStart(virKeepAlivePtr ka, + "ka=%p client=%p interval=%d count=%u", + ka, ka->client, interval, count); + +- now = time(NULL); ++ now = g_get_monotonic_time() / G_USEC_PER_SEC; + delay = now - ka->lastPacketReceived; + if (delay > ka->interval) + timeout = 0; +@@ -375,7 +375,8 @@ virKeepAliveCheckMessage(virKeepAlivePtr ka, + virObjectLock(ka); + + ka->countToDeath = ka->count; +- ka->lastPacketReceived = ka->intervalStart = time(NULL); ++ ka->intervalStart = g_get_monotonic_time() / G_USEC_PER_SEC; ++ ka->lastPacketReceived = ka->intervalStart; + + if (msg->header.prog == KEEPALIVE_PROGRAM && + msg->header.vers == KEEPALIVE_PROTOCOL_VERSION && +-- +2.33.0 + diff --git a/rpc-socket-properly-call-virSetCloseExec.patch b/rpc-socket-properly-call-virSetCloseExec.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c39133b70a49d1a24e7e622ff1eee978a008e7a --- /dev/null +++ b/rpc-socket-properly-call-virSetCloseExec.patch @@ -0,0 +1,35 @@ +From 5bde58da3e35283dcbba97f4148db4b10a05ddcc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 22 Sep 2020 22:29:25 +0200 +Subject: [PATCH 031/108] rpc: socket: properly call virSetCloseExec +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cppcheck reports: +style: Argument 'fd<0' to function virSetCloseExec is always 0 [knownArgument] + +Signed-off-by: Ján Tomko +Fixes: 4b9919af4024a6fbc3d4ee996d8a4c27dbc44285 +Reviewed-by: Peter Krempa +(cherry picked from commit 2e7849735fc9d51513250f2a8e5712459bf9df63) +--- + src/rpc/virnetsocket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c +index 553728984b..d2c2072e1c 100644 +--- a/src/rpc/virnetsocket.c ++++ b/src/rpc/virnetsocket.c +@@ -1400,7 +1400,7 @@ int virNetSocketDupFD(virNetSocketPtr sock, bool cloexec) + } + #ifndef F_DUPFD_CLOEXEC + if (cloexec && +- virSetCloseExec(fd < 0)) { ++ virSetCloseExec(fd) < 0) { + int saveerr = errno; + closesocket(fd); + errno = saveerr; +-- +2.33.0 + diff --git a/securityselinuxhelper-Fix-retval-of-setcon_raw-and-s.patch b/securityselinuxhelper-Fix-retval-of-setcon_raw-and-s.patch new file mode 100644 index 0000000000000000000000000000000000000000..317a523af2a10cea738d40ce296d34b2e6a99133 --- /dev/null +++ b/securityselinuxhelper-Fix-retval-of-setcon_raw-and-s.patch @@ -0,0 +1,56 @@ +From 6ba1a092489ff7dbef0919417789e4ec4a6798a4 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 10 May 2021 10:33:02 +0200 +Subject: [PATCH 053/108] securityselinuxhelper: Fix retval of setcon_raw() and + security_disable() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The securityselinuxhelper is a mock that's replacing libselinux +APIs with our own implementation to achieve deterministic +results. Our implementation uses env vars (among other things) to +hold internal state. For instance, "FAKE_SELINUX_CONTEXT" and +"FAKE_SELINUX_DISABLED" variables are used. However, as we were +switching from setenv() to g_setenv() we also changed the set of +possible retvals from setcon_raw() and security_disable(). +Previously, the retval of setenv() was used directly which +returns 0 on success and -1 on error. But g_setenv() has +different retval semantics: it returns 1 on success and 0 on +error. + +This discrepancy can be observed by running viridentitytest where +case #2 reports an error ("!") - because setcon_raw() returns 1. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 4ce11062779cee3eaec0b75d862e3d7341ec3511) +--- + tests/securityselinuxhelper.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/securityselinuxhelper.c b/tests/securityselinuxhelper.c +index 63b57261da..e2c1dc9e0a 100644 +--- a/tests/securityselinuxhelper.c ++++ b/tests/securityselinuxhelper.c +@@ -145,7 +145,7 @@ int setcon_raw(const char *context) + errno = EINVAL; + return -1; + } +- return g_setenv("FAKE_SELINUX_CONTEXT", context, TRUE); ++ return g_setenv("FAKE_SELINUX_CONTEXT", context, TRUE) == TRUE ? 0 : -1; + } + + int setcon(const char *context) +@@ -224,7 +224,7 @@ int security_disable(void) + return -1; + } + +- return g_setenv("FAKE_SELINUX_DISABLED", "1", TRUE); ++ return g_setenv("FAKE_SELINUX_DISABLED", "1", TRUE) == TRUE ? 0 : -1; + } + + int security_getenforce(void) +-- +2.33.0 + diff --git a/storage-avoid-maybe-uninitialized-warning-by-GCC-10.patch b/storage-avoid-maybe-uninitialized-warning-by-GCC-10.patch new file mode 100644 index 0000000000000000000000000000000000000000..d7ac1ff3e47f03a62ab9912c9a8a64ce5fbc278f --- /dev/null +++ b/storage-avoid-maybe-uninitialized-warning-by-GCC-10.patch @@ -0,0 +1,79 @@ +From 75afa2f5b77edd8c34b2062074abfa5c3029437d Mon Sep 17 00:00:00 2001 +From: Boris Fiuczynski +Date: Thu, 13 Aug 2020 16:03:46 +0200 +Subject: [PATCH 046/108] storage: avoid maybe-uninitialized warning by GCC 10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +GCC 10 complains about variables may be used uninitialized. +Even though it might be false positives, we can easily avoid them. + +Avoiding + ../src/storage/storage_backend_iscsi_direct.c:634:11: error: ‘nb_block’ may be used uninitialized in this function [-Werror=maybe-uninitialized] + 634 | while (lba < nb_block) { + | ^ + ../src/storage/storage_backend_iscsi_direct.c:619:14: note: ‘nb_block’ was declared here + 619 | uint64_t nb_block; + | ^~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c:637:16: error: ‘block_size’ may be used uninitialized in this function [-Werror=maybe-uninitialized] + 637 | task = iscsi_write16_sync(iscsi, lun, lba, data, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 638 | block_size * to_write, + | ~~~~~~~~~~~~~~~~~~~~~~ + 639 | block_size, 0, 0, 0, 0, 0); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c:618:14: note: ‘block_size’ was declared here + 618 | uint32_t block_size; + | ^~~~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c: In function ‘virStorageBackendISCSIDirectRefreshPool’: + ../src/storage/storage_backend_iscsi_direct.c:320:39: error: ‘nb_block’ may be used uninitialized in this function [-Werror=maybe-uninitialized] + 320 | vol->target.capacity = block_size * nb_block; + | ~~~~~~~~~~~^~~~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c:306:14: note: ‘nb_block’ was declared here + 306 | uint64_t nb_block; + | ^~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c:320:39: error: ‘block_size’ may be used uninitialized in this function [-Werror=maybe-uninitialized] + 320 | vol->target.capacity = block_size * nb_block; + | ~~~~~~~~~~~^~~~~~~~~~ + ../src/storage/storage_backend_iscsi_direct.c:305:14: note: ‘block_size’ was declared here + 305 | uint32_t block_size; + | ^~~~~~~~~~ + +Signed-off-by: Boris Fiuczynski +Reviewed-by: Marc Hartmayer +Reviewed-by: Erik Skultety +(cherry picked from commit ae8a83c35378d8d3eac2e41b3a10cac0e587ce54) +--- + src/storage/storage_backend_iscsi_direct.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/storage/storage_backend_iscsi_direct.c b/src/storage/storage_backend_iscsi_direct.c +index c37c671db6..027fa83de7 100644 +--- a/src/storage/storage_backend_iscsi_direct.c ++++ b/src/storage/storage_backend_iscsi_direct.c +@@ -302,8 +302,8 @@ virISCSIDirectRefreshVol(virStoragePoolObjPtr pool, + char *portal) + { + virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); +- uint32_t block_size; +- uint64_t nb_block; ++ uint32_t block_size = 0; ++ uint64_t nb_block = 0; + g_autoptr(virStorageVolDef) vol = NULL; + + if (virISCSIDirectTestUnitReady(iscsi, lun) < 0) +@@ -615,8 +615,8 @@ virStorageBackendISCSIDirectVolWipeZero(virStorageVolDefPtr vol, + struct iscsi_context *iscsi) + { + uint64_t lba = 0; +- uint32_t block_size; +- uint64_t nb_block; ++ uint32_t block_size = 0; ++ uint64_t nb_block = 0; + struct scsi_task *task = NULL; + int lun = 0; + int ret = -1; +-- +2.33.0 + diff --git a/storageBackendProbeTarget-Don-t-fail-if-backing-stor.patch b/storageBackendProbeTarget-Don-t-fail-if-backing-stor.patch new file mode 100644 index 0000000000000000000000000000000000000000..d00fa97b885e75986b422596938b26334a40e5ea --- /dev/null +++ b/storageBackendProbeTarget-Don-t-fail-if-backing-stor.patch @@ -0,0 +1,45 @@ +From bd45da8b308c16f30766ad756fe3c2f54e4f3e9f Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 25 Feb 2021 13:51:51 +0100 +Subject: [PATCH 016/108] storageBackendProbeTarget: Don't fail if backing + store can't be parsed + +When the backing store of the image can't be parsed +virStorageSourceNewFromBacking returns -1. storageBackendProbeTarget +then also fails which makes the pool refresh fail or even the storage +pool becomes inactive after (re)start of libvirtd. + +In situations when we can't access the backing store via network we +just report the backing store string, thus we can do the same thing for +unparsable backing store to prevent the pool from going offline. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 104db1951d3abfd8cb363b8e8070f712044bc645) +--- + src/storage/storage_util.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c +index 4c67d3a4b1..2e4c7b29b3 100644 +--- a/src/storage/storage_util.c ++++ b/src/storage/storage_util.c +@@ -3363,13 +3363,11 @@ storageBackendProbeTarget(virStorageSourcePtr target, + return -1; + + if (meta->backingStoreRaw) { +- if (virStorageSourceNewFromBacking(meta, &target->backingStore) < 0) +- return -1; +- + /* XXX: Remote storage doesn't play nicely with volumes backed by + * remote storage. To avoid trouble, just fake the backing store is RAW + * and put the string from the metadata as the path of the target. */ +- if (!virStorageSourceIsLocalStorage(target->backingStore)) { ++ if (virStorageSourceNewFromBacking(meta, &target->backingStore) < 0 || ++ !virStorageSourceIsLocalStorage(target->backingStore)) { + virObjectUnref(target->backingStore); + + if (!(target->backingStore = virStorageSourceNew())) +-- +2.33.0 + diff --git a/storage_util-fix-qemu-img-sparse-allocation.patch b/storage_util-fix-qemu-img-sparse-allocation.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c163ce9aade4c6f62af8ed93b4b4993fefdf4ed --- /dev/null +++ b/storage_util-fix-qemu-img-sparse-allocation.patch @@ -0,0 +1,37 @@ +From bd345bfdd2f07bc07d4b0e52ebc900c19ee882e0 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Tue, 25 Aug 2020 15:09:53 +0200 +Subject: [PATCH 050/108] storage_util: fix qemu-img sparse allocation + +Commit introduced a support +to fully allocate qcow2 images when matches but +it doesn't work as expected. + +The issue is that info.size_arg is in KB but the info.allocation +introduced by the mentioned commit is in B. This results in using +"preallocation=falloc," in cases where "preallocation=metadata," should +be used. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Michal Privoznik +(cherry picked from commit 81a3042a12c7c06adc8e95264b6143b2eeb4953f) +--- + src/storage/storage_util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c +index 2e4c7b29b3..4c8316c0d0 100644 +--- a/src/storage/storage_util.c ++++ b/src/storage/storage_util.c +@@ -1065,7 +1065,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, + .type = NULL, + .inputType = NULL, + .path = vol->target.path, +- .allocation = vol->target.allocation, ++ .allocation = VIR_DIV_UP(vol->target.allocation, 1024), + .encryption = !!vol->target.encryption, + .preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA), + .compat = vol->target.compat, +-- +2.33.0 + diff --git a/test-Fix-memory-leak-in-testParseXMLDocFromFile.patch b/test-Fix-memory-leak-in-testParseXMLDocFromFile.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6b68bc192402473408a168f32b909aa38e41fa2 --- /dev/null +++ b/test-Fix-memory-leak-in-testParseXMLDocFromFile.patch @@ -0,0 +1,32 @@ +From b8ac909459af85d5c141de4cd6157b49caf8adf0 Mon Sep 17 00:00:00 2001 +From: John Ferlan +Date: Tue, 16 Jun 2020 08:07:06 -0400 +Subject: [PATCH 002/108] test: Fix memory leak in testParseXMLDocFromFile + +Since ceb3255c, @absFile is leaked. + +Found by Coverity. + +Signed-off-by: John Ferlan +Reviewed-by: Peter Krempa +(cherry picked from commit 072f6d6e43dc37a37cb1503f17cf3c1071ea02ca) +--- + src/test/test_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test_driver.c b/src/test/test_driver.c +index 7759847c2d..33f1792177 100644 +--- a/src/test/test_driver.c ++++ b/src/test/test_driver.c +@@ -777,7 +777,7 @@ testParseXMLDocFromFile(xmlNodePtr node, const char *file, const char *type) + { + xmlNodePtr ret = NULL; + xmlDocPtr doc = NULL; +- char *absFile = NULL; ++ g_autofree char *absFile = NULL; + g_autofree char *relFile = NULL; + + if ((relFile = virXMLPropString(node, "file"))) { +-- +2.33.0 + diff --git a/tests-Don-t-leak-cpu-defs.patch b/tests-Don-t-leak-cpu-defs.patch new file mode 100644 index 0000000000000000000000000000000000000000..d3c2a5ed7b99d6ad08cb335e808452e03eaf2522 --- /dev/null +++ b/tests-Don-t-leak-cpu-defs.patch @@ -0,0 +1,41 @@ +From 5ad5d48df150a4025eb7628596f3715ba4a91eb1 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 30 Jul 2021 10:34:50 +0200 +Subject: [PATCH 098/108] tests: Don't leak cpu defs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are cpu definitions that are allocated in +qemuTestDriverInit() but are missing corresponding +virCPUDefFree() call in qemuTestDriverFree(). It's safe to call +the free function because the definitions contain a refcounter +and thus even if they were still in use the refcounter would be +just decreased. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 73890139bfa248e3a714feb5566144510c3e97dc) +--- + tests/testutilsqemu.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c +index 6c43f07015..0e932877e8 100644 +--- a/tests/testutilsqemu.c ++++ b/tests/testutilsqemu.c +@@ -317,6 +317,11 @@ void qemuTestDriverFree(virQEMUDriver *driver) + virObjectUnref(driver->caps); + virObjectUnref(driver->config); + virObjectUnref(driver->securityManager); ++ ++ virCPUDefFree(cpuDefault); ++ virCPUDefFree(cpuHaswell); ++ virCPUDefFree(cpuPower8); ++ virCPUDefFree(cpuPower9); + } + + int qemuTestCapsCacheInsert(virFileCachePtr cache, +-- +2.33.0 + diff --git a/tests-avoid-close-of-bad-file-handle-in-commandtest.patch b/tests-avoid-close-of-bad-file-handle-in-commandtest.patch new file mode 100644 index 0000000000000000000000000000000000000000..18cf5ae7305a6f9f5c0ca435092a0d763269c11f --- /dev/null +++ b/tests-avoid-close-of-bad-file-handle-in-commandtest.patch @@ -0,0 +1,37 @@ +From 1e5ac569100a5afa90ddee94e8a1cf9c7a9e0415 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 21 Sep 2020 18:37:03 +0100 +Subject: [PATCH 029/108] tests: avoid close of bad file handle in commandtest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Closed file handles need to be initialized to -1, not 0. This caused a +inappropriate double close of stdin, which is not desirable, although +it had no ill effects. + +Reviewed-by: Eric Blake +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit faf76dd70e96e43478b3fe02106afa62eeb65dc8) +--- + tests/commandtest.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/commandtest.c b/tests/commandtest.c +index ce492e31f7..cc2c99bb68 100644 +--- a/tests/commandtest.c ++++ b/tests/commandtest.c +@@ -1205,8 +1205,8 @@ static int test27(const void *unused G_GNUC_UNUSED) + printf("Could not set send buffers\n"); + goto cleanup; + } +- pipe1[1] = 0; +- pipe2[1] = 0; ++ pipe1[1] = -1; ++ pipe2[1] = -1; + buffer1 = NULL; + buffer2 = NULL; + +-- +2.33.0 + diff --git a/testutils-Don-t-leak-testBitmap-and-failedTests.patch b/testutils-Don-t-leak-testBitmap-and-failedTests.patch new file mode 100644 index 0000000000000000000000000000000000000000..e92e06ef7700930cb750283946d0d4876bd7532a --- /dev/null +++ b/testutils-Don-t-leak-testBitmap-and-failedTests.patch @@ -0,0 +1,37 @@ +From ad50df08d50dbaaad974d4f6b19328fb881857af Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 29 Jul 2021 15:53:16 +0200 +Subject: [PATCH 097/108] testutils: Don't leak @testBitmap and @failedTests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In virTestMain() the @failedTests bitmap is allocated and +optionally @testBitmap too. But neither of them is freed. + +Fixes: 0cd5a726e365e67690a81e3ce33ecd0cb0b5178d +Fixes: cebb468ef5e82b8d4253e27ef70c67812cf93c5a +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 77f7067059a59a1b15e898f64944a7a06ae9f675) +--- + tests/testutils.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tests/testutils.c b/tests/testutils.c +index aa4195920d..2aeaee3306 100644 +--- a/tests/testutils.c ++++ b/tests/testutils.c +@@ -849,6 +849,9 @@ int virTestMain(int argc, + fprintf(stderr, "Some tests failed. Run them using:\n"); + fprintf(stderr, "VIR_TEST_DEBUG=1 VIR_TEST_RANGE=%s %s\n", failed, argv[0]); + } ++ ++ virBitmapFree(testBitmap); ++ virBitmapFree(failedTests); + virLogReset(); + return ret; + } +-- +2.33.0 + diff --git a/testutils-call-va_end-before-return.patch b/testutils-call-va_end-before-return.patch new file mode 100644 index 0000000000000000000000000000000000000000..f3b17dcafb9300b8fc09f4d94c2d941a4acef5fd --- /dev/null +++ b/testutils-call-va_end-before-return.patch @@ -0,0 +1,27 @@ +From 35b8b20e2923777b9b413a3cb906d8c4bbc064e1 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Mon, 16 Nov 2020 16:12:09 +0100 +Subject: [PATCH 075/108] testutils: call va_end before return + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit e8e90a35df007ee6032d2dc0b6aa3d21747cc326) +--- + tests/testutils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/testutils.c b/tests/testutils.c +index 5fd81b70a2..aa4195920d 100644 +--- a/tests/testutils.c ++++ b/tests/testutils.c +@@ -771,6 +771,7 @@ int virTestMain(int argc, + while ((lib = va_arg(ap, const char *))) { + if (!virFileIsExecutable(lib)) { + perror(lib); ++ va_end(ap); + return EXIT_FAILURE; + } + +-- +2.33.0 + diff --git a/tools-avoid-potential-null-pointer-dereference-by-GC.patch b/tools-avoid-potential-null-pointer-dereference-by-GC.patch new file mode 100644 index 0000000000000000000000000000000000000000..4cd86b0780dbcfbe5bfe0f9e1a933c2cca61a3f6 --- /dev/null +++ b/tools-avoid-potential-null-pointer-dereference-by-GC.patch @@ -0,0 +1,42 @@ +From d02aeaf7c2b2e6038dd5967fddd9339480b7a25e Mon Sep 17 00:00:00 2001 +From: Boris Fiuczynski +Date: Thu, 13 Aug 2020 16:03:45 +0200 +Subject: [PATCH 045/108] tools: avoid potential null pointer dereference by + GCC 10 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +GCC 10 complains about "arg" possibly being a NULL dereference. +Even though it might be a false positive, we can easily avoid it. + +Avoiding + ../tools/vsh.c: In function ‘vshCommandOptStringReq’: + ../tools/vsh.c:1034:19: error: potential null pointer dereference [-Werror=null-dereference] + 1034 | else if (!*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK)) + | ~~~^~~~~~ + +Signed-off-by: Boris Fiuczynski +Reviewed-by: Marc Hartmayer +Reviewed-by: Erik Skultety +(cherry picked from commit e2bd2af6e4f9323cf732563b430ef02e075fc804) +--- + tools/vsh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/vsh.c b/tools/vsh.c +index 58bb1e6a3c..65f4a48d62 100644 +--- a/tools/vsh.c ++++ b/tools/vsh.c +@@ -1034,7 +1034,7 @@ vshCommandOptStringReq(vshControl *ctl, + /* this should not be propagated here, just to be sure */ + if (ret == -1) + error = N_("Mandatory option not present"); +- else if (!*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK)) ++ else if (arg && !*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK)) + error = N_("Option argument is empty"); + + if (error) { +-- +2.33.0 + diff --git a/util-Avoid-double-free-in-virProcessSetAffinity.patch b/util-Avoid-double-free-in-virProcessSetAffinity.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d55ccd5ceb35232cf1883eb87a71bc7241dafd1 --- /dev/null +++ b/util-Avoid-double-free-in-virProcessSetAffinity.patch @@ -0,0 +1,58 @@ +From 3c487e9d9b50e220f9eb32a020cbd9fd742d4405 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Tue, 27 Oct 2020 13:48:38 +0100 +Subject: [PATCH 072/108] util: Avoid double free in virProcessSetAffinity + +The cpu mask was free()'d immediately on any error and at the end of the +function, where it was expected that it would either error out and return or +goto another allocation if the code was to fail. However since commit +9514e24984ee the error path did not return in one new case which caused +double-free in such situation. In order to make the code more straightforward +just free the mask after it's been used even before checking the return code of +the call. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1819801 + +Signed-off-by: Martin Kletzander +Reviewed-by: Peter Krempa +(cherry picked from commit 1f807631f402210d036ec4803e7adfefa222f786) +--- + src/util/virprocess.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/util/virprocess.c b/src/util/virprocess.c +index 141ebb54e0..c3f88d206b 100644 +--- a/src/util/virprocess.c ++++ b/src/util/virprocess.c +@@ -450,6 +450,7 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map) + int numcpus = 1024; + size_t masklen; + cpu_set_t *mask; ++ int rv = -1; + + /* Not only may the statically allocated cpu_set_t be too small, + * but there is no way to ask the kernel what size is large enough. +@@ -473,8 +474,10 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map) + CPU_SET_S(i, masklen, mask); + } + +- if (sched_setaffinity(pid, masklen, mask) < 0) { +- CPU_FREE(mask); ++ rv = sched_setaffinity(pid, masklen, mask); ++ CPU_FREE(mask); ++ ++ if (rv < 0) { + if (errno == EINVAL && + numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */ + numcpus = numcpus << 2; +@@ -484,7 +487,6 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map) + _("cannot set CPU affinity on process %d"), pid); + return -1; + } +- CPU_FREE(mask); + + return 0; + } +-- +2.33.0 + diff --git a/util-Fix-error-reporting-in-virnetlink.patch b/util-Fix-error-reporting-in-virnetlink.patch new file mode 100644 index 0000000000000000000000000000000000000000..4e222c3a86b3c5be0090f4f23969de1c49110225 --- /dev/null +++ b/util-Fix-error-reporting-in-virnetlink.patch @@ -0,0 +1,33 @@ +From 4218f98f09f2155823f01846502c9373d660aa5a Mon Sep 17 00:00:00 2001 +From: Andrea Bolognani +Date: Tue, 9 Mar 2021 11:18:53 +0100 +Subject: [PATCH 020/108] util: Fix error reporting in virnetlink + +The preprocessor macro we use to check whether we're on Linux +has not been spelled properly, and so we will always report the +error message intended for other platforms. + +Fixes: 879bcee08ce0f91f556fddfe452c3fbed5318468 +Signed-off-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +(cherry picked from commit 9b2f6c103028ae2dfab21f152f69352a1bfd72b9) +--- + src/util/virnetlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c +index 3117dcbe65..a49c29a169 100644 +--- a/src/util/virnetlink.c ++++ b/src/util/virnetlink.c +@@ -1215,7 +1215,7 @@ virNetlinkEventRemoveClient(int watch, const virMacAddr *macaddr, + + #else + +-# if defined(__linux) ++# if defined(__linux__) + static const char *unsupported = N_("libnl was not available at build time"); + # else + static const char *unsupported = N_("not supported on non-linux platforms"); +-- +2.33.0 + diff --git a/util-Fix-memory-leak-in-virAuthConfigLookup.patch b/util-Fix-memory-leak-in-virAuthConfigLookup.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b9af8eedf982ec71191da6769097e831e5a9f37 --- /dev/null +++ b/util-Fix-memory-leak-in-virAuthConfigLookup.patch @@ -0,0 +1,34 @@ +From 654c77db8239678b3154590f16e7c7c1da557c89 Mon Sep 17 00:00:00 2001 +From: John Ferlan +Date: Tue, 16 Jun 2020 08:07:03 -0400 +Subject: [PATCH 004/108] util: Fix memory leak in virAuthConfigLookup + +Since 5084091a, @authcred is filled by a g_key_file_get_string which is +now an allocated string as opposed to some hash table lookup value, so +we need to treat it as so. + +Found by Coverity + +Signed-off-by: John Ferlan +Reviewed-by: Peter Krempa +(cherry picked from commit d25758141723d45aecd368ee3e5183ccb5c7eea2) +--- + src/util/virauthconfig.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virauthconfig.c b/src/util/virauthconfig.c +index 1c007757c7..0da9c2461f 100644 +--- a/src/util/virauthconfig.c ++++ b/src/util/virauthconfig.c +@@ -103,7 +103,7 @@ int virAuthConfigLookup(virAuthConfigPtr auth, + { + g_autofree char *authgroup = NULL; + g_autofree char *credgroup = NULL; +- const char *authcred; ++ g_autofree char *authcred = NULL; + + *value = NULL; + +-- +2.33.0 + diff --git a/util-Fix-memory-leak-in-virAuthGetCredential.patch b/util-Fix-memory-leak-in-virAuthGetCredential.patch new file mode 100644 index 0000000000000000000000000000000000000000..17a25e521fae128d0768d5a8f9b9217d6ca2b4f7 --- /dev/null +++ b/util-Fix-memory-leak-in-virAuthGetCredential.patch @@ -0,0 +1,101 @@ +From 1d0a80317f2bb3bc5e44c54cc7d49e44ac80b66f Mon Sep 17 00:00:00 2001 +From: John Ferlan +Date: Tue, 16 Jun 2020 08:07:02 -0400 +Subject: [PATCH 005/108] util: Fix memory leak in virAuthGetCredential + +Since 5084091a, @tmp is filled by a g_key_file_get_string which is +now an allocated string as opposed to some hash table lookup value, +so we need to treat it as so. + +Found by Coverity + +Signed-off-by: John Ferlan +Reviewed-by: Peter Krempa +(cherry picked from commit d585847d2e9c98ccb765027999824568c355ddc6) +--- + src/remote/remote_driver.c | 2 +- + src/util/virauth.c | 5 +---- + src/util/virauthconfig.c | 2 +- + src/util/virauthconfig.h | 2 +- + tests/virauthconfigtest.c | 2 +- + 5 files changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c +index 1202d44017..7591263f6d 100644 +--- a/src/remote/remote_driver.c ++++ b/src/remote/remote_driver.c +@@ -4097,7 +4097,7 @@ static int remoteAuthFillFromConfig(virConnectPtr conn, + } + + for (ninteract = 0; state->interact[ninteract].id != 0; ninteract++) { +- const char *value = NULL; ++ char *value = NULL; + + switch (state->interact[ninteract].id) { + case SASL_CB_USER: +diff --git a/src/util/virauth.c b/src/util/virauth.c +index f75e674586..105fca16eb 100644 +--- a/src/util/virauth.c ++++ b/src/util/virauth.c +@@ -107,7 +107,6 @@ virAuthGetCredential(const char *servicename, + char **value) + { + g_autoptr(virAuthConfig) config = NULL; +- const char *tmp; + + *value = NULL; + +@@ -121,11 +120,9 @@ virAuthGetCredential(const char *servicename, + servicename, + hostname, + credname, +- &tmp) < 0) ++ value) < 0) + return -1; + +- *value = g_strdup(tmp); +- + return 0; + } + +diff --git a/src/util/virauthconfig.c b/src/util/virauthconfig.c +index 0da9c2461f..2e50609531 100644 +--- a/src/util/virauthconfig.c ++++ b/src/util/virauthconfig.c +@@ -99,7 +99,7 @@ int virAuthConfigLookup(virAuthConfigPtr auth, + const char *service, + const char *hostname, + const char *credname, +- const char **value) ++ char **value) + { + g_autofree char *authgroup = NULL; + g_autofree char *credgroup = NULL; +diff --git a/src/util/virauthconfig.h b/src/util/virauthconfig.h +index de28b1ff28..b6f5b5c110 100644 +--- a/src/util/virauthconfig.h ++++ b/src/util/virauthconfig.h +@@ -37,6 +37,6 @@ int virAuthConfigLookup(virAuthConfigPtr auth, + const char *service, + const char *hostname, + const char *credname, +- const char **value); ++ char **value); + + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virAuthConfig, virAuthConfigFree); +diff --git a/tests/virauthconfigtest.c b/tests/virauthconfigtest.c +index 20855f004e..a88b453543 100644 +--- a/tests/virauthconfigtest.c ++++ b/tests/virauthconfigtest.c +@@ -42,7 +42,7 @@ struct ConfigLookupData { + static int testAuthLookup(const void *args) + { + const struct ConfigLookupData *data = args; +- const char *actual = NULL; ++ g_autofree char *actual = NULL; + int rv; + + rv = virAuthConfigLookup(data->config, +-- +2.33.0 + diff --git a/util-Skip-over-any-extra-verbiage-preceding-version-.patch b/util-Skip-over-any-extra-verbiage-preceding-version-.patch new file mode 100644 index 0000000000000000000000000000000000000000..35c82265718ab74135ea986aa70c891a994871ce --- /dev/null +++ b/util-Skip-over-any-extra-verbiage-preceding-version-.patch @@ -0,0 +1,62 @@ +From bd463a77381e3233d3529fa445c0f57b7851006c Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Thu, 7 Jan 2021 20:03:05 -0500 +Subject: [PATCH 081/108] util: Skip over any extra verbiage preceding version + in dnsmasq version string +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +dnsmasq usually prints out a version string like this: + + Dnsmasq version 2.82 [...] + +but a user reported that the build of dnsmasq included with pihole has +a version string like this: + + Dnsmasq version pi-hole-2.81 [...] + +We parse the dnsmasq version number to figure out if the dnsmasq +binary supports certain features. Since we expect the version number +(and it must be only numbers!) to start on the first non-space after +the string "Dnsmasq version", we fail to parse this format of the +version string. + +Rather than spending a bunch of time trying to get pihole to change +that, we can just make our parsing more permissive - after searching +for "Dnsmasq version", we'll skip ahead to the first decimal digit, +rather than just the first non-space. + +(NB: The features we're checking for purely by looking at version +number have been in all releases of dnsmasq since at least 2012, so we +could actually just remove the reading of the version number +completely. However it's possible (although *highly* unlikely) +that some new feature would be added to dnsmasq in the future and we +would need to add that code back.) + +Resolves: https://gitlab.com/libvirt/libvirt/-/issues/29 +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +(cherry picked from commit a4be2e35db39df87fe70a638cf64c32be74f1a55) +--- + src/util/virdnsmasq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/virdnsmasq.c b/src/util/virdnsmasq.c +index adc6f96bb6..5a329ae278 100644 +--- a/src/util/virdnsmasq.c ++++ b/src/util/virdnsmasq.c +@@ -648,7 +648,9 @@ dnsmasqCapsSetFromBuffer(dnsmasqCapsPtr caps, const char *buf) + p = STRSKIP(buf, DNSMASQ_VERSION_STR); + if (!p) + goto fail; +- virSkipSpaces(&p); ++ ++ virSkipToDigit(&p); ++ + if (virParseVersionString(p, &caps->version, true) < 0) + goto fail; + +-- +2.33.0 + diff --git a/util-avoid-race-in-releasing-the-GSource-in-event-th.patch b/util-avoid-race-in-releasing-the-GSource-in-event-th.patch new file mode 100644 index 0000000000000000000000000000000000000000..17b44e4012ab09394e8450c84ee40ec02dd78efd --- /dev/null +++ b/util-avoid-race-in-releasing-the-GSource-in-event-th.patch @@ -0,0 +1,128 @@ +From 55e288946ccda11131fd36a3f62c4c91ad93dde1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 29 Jul 2020 17:51:53 +0100 +Subject: [PATCH 001/108] util: avoid race in releasing the GSource in event + thread +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is a race between vir_event_thread_finalize and +virEventThreadWorker in releasing the last reference on +the GMainContext. If virEventThreadDataFree() runs after +vir_event_thread_finalize releases its reference, then +it will release the last reference on the GMainContext. +As a result g_autoptr cleanup on the GSource will access +free'd memory. + +The race can be seen in non-deterministic crashes of the +virt-run-qemu program during its shutdown, but could +also likely affect the main libvirtd QEMU driver: + + Thread 2 (Thread 0x7f508ffff700 (LWP 222813)): + #0 0x00007f509c8e26b0 in malloc_consolidate (av=av@entry=0x7f5088000020) at malloc.c:4488 + #1 0x00007f509c8e4b08 in _int_malloc (av=av@entry=0x7f5088000020, bytes=bytes@entry=2048) at malloc.c:3711 + #2 0x00007f509c8e6412 in __GI___libc_malloc (bytes=2048) at malloc.c:3073 + #3 0x00007f509d6e925e in g_realloc (mem=0x0, n_bytes=2048) at gmem.c:164 + #4 0x00007f509d705a57 in g_string_maybe_expand (string=string@entry=0x7f5088001f20, len=len@entry=1024) at gstring.c:102 + #5 0x00007f509d705ab6 in g_string_sized_new (dfl_size=dfl_size@entry=1024) at gstring.c:127 + #6 0x00007f509d708c5e in g_test_log_dump (len=, msg=) at gtestutils.c:3330 + #7 0x00007f509d708c5e in g_test_log + (lbit=G_TEST_LOG_ERROR, string1=0x7f508800fcb0 "GLib:ERROR:ghash.c:377:g_hash_table_lookup_node: assertion failed: (hash_table->ref_count > 0)", string2=, n_args=0, largs=0x0) at gtestutils.c:975 + #8 0x00007f509d70af2a in g_assertion_message + (domain=, file=0x7f509d7324a2 "ghash.c", line=, func=0x7f509d732750 <__func__.11348> "g_hash_table_lookup_node", message=) + at gtestutils.c:2504 + #9 0x00007f509d70af8e in g_assertion_message_expr + (domain=domain@entry=0x7f509d72d76e "GLib", file=file@entry=0x7f509d7324a2 "ghash.c", line=line@entry=377, func=func@entry=0x7f509d732750 <__func__.11348> "g_hash_table_lookup_node", expr=expr@entry=0x7f509d732488 "hash_table->ref_count > 0") at gtestutils.c:2555 + #10 0x00007f509d6d197e in g_hash_table_lookup_node (hash_table=0x55b70ace1760, key=, hash_return=) at ghash.c:377 + #11 0x00007f509d6d197e in g_hash_table_lookup_node (hash_return=, key=, hash_table=0x55b70ace1760) at ghash.c:361 + #12 0x00007f509d6d197e in g_hash_table_remove_internal (hash_table=0x55b70ace1760, key=, notify=1) at ghash.c:1371 + #13 0x00007f509d6e0664 in g_source_unref_internal (source=0x7f5088000b60, context=0x55b70ad87e00, have_lock=0) at gmain.c:2103 + #14 0x00007f509d6e1f64 in g_source_unref (source=) at gmain.c:2176 + #15 0x00007f50a08ff84c in glib_autoptr_cleanup_GSource (_ptr=) at /usr/include/glib-2.0/glib/glib-autocleanups.h:58 + #16 0x00007f50a08ff84c in virEventThreadWorker (opaque=0x55b70ad87f80) at ../../src/util/vireventthread.c:114 + #17 0x00007f509d70bd4a in g_thread_proxy (data=0x55b70acf3850) at gthread.c:784 + #18 0x00007f509d04714a in start_thread (arg=) at pthread_create.c:479 + #19 0x00007f509c95cf23 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 + + Thread 1 (Thread 0x7f50a1380c00 (LWP 222802)): + #0 0x00007f509c8977ff in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 + #1 0x00007f509c881c35 in __GI_abort () at abort.c:79 + #2 0x00007f509d72a823 in g_mutex_clear (mutex=0x55b70ad87e00) at gthread-posix.c:1307 + #3 0x00007f509d72a823 in g_mutex_clear (mutex=mutex@entry=0x55b70ad87e00) at gthread-posix.c:1302 + #4 0x00007f509d6e1a84 in g_main_context_unref (context=0x55b70ad87e00) at gmain.c:582 + #5 0x00007f509d6e1a84 in g_main_context_unref (context=0x55b70ad87e00) at gmain.c:541 + #6 0x00007f50a08ffabb in vir_event_thread_finalize (object=0x55b70ad83180 [virEventThread]) at ../../src/util/vireventthread.c:50 + #7 0x00007f509d9c48a9 in g_object_unref (_object=) at gobject.c:3340 + #8 0x00007f509d9c48a9 in g_object_unref (_object=0x55b70ad83180) at gobject.c:3232 + + #9 0x00007f509583d311 in qemuProcessQMPFree (proc=proc@entry=0x55b70ad87b90) at ../../src/qemu/qemu_process.c:8355 + #10 0x00007f5095790f58 in virQEMUCapsInitQMPSingle + (qemuCaps=qemuCaps@entry=0x55b70ad88010, libDir=libDir@entry=0x55b70ad049e0 "/tmp/virt-qemu-run-VZC9N0/lib/qemu", runUid=runUid@entry=107, runGid=runGid@entry=107, onlyTCG=onlyTCG@entry=false) at ../../src/qemu/qemu_capabilities.c:5409 + #11 0x00007f509579108f in virQEMUCapsInitQMP (runGid=107, runUid=107, libDir=0x55b70ad049e0 "/tmp/virt-qemu-run-VZC9N0/lib/qemu", qemuCaps=0x55b70ad88010) + at ../../src/qemu/qemu_capabilities.c:5420 + #12 0x00007f509579108f in virQEMUCapsNewForBinaryInternal + (hostArch=VIR_ARCH_X86_64, binary=binary@entry=0x55b70ad7dc40 "/usr/libexec/qemu-kvm", libDir=0x55b70ad049e0 "/tmp/virt-qemu-run-VZC9N0/lib/qemu", runUid=107, runGid=107, hostCPUSignature=0x55b70ad01320 "GenuineIntel, Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz, family: 6, model: 85, stepping: 7", microcodeVersion=83898113, kernelVersion=0x55b70ad00d60 "4.18.0-211.el8.x86_64 #1 SMP Thu Jun 4 08:08:16 UTC 2020") at ../../src/qemu/qemu_capabilities.c:5472 + #13 0x00007f5095791373 in virQEMUCapsNewData (binary=0x55b70ad7dc40 "/usr/libexec/qemu-kvm", privData=0x55b70ad5b8f0) at ../../src/qemu/qemu_capabilities.c:5505 + #14 0x00007f50a09a32b1 in virFileCacheNewData (name=0x55b70ad7dc40 "/usr/libexec/qemu-kvm", cache=) at ../../src/util/virfilecache.c:208 + #15 0x00007f50a09a32b1 in virFileCacheValidate (cache=cache@entry=0x55b70ad5c030, name=name@entry=0x55b70ad7dc40 "/usr/libexec/qemu-kvm", data=data@entry=0x7ffca39ffd90) + at ../../src/util/virfilecache.c:277 + #16 0x00007f50a09a37ea in virFileCacheLookup (cache=cache@entry=0x55b70ad5c030, name=name@entry=0x55b70ad7dc40 "/usr/libexec/qemu-kvm") at ../../src/util/virfilecache.c:310 + #17 0x00007f5095791627 in virQEMUCapsCacheLookup (cache=0x55b70ad5c030, binary=0x55b70ad7dc40 "/usr/libexec/qemu-kvm") at ../../src/qemu/qemu_capabilities.c:5647 + #18 0x00007f50957c34c3 in qemuDomainPostParseDataAlloc (def=, parseFlags=, opaque=, parseOpaque=0x7ffca39ffe18) + at ../../src/qemu/qemu_domain.c:5470 + #19 0x00007f50a0a34051 in virDomainDefPostParse + (def=def@entry=0x55b70ad7d200, parseFlags=parseFlags@entry=258, xmlopt=xmlopt@entry=0x55b70ad5d010, parseOpaque=parseOpaque@entry=0x0) + at ../../src/conf/domain_conf.c:5970 + #20 0x00007f50a0a464bb in virDomainDefParseNode + (xml=xml@entry=0x55b70aced140, root=root@entry=0x55b70ad5f020, xmlopt=xmlopt@entry=0x55b70ad5d010, parseOpaque=parseOpaque@entry=0x0, flags=flags@entry=258) + at ../../src/conf/domain_conf.c:22520 + #21 0x00007f50a0a4669b in virDomainDefParse + (xmlStr=xmlStr@entry=0x55b70ad5f9e0 "\n 83\n 9350639d-1c8a-4f51-a4a6-4eaf8eabe83e\n \n \n <"..., filename=filename@entry=0x0, xmlopt=0x55b70ad5d010, parseOpaque=parseOpaque@entry=0x0, flags=flags@entry=258) at ../../src/conf/domain_conf.c:22474 + #22 0x00007f50a0a467ae in virDomainDefParseString + (xmlStr=xmlStr@entry=0x55b70ad5f9e0 "\n 83\n 9350639d-1c8a-4f51-a4a6-4eaf8eabe83e\n \n \n <"..., xmlopt=, parseOpaque=parseOpaque@entry=0x0, flags=flags@entry=258) + at ../../src/conf/domain_conf.c:22488 + #23 0x00007f50958ce112 in qemuDomainCreateXML + (conn=0x55b70acf9090, xml=0x55b70ad5f9e0 "\n 83\n 9350639d-1c8a-4f51-a4a6-4eaf8eabe83e\n \n \n <"..., flags=0) at ../../src/qemu/qemu_driver.c:1744 + #24 0x00007f50a0c268ac in virDomainCreateXML + (conn=0x55b70acf9090, xmlDesc=0x55b70ad5f9e0 "\n 83\n 9350639d-1c8a-4f51-a4a6-4eaf8eabe83e\n \n \n <"..., flags=0) at ../../src/libvirt-domain.c:176 + #25 0x000055b709547e7b in main (argc=, argv=) at ../../src/qemu/qemu_shim.c:289 + +The solution is to explicitly unref the GSource at a safe time instead +of letting g_autoptr unref it when leaving scope. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 2998ba2012ea7997f2b233b2b81879fea3ee1b6a) +--- + src/util/vireventthread.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/util/vireventthread.c b/src/util/vireventthread.c +index cf865925eb..485672278a 100644 +--- a/src/util/vireventthread.c ++++ b/src/util/vireventthread.c +@@ -111,7 +111,11 @@ static void * + virEventThreadWorker(void *opaque) + { + virEventThreadData *data = opaque; +- g_autoptr(GSource) running = g_idle_source_new(); ++ /* ++ * Do NOT use g_autoptr on this. We need to unref it ++ * before the GMainContext is unrefed ++ */ ++ GSource *running = g_idle_source_new(); + + g_source_set_callback(running, virEventThreadNotify, data, NULL); + +@@ -119,6 +123,7 @@ virEventThreadWorker(void *opaque) + + g_main_loop_run(data->loop); + ++ g_source_unref(running); + virEventThreadDataFree(data); + + return NULL; +-- +2.33.0 + diff --git a/util-event-check-return-value-of-virInitialize.patch b/util-event-check-return-value-of-virInitialize.patch new file mode 100644 index 0000000000000000000000000000000000000000..bccea8b6fca0b112ee3d1182c8d30c7550408285 --- /dev/null +++ b/util-event-check-return-value-of-virInitialize.patch @@ -0,0 +1,35 @@ +From c8f1809df2bc40720415a6043f86aabaecd1490e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 22 Sep 2020 23:17:18 +0200 +Subject: [PATCH 030/108] util: event: check return value of virInitialize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This function can possibly fail. + +Signed-off-by: Ján Tomko +Fixes: 2e07a1e14635ad25c57b66c13488feff4c8d2b0c +Reviewed-by: Peter Krempa +(cherry picked from commit a95fc756271d2371c5ae947840458c572d83fd13) +--- + src/util/virevent.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util/virevent.c b/src/util/virevent.c +index 3477d63554..f6eb806faf 100644 +--- a/src/util/virevent.c ++++ b/src/util/virevent.c +@@ -305,7 +305,8 @@ int virEventRegisterDefaultImpl(void) + { + VIR_DEBUG("registering default event implementation"); + +- virInitialize(); ++ if (virInitialize() < 0) ++ return -1; + + virResetLastError(); + +-- +2.33.0 + diff --git a/util-fix-cache-invalidation-of-swtpm-capabilities.patch b/util-fix-cache-invalidation-of-swtpm-capabilities.patch new file mode 100644 index 0000000000000000000000000000000000000000..731331a111693a846ada91dfabce02aa26808237 --- /dev/null +++ b/util-fix-cache-invalidation-of-swtpm-capabilities.patch @@ -0,0 +1,46 @@ +From 7aee8a63e2ad8aac9fc0c0902e1c6e406a6b149f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 24 Nov 2021 10:56:02 +0000 +Subject: [PATCH 105/108] util: fix cache invalidation of swtpm capabilities +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The check for whether the swtpm binary was modified is checking pointers +to the mtime field in two distinct structs, so will always compare +different. This resulted in re-probing swtpm capabilities every time, +as many as 20 times for a single VM launch. + +Fixes: + + commit 01cf7a1bb9f1da27ad8bcbaa82c4f7a948c6a793 + Author: Stefan Berger + Date: Thu Jul 25 14:22:04 2019 -0400 + + tpm: Check whether previously found executables were updated + +Reviewed-by: Michal Privoznik +Reviewed-by: Martin Kletzander +Reviewed-by: Ján Tomko +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit e18fff6c85485e45ea17385862b80af9dc37383e) +--- + src/util/virtpm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virtpm.c b/src/util/virtpm.c +index 1a61a92f69..79e1c3cd6a 100644 +--- a/src/util/virtpm.c ++++ b/src/util/virtpm.c +@@ -298,7 +298,7 @@ virTPMEmulatorInit(void) + findit = true; + + if (!findit && +- &statbuf.st_mtime != &prgs[i].stat->st_mtime) ++ statbuf.st_mtime != prgs[i].stat->st_mtime) + findit = true; + } + +-- +2.33.0 + diff --git a/util-fix-very-old-bug-typo-in-virNetDevParseVfInfo.patch b/util-fix-very-old-bug-typo-in-virNetDevParseVfInfo.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ef70af3773af2fd926a795d4498e7da1895625d --- /dev/null +++ b/util-fix-very-old-bug-typo-in-virNetDevParseVfInfo.patch @@ -0,0 +1,56 @@ +From 416267baaa37a7ada0b9fc0f78c7d9be3df3c52e Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Tue, 20 Oct 2020 22:31:27 -0400 +Subject: [PATCH 073/108] util: fix very old bug/typo in virNetDevParseVfInfo() + +When this function was recently changed to add in parsing of +IFLA_VF_STATS, I noticed that the checks for existence of IFLA_VF_MAC +and IFLA_VF_VLAN were looking in the *wrong array*. The array that +contains the results of parsing each IFLA_VFINFO in +tb[IFLA_VFINFO_LIST] is tb_vf, but we were checking for these in tb +(which is the array containing the results of the toplevel parsing of +the netlink message, *not* the results of parsing one of the nested +IFLA_VFINFO's. + +This incorrect code has been here since the function was originally +written in 2012. It has only worked all these years due to coincidence +- the items at those indexes in tb are IFLA_ADDRESS and IFLA_BROADCAST +(of the *PF*, not of any of its VFs), and those happen to always be +present in the toplevel netlink message; since we are only looking in +the incorrect place to check for mere existence of the attribute (but +are doing the actual retrieval of the attribute from the correct +place), this bug has no real consequences other than confusing anyone +trying to understand the code. + +Signed-off-by: Laine Stump +Reviewed-by: Michal Privoznik +(cherry picked from commit 6bd4505dea60b66203d82b3636bc9c51a557629f) +--- + src/util/virnetdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index ff86aa1fc9..950844b110 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -1713,7 +1713,7 @@ virNetDevParseVfConfig(struct nlattr **tb, int32_t vf, virMacAddrPtr mac, + return rc; + } + +- if (mac && tb[IFLA_VF_MAC]) { ++ if (mac && tb_vf[IFLA_VF_MAC]) { + vf_mac = RTA_DATA(tb_vf[IFLA_VF_MAC]); + if (vf_mac && vf_mac->vf == vf) { + virMacAddrSetRaw(mac, vf_mac->mac); +@@ -1721,7 +1721,7 @@ virNetDevParseVfConfig(struct nlattr **tb, int32_t vf, virMacAddrPtr mac, + } + } + +- if (vlanid && tb[IFLA_VF_VLAN]) { ++ if (vlanid && tb_vf[IFLA_VF_VLAN]) { + vf_vlan = RTA_DATA(tb_vf[IFLA_VF_VLAN]); + if (vf_vlan && vf_vlan->vf == vf) { + *vlanid = vf_vlan->vlan; +-- +2.33.0 + diff --git a/util-new-function-virSkipToDigit.patch b/util-new-function-virSkipToDigit.patch new file mode 100644 index 0000000000000000000000000000000000000000..9da7aa6c018ffceef70cc6c938a1d124ad18c368 --- /dev/null +++ b/util-new-function-virSkipToDigit.patch @@ -0,0 +1,77 @@ +From 6282c4e163751149ade6d5407229644fd41d5fbb Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Thu, 7 Jan 2021 19:55:43 -0500 +Subject: [PATCH 080/108] util: new function virSkipToDigit() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This function skips over the beginning of a string until it reaches a +decimal digit (0-9) or the NULL at the end of the string. The original +pointer is modified in place (similar to virSkipSpaces()). + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +(cherry picked from commit 0e89a7b4e0defb2b3711c1e854a51d296d7b6f7f) +--- + src/libvirt_private.syms | 1 + + src/util/virstring.c | 18 ++++++++++++++++++ + src/util/virstring.h | 1 + + 3 files changed, 20 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 997039868e..4d54c5e42f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3172,6 +3172,7 @@ virStorageFileBackendRegister; + virSkipSpaces; + virSkipSpacesAndBackslash; + virSkipSpacesBackwards; ++virSkipToDigit; + virStrcpy; + virStringBufferIsPrintable; + virStringFilterChars; +diff --git a/src/util/virstring.c b/src/util/virstring.c +index e9e792f3bf..56c5e37def 100644 +--- a/src/util/virstring.c ++++ b/src/util/virstring.c +@@ -817,6 +817,24 @@ virSkipSpacesAndBackslash(const char **str) + *str = cur; + } + ++ ++/** ++ * virSkipToDigit: ++ * @str: pointer to the char pointer used ++ * ++ * Skip over any character that is not 0-9 ++ */ ++void ++virSkipToDigit(const char **str) ++{ ++ const char *cur = *str; ++ ++ while (*cur && !g_ascii_isdigit(*cur)) ++ cur++; ++ *str = cur; ++} ++ ++ + /** + * virTrimSpaces: + * @str: string to modify to remove all trailing spaces +diff --git a/src/util/virstring.h b/src/util/virstring.h +index 360c68395c..878da86c33 100644 +--- a/src/util/virstring.h ++++ b/src/util/virstring.h +@@ -117,6 +117,7 @@ int virDoubleToStr(char **strp, double number) + + void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1); + void virSkipSpacesAndBackslash(const char **str) ATTRIBUTE_NONNULL(1); ++void virSkipToDigit(const char **str) ATTRIBUTE_NONNULL(1); + void virTrimSpaces(char *str, char **endp) ATTRIBUTE_NONNULL(1); + void virSkipSpacesBackwards(const char *str, char **endp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +-- +2.33.0 + diff --git a/util-virExec-may-blocked-by-reading-pipe-if-grandchi.patch b/util-virExec-may-blocked-by-reading-pipe-if-grandchi.patch new file mode 100644 index 0000000000000000000000000000000000000000..2bd7ef4e6894163466a05b6f2178555c3ea32980 --- /dev/null +++ b/util-virExec-may-blocked-by-reading-pipe-if-grandchi.patch @@ -0,0 +1,38 @@ +From 5122e578df1760c5e576682e3f84a1d18dbfca5d Mon Sep 17 00:00:00 2001 +From: Xu Chao +Date: Wed, 24 Nov 2021 10:33:11 +0800 +Subject: [PATCH 104/108] util: virExec may blocked by reading pipe if + grandchild prematurely exit + +When VIR_EXEC_DAEMON is set, if virPidFileAcquirePath/virSetInherit failed, +then pipesync[0] can not be closed when granchild process exit, because +pipesync[1] still opened in child process. and then saferead in child +process may blocked forever, and left grandchild process in defunct state. + +Signed-off-by: Xu Chao +Signed-off-by: Yi Wang +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit 6fac961b085af51340246bf51205a9f2f1615962) +--- + src/util/vircommand.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index 8ab83cb8f5..bb824bf60f 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -775,6 +775,10 @@ virExec(virCommandPtr cmd) + } + + if (pid > 0) { ++ /* At this point it's us and the child that holds the write end of ++ * the pipe open. Close the write end of the pipe, so that the pipe ++ * is fully closed if child dies prematurely. */ ++ VIR_FORCE_CLOSE(pipesync[1]); + /* The parent expect us to have written the pid file before + * exiting. Wait here for the child to write it and signal us. */ + if (cmd->pidfile && +-- +2.33.0 + diff --git a/util-virIdentitySetCurrent-only-unref-the-old-identi.patch b/util-virIdentitySetCurrent-only-unref-the-old-identi.patch new file mode 100644 index 0000000000000000000000000000000000000000..0c3191ed75fff9eb519644427c6fb27f6beed98a --- /dev/null +++ b/util-virIdentitySetCurrent-only-unref-the-old-identi.patch @@ -0,0 +1,46 @@ +From 8a06893a603f32791899314fd16afdd424e77e6a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Fri, 3 Sep 2021 16:04:44 +0200 +Subject: [PATCH 100/108] util: virIdentitySetCurrent: only unref the old + identity on success +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the unlikely case that we were unable to set the new +identity, we would unref the old one even though it still +could be in the thread-local storage. + +Fixes: c6825d88137cb8e4debdf4310e45ee23cb5698c0 +Signed-off-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit a082c462290bfa8fd4cbbc41c1d6040864228c78) +--- + src/util/viridentity.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/viridentity.c b/src/util/viridentity.c +index 2cb9042a84..e133d29e7d 100644 +--- a/src/util/viridentity.c ++++ b/src/util/viridentity.c +@@ -122,7 +122,7 @@ virIdentityPtr virIdentityGetCurrent(void) + */ + int virIdentitySetCurrent(virIdentityPtr ident) + { +- g_autoptr(virIdentity) old = NULL; ++ virIdentity *old = NULL; + + if (virIdentityInitialize() < 0) + return -1; +@@ -138,6 +138,8 @@ int virIdentitySetCurrent(virIdentityPtr ident) + return -1; + } + ++ if (old) ++ g_object_unref(old); + return 0; + } + +-- +2.33.0 + diff --git a/vahDeinit-Fix-memory-leak.patch b/vahDeinit-Fix-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..73c74efaaf4c48e2112a6f3c32c0907d1acd6d0b --- /dev/null +++ b/vahDeinit-Fix-memory-leak.patch @@ -0,0 +1,35 @@ +From adc93f772bd3552be91ca53cf62bb81e9c6737e2 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Thu, 22 Apr 2021 15:07:33 +0200 +Subject: [PATCH 051/108] vahDeinit: Fix memory leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Calling VIR_FREE on a virDomainDef* does not free its various contained +pointers. + +Signed-off-by: Tim Wiederhake +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +(cherry picked from commit 9ac2ca799a48388ac1d3c561b99bfbe039d17cca) +--- + src/security/virt-aa-helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c +index 8526b7b985..9c9b844146 100644 +--- a/src/security/virt-aa-helper.c ++++ b/src/security/virt-aa-helper.c +@@ -78,7 +78,7 @@ vahDeinit(vahControl * ctl) + if (ctl == NULL) + return -1; + +- VIR_FREE(ctl->def); ++ virDomainDefFree(ctl->def); + virObjectUnref(ctl->caps); + virObjectUnref(ctl->xmlopt); + VIR_FREE(ctl->files); +-- +2.33.0 + diff --git a/virBufferAdd-Ensure-that-the-buffer-is-initialized-a.patch b/virBufferAdd-Ensure-that-the-buffer-is-initialized-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0d5237b25d21f8f49ec2e58ab5b703a94d6aaba --- /dev/null +++ b/virBufferAdd-Ensure-that-the-buffer-is-initialized-a.patch @@ -0,0 +1,52 @@ +From 56b44fe637c040187338b51a401d8cc2f1d60612 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 4 Mar 2021 18:09:42 +0100 +Subject: [PATCH 018/108] virBufferAdd: Ensure that the buffer is initialized + also when len == 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There's an optimization in virBufferAdd which returns early when the +length of the added string is 0 (given that auto-indent is disabled). + +The optimization causes inconsistent behaviour between these two cases: + + virBufferAdd(buf, "", 0); // this doesn't initialize the buffer + +and + + virBufferAdd(buf, "", -1); //this initializes the buffer + +Since using an empty string is used to prime the buffer to an empty +string it can be confusing. Remove the optimization. + +This fixes such a wrong initialization done in x86FeatureNames. + +Note that our code in many places expects that if no virBuffer APIs are +used on a buffer object, then NULL should be retured, so we can't always +prime the buffer to an empty string. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 1553e7256701c725cf87bafa5d738da16f278c3d) +--- + src/util/virbuffer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c +index b78c3debe9..1fd055f77d 100644 +--- a/src/util/virbuffer.c ++++ b/src/util/virbuffer.c +@@ -156,7 +156,7 @@ virBufferApplyIndent(virBufferPtr buf) + void + virBufferAdd(virBufferPtr buf, const char *str, int len) + { +- if (!str || !buf || (len == 0 && buf->indent == 0)) ++ if (!str || !buf) + return; + + virBufferInitialize(buf); +-- +2.33.0 + diff --git a/virCPUDefFindFeature-Make-first-argument-const-ptr.patch b/virCPUDefFindFeature-Make-first-argument-const-ptr.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7a53ce4e949d78883b57cf740cc034af692064e --- /dev/null +++ b/virCPUDefFindFeature-Make-first-argument-const-ptr.patch @@ -0,0 +1,42 @@ +From 993e67d6fcd79d3fb9c96a805b8c3882206c3b2c Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Tue, 23 Mar 2021 11:01:53 +0100 +Subject: [PATCH 092/108] virCPUDefFindFeature: Make first argument const ptr + +Signed-off-by: Tim Wiederhake +Reviewed-by: Jiri Denemark +Date: Tue, 4 May 2021 08:21:59 +0200 +Subject: [PATCH 054/108] virCapabilitiesHostNUMAInitReal: Free @cpus properly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The @cpus variable is an array of structs in which each item +contains a virBitmap member. As such it is not enough to just +VIR_FREE() the array - each bitmap has to be freed too. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 26a24a702c47403effadb355b7e37f7cf5a488db) +--- + src/conf/capabilities.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index 99b69aebb5..d6ec1f12f4 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -1690,6 +1690,7 @@ virCapabilitiesHostNUMAInitReal(virCapsHostNUMAPtr caps) + + cleanup: + virBitmapFree(cpumap); ++ virCapabilitiesClearHostNUMACellCPUTopology(cpus, ncpus); + VIR_FREE(cpus); + VIR_FREE(siblings); + VIR_FREE(pageinfo); +-- +2.33.0 + diff --git a/virFileReadLimFD-Cast-maxlen-to-size_t-before-adding.patch b/virFileReadLimFD-Cast-maxlen-to-size_t-before-adding.patch new file mode 100644 index 0000000000000000000000000000000000000000..b3749ce14db9060c43d753e694d804cd234da2bb --- /dev/null +++ b/virFileReadLimFD-Cast-maxlen-to-size_t-before-adding.patch @@ -0,0 +1,34 @@ +From 6c70b9987df7b3c2e82b88513ad6f5ebbe87065a Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Thu, 22 Jul 2021 10:30:21 +0200 +Subject: [PATCH 095/108] virFileReadLimFD: Cast maxlen to size_t before adding +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the function is called with maxlen equal to `INT_MAX`, adding +one will trigger a signed integer overflow. + +Signed-off-by: Tim Wiederhake +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 2ed93ed979170c3310ace5cdf75a99873ba9d317) +--- + src/util/virfile.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 20260a2e58..74eae7658e 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -1423,7 +1423,7 @@ virFileReadLimFD(int fd, int maxlen, char **buf) + errno = EINVAL; + return -1; + } +- s = saferead_lim(fd, maxlen+1, &len); ++ s = saferead_lim(fd, (size_t) maxlen + 1, &len); + if (s == NULL) + return -1; + if (len > maxlen || (int)len != len) { +-- +2.33.0 + diff --git a/virNodeDevPCICapSRIOVVirtualParseXML-fix-memleak-of-.patch b/virNodeDevPCICapSRIOVVirtualParseXML-fix-memleak-of-.patch new file mode 100644 index 0000000000000000000000000000000000000000..fcf8bb0e3c6d6367af3f2dd96c271e6a2d14bcbb --- /dev/null +++ b/virNodeDevPCICapSRIOVVirtualParseXML-fix-memleak-of-.patch @@ -0,0 +1,41 @@ +From d707abe3210f4bdc723aefdf8e99710efc78edea Mon Sep 17 00:00:00 2001 +From: Hao Wang +Date: Thu, 30 Jul 2020 20:03:08 +0800 +Subject: [PATCH 040/108] virNodeDevPCICapSRIOVVirtualParseXML: fix memleak of + addr + +virPCIDeviceAddressPtr 'addr' is forgotten to be freed in the branch +'VIR_APPEND_ELEMENT() < 0'. Use g_autoptr instead. + +Signed-off-by: Hao Wang +Reviewed-by: Michal Privoznik +(cherry picked from commit f7f5b86be25d27915cc67a8b84fa9a2589df4ab8) +--- + src/conf/node_device_conf.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c +index 4cf5b6e3d7..d64f6d3986 100644 +--- a/src/conf/node_device_conf.c ++++ b/src/conf/node_device_conf.c +@@ -1503,15 +1503,13 @@ virNodeDevPCICapSRIOVVirtualParseXML(xmlXPathContextPtr ctxt, + goto cleanup; + + for (i = 0; i < naddresses; i++) { +- virPCIDeviceAddressPtr addr = NULL; ++ g_autoptr(virPCIDeviceAddress) addr = NULL; + + if (VIR_ALLOC(addr) < 0) + goto cleanup; + +- if (virPCIDeviceAddressParseXML(addresses[i], addr) < 0) { +- VIR_FREE(addr); ++ if (virPCIDeviceAddressParseXML(addresses[i], addr) < 0) + goto cleanup; +- } + + if (VIR_APPEND_ELEMENT(pci_dev->virtual_functions, + pci_dev->num_virtual_functions, +-- +2.33.0 + diff --git a/virPipeImpl-Don-t-overwrite-error.patch b/virPipeImpl-Don-t-overwrite-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..de7c87c1f1f0e40d317e94b3434b1d72de85a160 --- /dev/null +++ b/virPipeImpl-Don-t-overwrite-error.patch @@ -0,0 +1,37 @@ +From 03f4080c80170f388f9d902e4f8db3c5d0a6eb10 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 1 Mar 2021 10:25:18 +0100 +Subject: [PATCH 017/108] virPipeImpl: Don't overwrite error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If WITH_PIPE2 is not defined we attempt to set the pipe to nonblocking +operation after they are created. We errorneously rewrote the existing +error message on failure to do so or even reported an error if quiet +mode was requested. + +Fixes: ab36f729470c313b9d5b7debdbeac441f7780dec +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit ae87dc3d09cc26aa9b6587e4db73d42529dce69b) +--- + src/util/virutil.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/util/virutil.c b/src/util/virutil.c +index bea9749cae..ada3dae7c6 100644 +--- a/src/util/virutil.c ++++ b/src/util/virutil.c +@@ -1759,8 +1759,6 @@ virPipeImpl(int fds[2], bool nonblock, bool errreport) + if (errreport) + virReportSystemError(errno, "%s", + _("Unable to set pipes to non-blocking")); +- virReportSystemError(errno, "%s", +- _("Unable to create pipes")); + VIR_FORCE_CLOSE(fds[0]); + VIR_FORCE_CLOSE(fds[1]); + return -1; +-- +2.33.0 + diff --git a/virSecurityManagerMetadataLock-Clarify-directory-loc.patch b/virSecurityManagerMetadataLock-Clarify-directory-loc.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c4f3e11436cf6f2a90bd3b76e8b12564abd9d75 --- /dev/null +++ b/virSecurityManagerMetadataLock-Clarify-directory-loc.patch @@ -0,0 +1,37 @@ +From 027f0b2895a4f5fbf879d02f43ab1bb0489bd938 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 10 Jul 2020 10:42:01 +0200 +Subject: [PATCH 008/108] virSecurityManagerMetadataLock: Clarify directory + locking comment +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the light of recent commit of 9d83281382 fix the comment that +says directories can't be locked. Well, in general they can, but +not in our case. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 0a145de970af31e605d837c3502855fe93aaec9a) +--- + src/security/security_manager.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index 5159abd92d..9d5dfec12b 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -1331,7 +1331,8 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED, + continue; + + if (S_ISDIR(sb.st_mode)) { +- /* Directories can't be locked */ ++ /* We need to open the path for writing because we need exclusive ++ * (write) lock. But directories can't be opened for writing. */ + continue; + } + +-- +2.33.0 + diff --git a/virSecurityManagerMetadataLock-Ignore-RO-filesystem.patch b/virSecurityManagerMetadataLock-Ignore-RO-filesystem.patch new file mode 100644 index 0000000000000000000000000000000000000000..2986ac3685c42fbf00482a4e3a5db6a9c697761f --- /dev/null +++ b/virSecurityManagerMetadataLock-Ignore-RO-filesystem.patch @@ -0,0 +1,44 @@ +From 4f9226a33786ead60eb470f88783d8764a66e35a Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 10 Jul 2020 10:48:01 +0200 +Subject: [PATCH 007/108] virSecurityManagerMetadataLock: Ignore RO filesystem +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When locking files for metadata change, we open() them for R/W +access. The write access is needed because we want to acquire +exclusive (write) lock (to mutually exclude with other daemons +trying to modify XATTRs on the same file). Anyway, the open() +might fail if the file lives on a RO filesystem. Well, if that's +the case, ignore the error and continue with the next file on the +list. We won't change any seclabel on the file anyway - there is +nothing to remember then. + +Reported-by: Olaf Hering +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit c531f42755119190888ac73a58f93d79de5afa56) +--- + src/security/security_manager.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index 1445291410..5159abd92d 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -1336,6 +1336,11 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED, + } + + if ((fd = open(p, O_RDWR)) < 0) { ++ if (errno == EROFS) { ++ /* There is nothing we can do for RO filesystem. */ ++ continue; ++ } ++ + #ifndef WIN32 + if (S_ISSOCK(sb.st_mode)) { + /* Sockets can be opened only if there exists the +-- +2.33.0 + diff --git a/vircommand.c-write-child-pidfile-before-process-tuni.patch b/vircommand.c-write-child-pidfile-before-process-tuni.patch new file mode 100644 index 0000000000000000000000000000000000000000..1fdf5c5d3e5e6d92b705bed083c4959c801776fd --- /dev/null +++ b/vircommand.c-write-child-pidfile-before-process-tuni.patch @@ -0,0 +1,85 @@ +From ea6794e88ca66d730a6c0ba76a996ff59491176e Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Thu, 1 Oct 2020 10:34:24 -0300 +Subject: [PATCH 034/108] vircommand.c: write child pidfile before process + tuning in virExec() + +When VIR_EXEC_DAEMON is true and cmd->pidfile exists, the parent +will expect the pidfile to be written before exiting, sitting +tight in a saferead() call waiting. + +The child then does process tuning (via virProcessSet* functions) +before writing the pidfile. Problem is that these tunings can +fail, and trigger a 'fork_error' jump, before cmd->pidfile is +written. The result is that the process was aborted in the +child, but the parent is still hang in the saferead() call. + +This behavior can be reproduced by trying to create and execute +a QEMU guest in user mode (e.g. using qemu:///session as non-root). +virProcessSetMaxMemLock() will fail if the spawned libvirtd user +process does not have CAP_SYS_RESOURCE capability. setrlimit() will +fail, and a 'fork_error' jump is triggered before cmd->pidfile +is written. The parent will hung in saferead() indefinitely. From +the user perspective, 'virsh start ' will hang up +indefinitely. CTRL+C can be used to retrieve the terminal, but +any subsequent 'virsh' call will also hang because the previous +libvirtd user process is still there. + +We can fix this by moving all virProcessSet*() tuning functions +to be executed after cmd->pidfile is taken care of. In the case +mentioned above, this would be the result of 'virsh start' +after this patch: + +error: Failed to start domain vm1 +error: internal error: Process exited prior to exec: libvirt: error : +cannot limit locked memory to 79691776: Operation not permitted + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1882093 + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit 0bb796bda31103ebf54eefc11c471586c87b95fd) +--- + src/util/vircommand.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index 86e4c5cd39..8ab83cb8f5 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -787,15 +787,6 @@ virExec(virCommandPtr cmd) + } + } + +- if (virProcessSetMaxMemLock(0, cmd->maxMemLock) < 0) +- goto fork_error; +- if (virProcessSetMaxProcesses(0, cmd->maxProcesses) < 0) +- goto fork_error; +- if (virProcessSetMaxFiles(0, cmd->maxFiles) < 0) +- goto fork_error; +- if (cmd->setMaxCore && +- virProcessSetMaxCoreSize(0, cmd->maxCore) < 0) +- goto fork_error; + if (cmd->pidfile) { + int pidfilefd = -1; + char c; +@@ -820,6 +811,16 @@ virExec(virCommandPtr cmd) + /* pidfilefd is intentionally leaked. */ + } + ++ if (virProcessSetMaxMemLock(0, cmd->maxMemLock) < 0) ++ goto fork_error; ++ if (virProcessSetMaxProcesses(0, cmd->maxProcesses) < 0) ++ goto fork_error; ++ if (virProcessSetMaxFiles(0, cmd->maxFiles) < 0) ++ goto fork_error; ++ if (cmd->setMaxCore && ++ virProcessSetMaxCoreSize(0, cmd->maxCore) < 0) ++ goto fork_error; ++ + if (cmd->hook) { + VIR_DEBUG("Run hook %p %p", cmd->hook, cmd->opaque); + ret = cmd->hook(cmd->opaque); +-- +2.33.0 + diff --git a/vireventglib-Remove-handles-with-the-highest-priorit.patch b/vireventglib-Remove-handles-with-the-highest-priorit.patch new file mode 100644 index 0000000000000000000000000000000000000000..09aa7a36688048d491820ae3d0c441c4bc3e1206 --- /dev/null +++ b/vireventglib-Remove-handles-with-the-highest-priorit.patch @@ -0,0 +1,88 @@ +From 1a419107d7f9620cb6694c931450521a60b5c5f8 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 7 Oct 2021 13:46:43 +0200 +Subject: [PATCH 101/108] vireventglib: Remove handles with the highest + priority +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a server decides to close a client, the +virNetServerClientCloseLocked() is called. In here various +cleanup steps are taken, but the most important part (from this +commit's POV at least) is the way that the socket is closed. +Firstly, removal of the socket associated with the client from +the event loop is signalized and then the socket is unrefed. The +socket is not closed just yet though, because the event loop +holds a reference to it. This reference will be freed as soon as +the event loop wakes up and starts issuing callbacks (in this +case virNetSocketEventFree()). + +So far, this is how things usually work. But if the daemon +reaches the number of opened files limit, things start to work +differently. + +If the RLIMIT_NOFILE limit is reached and there's a client that +wants to connect then the event loop wakes up, sees POLLIN on the +socket and calls virNetServerServiceAccept() which in turn calls +virNetSocketAccept(). But because of the limit, accept() fails +with EMFILE leaving the POLLIN event unhandled. The dispatch then +continues to next FDs with events on them. BUT, it will NOT call +the socket removal callback (virNetSocketEventFree()) because it +has low priority (G_PRIORITY_DEFAULT_IDLE). Per glib's +documentation: + + * Each event source is assigned a priority. The default priority, + * %G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities. + * Values greater than 0 denote lower priorities. Events from high priority + * sources are always processed before events from lower priority sources. + +and per g_idle_add() documentation: + + * Adds a function to be called whenever there are no higher priority + * events pending to the default main loop. The function is given the + * default idle priority, %G_PRIORITY_DEFAULT_IDLE. + +Now, because we did not accept() the client we are constantly +seeing POLLIN on the main socket and thus the removal of the +client socket won't ever happen. + +The fix is to set at least the same priority as other sources, +but since we want to just close an FD, let's give it the highest +priority and call it before handling other events. + +This issue can be easily reproduced, for instance: + + # ulimit -S -n 40 (tweak this number if needed) + # ./src/libvirtd + +from another terminal: + + # for ((i=0; i<100; i++)); do virsh list & done; virsh list + +The last `virsh list` must not get stuck. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2007168 +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 5de203f8795d96229d2663e9ea1a24fba5db38fc) +--- + src/util/vireventglib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c +index 803332a6f8..47c2835552 100644 +--- a/src/util/vireventglib.c ++++ b/src/util/vireventglib.c +@@ -283,7 +283,7 @@ virEventGLibHandleRemove(int watch) + * 'removed' to prevent reuse + */ + data->removed = TRUE; +- g_idle_add(virEventGLibHandleRemoveIdle, data); ++ g_idle_add_full(G_PRIORITY_HIGH, virEventGLibHandleRemoveIdle, data, NULL); + + ret = 0; + +-- +2.33.0 + diff --git a/virnetdevbridge-Ignore-EEXIST-when-adding-an-entry-t.patch b/virnetdevbridge-Ignore-EEXIST-when-adding-an-entry-t.patch new file mode 100644 index 0000000000000000000000000000000000000000..4529c29e53a0288ed5f3f5191dca4f17f6fabcca --- /dev/null +++ b/virnetdevbridge-Ignore-EEXIST-when-adding-an-entry-t.patch @@ -0,0 +1,58 @@ +From 0cd5b4ef642e65e8e8ba35306700e2084a39fdab Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Fri, 30 Apr 2021 17:25:29 +0200 +Subject: [PATCH 052/108] virnetdevbridge: Ignore EEXIST when adding an entry + to fdb + +When updating entries in a bridge forwarding database (i.e., when +macTableManager='libvirt' is configured for the bridge), we may end up +in a situation when the entry we want to add is already present. Let's +just ignore the error in such a case. + +This fixes an error to resume a domain when fdb entries were not +properly removed when the domain was paused: + + virsh # resume test + error: Failed to resume domain test + error: error adding fdb entry for vnet2: File exists + +For some reason, fdb entries are only removed when libvirt explicitly +stops CPUs, but nothing happens when we just get STOP event from QEMU. +An alternative approach would be to make sure we always remove the +entries regardless on why a domain was paused (e.g., during migration), +but that would be a significantly more disruptive change with possible +side effects. + +https://bugzilla.redhat.com/show_bug.cgi?id=1603155 + +Signed-off-by: Jiri Denemark +Reviewed-by: Laine Stump +(cherry picked from commit 241c22a9a531cb39d2b6b892561fe856f32f310d) +--- + src/util/virnetdevbridge.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c +index e1ba119b8b..49e5f830ea 100644 +--- a/src/util/virnetdevbridge.c ++++ b/src/util/virnetdevbridge.c +@@ -1065,9 +1065,13 @@ virNetDevBridgeFDBAddDel(const virMacAddr *mac, const char *ifname, + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + if (err->error) { +- virReportSystemError(-err->error, +- _("error adding fdb entry for %s"), ifname); +- return -1; ++ if (isAdd && -err->error == EEXIST) { ++ VIR_DEBUG("fdb entry for %s already exists", ifname); ++ } else { ++ virReportSystemError(-err->error, ++ _("error adding fdb entry for %s"), ifname); ++ return -1; ++ } + } + break; + case NLMSG_DONE: +-- +2.33.0 + diff --git a/virnettlscontext-Don-t-pass-static-key-length-to-gnu.patch b/virnettlscontext-Don-t-pass-static-key-length-to-gnu.patch new file mode 100644 index 0000000000000000000000000000000000000000..7123f9515b14ad40e188e30402159cc8ded3a669 --- /dev/null +++ b/virnettlscontext-Don-t-pass-static-key-length-to-gnu.patch @@ -0,0 +1,74 @@ +From 096e7bf2a9472f29b43c53fdf50ad349584677fe Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 21 Dec 2021 10:04:21 +0100 +Subject: [PATCH 107/108] virnettlscontext: Don't pass static key length to + gnutls_dh_params_generate2() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As encryption norms get more strict it's easy to fall on the +insecure side. For instance, so far we are generating 2048 bits +long prime for Diffie-Hellman keys. Some systems consider this +not long enough. While we may just keep increasing the value +passed to the corresponding gnutls_* function, that is not well +maintainable. Instead, we may do what's recommended in the +gnutls_* manpage. From gnutls_dh_params_generate2(3): + + It is recommended not to set the number of bits directly, but + use gnutls_sec_param_to_pk_bits() instead. + +Looking into the gnutls_sec_param_to_pk_bits() then [1], 2048 +bits corresponds to parameter MEDIUM. + +1: https://www.gnutls.org/manual/gnutls.html#tab_003akey_002dsizes + +Signed-off-by: Michal Privoznik +Reviewed-by: Ani Sinha +Reviewed-by: Ján Tomko +(cherry picked from commit 4b77b194069f048e6efdaf5d363098ae039dc4f5) +--- + src/rpc/virnettlscontext.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c +index d648a3815c..06365e15fb 100644 +--- a/src/rpc/virnettlscontext.c ++++ b/src/rpc/virnettlscontext.c +@@ -38,8 +38,6 @@ + #include "virthread.h" + #include "configmake.h" + +-#define DH_BITS 2048 +- + #define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" + #define LIBVIRT_CACERT LIBVIRT_PKI_DIR "/CA/cacert.pem" + #define LIBVIRT_CACRL LIBVIRT_PKI_DIR "/CA/cacrl.pem" +@@ -720,6 +718,15 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert, + * security requirements. + */ + if (isServer) { ++ unsigned int bits = 0; ++ ++ bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM); ++ if (bits == 0) { ++ virReportError(VIR_ERR_SYSTEM_ERROR, "%s", ++ _("Unable to get key length for diffie-hellman parameters")); ++ goto error; ++ } ++ + err = gnutls_dh_params_init(&ctxt->dhParams); + if (err < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, +@@ -727,7 +734,7 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert, + gnutls_strerror(err)); + goto error; + } +- err = gnutls_dh_params_generate2(ctxt->dhParams, DH_BITS); ++ err = gnutls_dh_params_generate2(ctxt->dhParams, bits); + if (err < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, + _("Unable to generate diffie-hellman parameters: %s"), +-- +2.33.0 + diff --git a/virnettlscontext-Drop-gnutls_dh_set_prime_bits.patch b/virnettlscontext-Drop-gnutls_dh_set_prime_bits.patch new file mode 100644 index 0000000000000000000000000000000000000000..f0532965772836bcd5b831f1371288e6e7180b58 --- /dev/null +++ b/virnettlscontext-Drop-gnutls_dh_set_prime_bits.patch @@ -0,0 +1,38 @@ +From 249902c244d0ee0659c6f9907b7384d6453ce77c Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 21 Dec 2021 10:05:00 +0100 +Subject: [PATCH 106/108] virnettlscontext: Drop gnutls_dh_set_prime_bits() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to the gnutls_dh_set_prime_bits() manpage: + + The function has no effect in server side. + +Therefore, don't call it when creating server side context. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ani Sinha +Reviewed-by: Ján Tomko +(cherry picked from commit fb474c33ccc2c2726a2d6f9396effed13bfff9e8) +--- + src/rpc/virnettlscontext.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c +index 02c17124a1..d648a3815c 100644 +--- a/src/rpc/virnettlscontext.c ++++ b/src/rpc/virnettlscontext.c +@@ -1235,8 +1235,6 @@ virNetTLSSessionPtr virNetTLSSessionNew(virNetTLSContextPtr ctxt, + */ + if (ctxt->isServer) { + gnutls_certificate_server_set_request(sess->session, GNUTLS_CERT_REQUEST); +- +- gnutls_dh_set_prime_bits(sess->session, DH_BITS); + } + + gnutls_transport_set_ptr(sess->session, sess); +-- +2.33.0 + diff --git a/virnuma-Don-t-work-around-numa_node_to_cpus-for-non-.patch b/virnuma-Don-t-work-around-numa_node_to_cpus-for-non-.patch new file mode 100644 index 0000000000000000000000000000000000000000..04fd4f319b03fed7cab47c87d7cfebcda5930914 --- /dev/null +++ b/virnuma-Don-t-work-around-numa_node_to_cpus-for-non-.patch @@ -0,0 +1,74 @@ +From 3e40b796a66a73fd2efd3a520f1f11a8a77fcea5 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 21 Aug 2020 14:43:21 +0200 +Subject: [PATCH 047/108] virnuma: Don't work around numa_node_to_cpus() for + non-existent nodes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In a very distant past, we came around machines that has not +continuous node IDs. This made us error out when constructing +capabilities XML. We resolved it by utilizing strange behaviour +of numa_node_to_cpus() in which it returned a mask with all bits +set for a non-existent node. However, this is not the only case +when it returns all ones mask - if the node exists and has enough +CPUs to fill the mask up (e.g. 128 CPUs). + +The fix consists of using nodemask_isset(&numa_all_nodes, ..) +prior to calling numa_node_to_cpus() to determine if the node +exists. + +Fixes: 628c93574758abb59e71160042524d321a33543f +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1860231 +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 24d7d85208f812a45686b32a0561cc9c5c9a49c9) +--- + src/util/virnuma.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index eeca438f25..75d5628cff 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -256,31 +256,23 @@ virNumaGetNodeCPUs(int node, + int mask_n_bytes = max_n_cpus / 8; + size_t i; + g_autofree unsigned long *mask = NULL; +- g_autofree unsigned long *allonesmask = NULL; + g_autoptr(virBitmap) cpumap = NULL; + + *cpus = NULL; + +- if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof(*mask)) < 0) +- return -1; ++ if (!nodemask_isset(&numa_all_nodes, node)) { ++ VIR_DEBUG("NUMA topology for cell %d is not available, ignoring", node); ++ return -2; ++ } + +- if (VIR_ALLOC_N(allonesmask, mask_n_bytes / sizeof(*mask)) < 0) ++ if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof(*mask)) < 0) + return -1; + +- memset(allonesmask, 0xff, mask_n_bytes); +- +- /* The first time this returns -1, ENOENT if node doesn't exist... */ + if (numa_node_to_cpus(node, mask, mask_n_bytes) < 0) { + VIR_WARN("NUMA topology for cell %d is not available, ignoring", node); + return -2; + } + +- /* second, third... times it returns an all-1's mask */ +- if (memcmp(mask, allonesmask, mask_n_bytes) == 0) { +- VIR_DEBUG("NUMA topology for cell %d is invalid, ignoring", node); +- return -2; +- } +- + if (!(cpumap = virBitmapNew(max_n_cpus))) + return -1; + +-- +2.33.0 + diff --git a/virnuma-Use-numa_nodes_ptr-when-checking-available-N.patch b/virnuma-Use-numa_nodes_ptr-when-checking-available-N.patch new file mode 100644 index 0000000000000000000000000000000000000000..fb13ec336462248cc9007a5174b8a00ecc38dbfe --- /dev/null +++ b/virnuma-Use-numa_nodes_ptr-when-checking-available-N.patch @@ -0,0 +1,53 @@ +From 2481f6302d65f98d143aca9933a0fd17b492069a Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 11 Sep 2020 11:50:33 +0200 +Subject: [PATCH 096/108] virnuma: Use numa_nodes_ptr when checking available + NUMA nodes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In v6.7.0-rc1~86 I've tried to fix a problem where we were not +detecting NUMA nodes properly because we misused behaviour of a +libnuma API and as it turned out the behaviour was correct for +hosts with 64 CPUs in one NUMA node. So I changed the code to use +nodemask_isset(&numa_all_nodes, ..) instead and it fixed the +problem on such hosts. However, what I did not realize is that +numa_all_nodes does not reflect all NUMA nodes visible to +userspace, it contains only those nodes that the process +(libvirtd) an allocate memory from, which can be only a subset of +all NUMA nodes. The bitmask that contains all NUMA nodes visible +to userspace and which one I should have used is: numa_nodes_ptr. +For curious ones: + +https://github.com/numactl/numactl/commit/4a22f2238234155e11e3e2717c011864722b767b + +And as I was fixing virNumaGetNodeCPUs() I came to realize that +we already have a function that wraps the correct bitmask: +virNumaNodeIsAvailable(). + +Fixes: 24d7d85208f812a45686b32a0561cc9c5c9a49c9 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1876956 +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 551fb778f5451d40211867365b5eb9b8384b4e3b) +--- + src/util/virnuma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index 75d5628cff..b7e6473e77 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -260,7 +260,7 @@ virNumaGetNodeCPUs(int node, + + *cpus = NULL; + +- if (!nodemask_isset(&numa_all_nodes, node)) { ++ if (!virNumaNodeIsAvailable(node)) { + VIR_DEBUG("NUMA topology for cell %d is not available, ignoring", node); + return -2; + } +-- +2.33.0 + diff --git a/virsh-Fix-XPATH-in-virshDomainDeviceAliasCompleter.patch b/virsh-Fix-XPATH-in-virshDomainDeviceAliasCompleter.patch new file mode 100644 index 0000000000000000000000000000000000000000..00c6d6471360b5993e304de587f2fdeb2cf66303 --- /dev/null +++ b/virsh-Fix-XPATH-in-virshDomainDeviceAliasCompleter.patch @@ -0,0 +1,42 @@ +From 97672f8da837bbe9e1a57714db3b2ce5f299b8d3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 22 Jan 2021 09:29:54 +0100 +Subject: [PATCH 085/108] virsh: Fix XPATH in virshDomainDeviceAliasCompleter() + +The way this completer works is that it dumps XML of specified +domain and then tries to look for @name attribute of +element. However, the XPATH it uses is not correct which results +in no aliases returned by the completer. + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +(cherry picked from commit f023a8acd9c08ea3bc72bf8f968ad63426b033bd) +--- + tools/virsh-completer-domain.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c +index 4472ee08f2..7e155d9ee2 100644 +--- a/tools/virsh-completer-domain.c ++++ b/tools/virsh-completer-domain.c +@@ -266,7 +266,7 @@ virshDomainDeviceAliasCompleter(vshControl *ctl, + if (virshDomainGetXML(ctl, cmd, domainXMLFlags, &xmldoc, &ctxt) < 0) + return NULL; + +- naliases = virXPathNodeSet("./devices//alias/@name", ctxt, &aliases); ++ naliases = virXPathNodeSet("/domain/devices//alias[@name]", ctxt, &aliases); + if (naliases < 0) + return NULL; + +@@ -274,7 +274,7 @@ virshDomainDeviceAliasCompleter(vshControl *ctl, + return NULL; + + for (i = 0; i < naliases; i++) { +- if (!(tmp[i] = virXMLNodeContentString(aliases[i]))) ++ if (!(tmp[i] = virXMLPropString(aliases[i], "name"))) + return NULL; + } + +-- +2.33.0 + diff --git a/virsh-completer-use-signed-variable-for-XPathNodeSet.patch b/virsh-completer-use-signed-variable-for-XPathNodeSet.patch new file mode 100644 index 0000000000000000000000000000000000000000..359794de06dbfda5491ec4ff39b380fdb433f9b7 --- /dev/null +++ b/virsh-completer-use-signed-variable-for-XPathNodeSet.patch @@ -0,0 +1,44 @@ +From d9012d5897fc600853526079fe01fa477acd4eb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Sun, 2 Aug 2020 23:30:17 +0200 +Subject: [PATCH 042/108] virsh: completer: use signed variable for + XPathNodeSet errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although virXPathNodeSet is unlikely to return -1, we should +check for it properly or not at all. + +Signed-off-by: Ján Tomko +Reviewed-by: Martin Kletzander +(cherry picked from commit ce2483f6199a2d623f142a992a6afe41015d9ad8) +--- + tools/virsh-completer-host.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/virsh-completer-host.c b/tools/virsh-completer-host.c +index 35e6bba661..8893888ec2 100644 +--- a/tools/virsh-completer-host.c ++++ b/tools/virsh-completer-host.c +@@ -55,7 +55,7 @@ virshAllocpagesPagesizeCompleter(vshControl *ctl, + { + g_autoptr(xmlXPathContext) ctxt = NULL; + virshControlPtr priv = ctl->privData; +- unsigned int npages = 0; ++ int npages = 0; + g_autofree xmlNodePtr *pages = NULL; + g_autoptr(xmlDoc) doc = NULL; + size_t i = 0; +@@ -106,7 +106,7 @@ virshCellnoCompleter(vshControl *ctl, + { + g_autoptr(xmlXPathContext) ctxt = NULL; + virshControlPtr priv = ctl->privData; +- unsigned int ncells = 0; ++ int ncells = 0; + g_autofree xmlNodePtr *cells = NULL; + g_autoptr(xmlDoc) doc = NULL; + size_t i = 0; +-- +2.33.0 + diff --git a/virsh-do-not-return-bool-in-virshNetworkPortUUIDComp.patch b/virsh-do-not-return-bool-in-virshNetworkPortUUIDComp.patch new file mode 100644 index 0000000000000000000000000000000000000000..09a2a7ce264713ae9e0485b5e1fb50de30c9d2be --- /dev/null +++ b/virsh-do-not-return-bool-in-virshNetworkPortUUIDComp.patch @@ -0,0 +1,35 @@ +From 5e44cc4ad52cb0acb43367ddccdc034f3a967594 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 22 Sep 2020 22:19:26 +0200 +Subject: [PATCH 032/108] virsh: do not return bool in + virshNetworkPortUUIDCompleter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +portability: Returning an integer in a function with pointer +return type is not portable. [CastIntegerToAddressAtReturn] + +Signed-off-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit dbe3cf6c64a38c571062557770d64fed837f9c3d) +--- + tools/virsh-completer-network.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-completer-network.c b/tools/virsh-completer-network.c +index 8f0048ed6f..7be36d7ad8 100644 +--- a/tools/virsh-completer-network.c ++++ b/tools/virsh-completer-network.c +@@ -106,7 +106,7 @@ virshNetworkPortUUIDCompleter(vshControl *ctl, + return NULL; + + if (!(net = virshCommandOptNetwork(ctl, cmd, NULL))) +- return false; ++ return NULL; + + if ((nports = virNetworkListAllPorts(net, &ports, flags)) < 0) + return NULL; +-- +2.33.0 + diff --git a/virsh-domain-Fix-error-handling-of-pthread_sigmask.patch b/virsh-domain-Fix-error-handling-of-pthread_sigmask.patch new file mode 100644 index 0000000000000000000000000000000000000000..97c1f4acc4551fe04217a68e4debf621323b1546 --- /dev/null +++ b/virsh-domain-Fix-error-handling-of-pthread_sigmask.patch @@ -0,0 +1,60 @@ +From 4e69b1be71fd431614aaf6d69208dabc4d7bf053 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 1 Feb 2021 13:42:01 +0100 +Subject: [PATCH 086/108] virsh-domain: Fix error handling of pthread_sigmask + +pthread_sigmask() returns 0 on success and "a non-zero value +on failure", but not neccessarily a negative one. + +Found by clang-tidy's "bugprone-posix-return" check. + +Signed-off-by: Tim Wiederhake +Reviewed-by: Peter Krempa +(cherry picked from commit 4f5c22b27c7580a93d45e7475580b4dd55fd0da5) +--- + tools/virsh-domain.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index 622972bdd4..49b2ed3a3f 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -4238,7 +4238,7 @@ doSave(void *opaque) + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGINT); +- if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0) ++ if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) != 0) + goto out_sig; + #endif /* !WIN32 */ + +@@ -4768,7 +4768,7 @@ doManagedsave(void *opaque) + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGINT); +- if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0) ++ if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) != 0) + goto out_sig; + #endif /* !WIN32 */ + +@@ -5450,7 +5450,7 @@ doDump(void *opaque) + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGINT); +- if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0) ++ if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) != 0) + goto out_sig; + #endif /* !WIN32 */ + +@@ -10740,7 +10740,7 @@ doMigrate(void *opaque) + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGINT); +- if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) < 0) ++ if (pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask) != 0) + goto out_sig; + #endif /* !WIN32 */ + +-- +2.33.0 + diff --git a/virsh-guest-agent-timeout-set-default-value-for-opti.patch b/virsh-guest-agent-timeout-set-default-value-for-opti.patch new file mode 100644 index 0000000000000000000000000000000000000000..d30db7cdd566c58f3cd2e83c916d05fd59f077b7 --- /dev/null +++ b/virsh-guest-agent-timeout-set-default-value-for-opti.patch @@ -0,0 +1,61 @@ +From 6545b7b8501bdbdf12cbaf2098ef4617764de591 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= +Date: Fri, 21 Aug 2020 14:34:51 +0200 +Subject: [PATCH 048/108] virsh: guest-agent-timeout: set default value for + optional argument +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The timeout argument for guest-agent-timeout is optional but it did not +have proper default value specified. Also update the virsh man page +accordingly. + +Signed-off-by: Tomáš Golembiovský +Reviewed-by: Michal Privoznik +(cherry picked from commit c7547a16f8a30cf573a7d11d9497fca2f28d9bf3) +--- + docs/manpages/virsh.rst | 7 ++++--- + tools/virsh-domain.c | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index dc404ddfe8..db15cc6507 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -2622,15 +2622,16 @@ guest + + .. code-block:: + +- guest-agent-timeout domain --timeout value ++ guest-agent-timeout domain [--timeout value] + + Set how long to wait for a response from guest agent commands. By default, + agent commands block forever waiting for a response. ``value`` must be a + positive value (wait for given amount of seconds) or one of the following + values: + +-* -2 - block forever waiting for a result, +-* -1 - reset timeout to the default value, ++* -2 - block forever waiting for a result (used when --timeout is omitted), ++* -1 - reset timeout to the default value (currently defined as 5 seconds in ++ libvirt daemon), + * 0 - do not wait at all, + + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index b5375ebd3e..622972bdd4 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -14227,7 +14227,7 @@ static bool + cmdGuestAgentTimeout(vshControl *ctl, const vshCmd *cmd) + { + virDomainPtr dom = NULL; +- int timeout; ++ int timeout = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK; + const unsigned int flags = 0; + bool ret = false; + +-- +2.33.0 + diff --git a/virsh-snapshot-Don-t-leak-then-in-cmdSnapshotList.patch b/virsh-snapshot-Don-t-leak-then-in-cmdSnapshotList.patch new file mode 100644 index 0000000000000000000000000000000000000000..59a4222041530707ef35dd4e17214b13b010c3fb --- /dev/null +++ b/virsh-snapshot-Don-t-leak-then-in-cmdSnapshotList.patch @@ -0,0 +1,43 @@ +From 66b196dfcfe3cc6281cfeb31c07465074d7a4b2d Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 23 Aug 2021 14:08:10 +0200 +Subject: [PATCH 099/108] virsh-snapshot: Don't leak @then in cmdSnapshotList() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The variable is used inside a loop in which it's allocated in +each iteration. Bring it inside the loop so that g_autoptr() +kicks in each iteration. + +Fixes: 3caa28dc50df7ec215713075d669b20bef6473a2 +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 6d7a16361b54d1ea8cb0ae15a4d4d90a6f282ce0) +--- + tools/virsh-snapshot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c +index 376290d468..c7d3e01fa8 100644 +--- a/tools/virsh-snapshot.c ++++ b/tools/virsh-snapshot.c +@@ -1492,7 +1492,6 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + virDomainSnapshotPtr snapshot = NULL; + char *state = NULL; + long long creation_longlong; +- g_autoptr(GDateTime) then = NULL; + bool tree = vshCommandOptBool(cmd, "tree"); + bool name = vshCommandOptBool(cmd, "name"); + bool from = vshCommandOptBool(cmd, "from"); +@@ -1587,6 +1586,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + } + + for (i = 0; i < snaplist->nsnaps; i++) { ++ g_autoptr(GDateTime) then = NULL; + g_autofree gchar *thenstr = NULL; + const char *snap_name; + +-- +2.33.0 + diff --git a/virshCheckpointListCollect-Do-not-pass-NULL-to-qsort.patch b/virshCheckpointListCollect-Do-not-pass-NULL-to-qsort.patch new file mode 100644 index 0000000000000000000000000000000000000000..57486961fdf21953560c5266948034e01bcdd63e --- /dev/null +++ b/virshCheckpointListCollect-Do-not-pass-NULL-to-qsort.patch @@ -0,0 +1,29 @@ +From f64a491232e5aeca4d0d86523564bdea9913bb73 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 19 Apr 2021 13:54:15 +0200 +Subject: [PATCH 063/108] virshCheckpointListCollect: Do not pass NULL to qsort + +Signed-off-by: Tim Wiederhake +Reviewed-by: Laine Stump +(cherry picked from commit 1c34211c22de28127a509edbf2cf2f44cb0d891e) +--- + tools/virsh-checkpoint.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/virsh-checkpoint.c b/tools/virsh-checkpoint.c +index 1a3a74b2d5..6effbdc26c 100644 +--- a/tools/virsh-checkpoint.c ++++ b/tools/virsh-checkpoint.c +@@ -622,7 +622,8 @@ virshCheckpointListCollect(vshControl *ctl, + } + } + +- if (!(orig_flags & VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL)) ++ if (!(orig_flags & VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL) && ++ checkpointlist->chks) + qsort(checkpointlist->chks, checkpointlist->nchks, + sizeof(*checkpointlist->chks), virshChkSorter); + +-- +2.33.0 + diff --git a/virsocketaddr-Zero-netmask-in-virSocketAddrPrefixToN.patch b/virsocketaddr-Zero-netmask-in-virSocketAddrPrefixToN.patch new file mode 100644 index 0000000000000000000000000000000000000000..bfb38112ecac7759d4d93a90a239d6203f71b435 --- /dev/null +++ b/virsocketaddr-Zero-netmask-in-virSocketAddrPrefixToN.patch @@ -0,0 +1,62 @@ +From 7abf979f6a787890f20407848a8595e3a6c8aee5 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 9 Oct 2020 16:16:58 +0200 +Subject: [PATCH 035/108] virsocketaddr: Zero @netmask in + virSocketAddrPrefixToNetmask() + +The aim of virSocketAddrPrefixToNetmask() is to initialize passed +virSocketAddr structure based on prefix length and family. +However, it doesn't set all members in the struct which may lead +to reads of uninitialized values: + +==15421== Use of uninitialised value of size 8 +==15421== at 0x50F297A: _itoa_word (in /lib64/libc-2.31.so) +==15421== by 0x510C8FE: __vfprintf_internal (in /lib64/libc-2.31.so) +==15421== by 0x5120295: __vsnprintf_internal (in /lib64/libc-2.31.so) +==15421== by 0x50F8969: snprintf (in /lib64/libc-2.31.so) +==15421== by 0x51BB602: getnameinfo (in /lib64/libc-2.31.so) +==15421== by 0x496DEE0: virSocketAddrFormatFull (virsocketaddr.c:486) +==15421== by 0x496DD9F: virSocketAddrFormat (virsocketaddr.c:444) +==15421== by 0x11871F: networkDnsmasqConfContents (bridge_driver.c:1404) +==15421== by 0x1118F5: testCompareXMLToConfFiles (networkxml2conftest.c:48) +==15421== by 0x111BAF: testCompareXMLToConfHelper (networkxml2conftest.c:112) +==15421== by 0x112679: virTestRun (testutils.c:142) +==15421== by 0x111D09: mymain (networkxml2conftest.c:144) +==15421== Uninitialised value was created by a stack allocation +==15421== at 0x1175D2: networkDnsmasqConfContents (bridge_driver.c:1056) + +All callers expect the function to initialize the structure +fully. + +Signed-off-by: Michal Privoznik +Reviewed-by: Laine Stump +(cherry picked from commit 14506720717f2a86ab64ae3d5cdef3a4b2641b11) +--- + src/util/virsocketaddr.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c +index 4c9f124e88..9183687e18 100644 +--- a/src/util/virsocketaddr.c ++++ b/src/util/virsocketaddr.c +@@ -1100,6 +1100,8 @@ virSocketAddrPrefixToNetmask(unsigned int prefix, + virSocketAddrPtr netmask, + int family) + { ++ memset(netmask, 0, sizeof(*netmask)); ++ + netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */ + + if (family == AF_INET) { +@@ -1138,7 +1140,7 @@ virSocketAddrPrefixToNetmask(unsigned int prefix, + } + + return 0; +- } ++} + + /** + * virSocketAddrGetIPPrefix: +-- +2.33.0 + diff --git a/virt-login-shell-correctly-calculate-string-length.patch b/virt-login-shell-correctly-calculate-string-length.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7708fe522b9f3e26d479c85dd76005bb653f571 --- /dev/null +++ b/virt-login-shell-correctly-calculate-string-length.patch @@ -0,0 +1,36 @@ +From c28905b5363ded3347a1bf8846c57f0122c6cbfe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Sun, 2 Aug 2020 14:58:38 +0200 +Subject: [PATCH 043/108] virt-login-shell: correctly calculate string length +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +virLoginShellGetShellArgv was not dereferencing the pointer +to the string list containing the shell parameters from the +config file, thus setting some random number as shargvlen. + +Signed-off-by: Ján Tomko +Fixes: 740e4d705284ba0598258291c2656f50075486f0 +Reviewed-by: Martin Kletzander +(cherry picked from commit d339113ab050107fcc4e2a3e9ab939cd92352efe) +--- + tools/virt-login-shell-helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virt-login-shell-helper.c b/tools/virt-login-shell-helper.c +index d9db883ee6..2db349754e 100644 +--- a/tools/virt-login-shell-helper.c ++++ b/tools/virt-login-shell-helper.c +@@ -104,7 +104,7 @@ static int virLoginShellGetShellArgv(virConfPtr conf, + (*shargv)[0] = g_strdup("/bin/sh"); + *shargvlen = 1; + } else { +- *shargvlen = virStringListLength((const char *const *)shargv); ++ *shargvlen = virStringListLength((const char *const *)*shargv); + } + return 0; + } +-- +2.33.0 + diff --git a/vsh-fix-memory-leak-in-vshCommandParse.patch b/vsh-fix-memory-leak-in-vshCommandParse.patch new file mode 100644 index 0000000000000000000000000000000000000000..8417f4a1a08b5453c23d747512fbb90b84f4d49c --- /dev/null +++ b/vsh-fix-memory-leak-in-vshCommandParse.patch @@ -0,0 +1,36 @@ +From 4f1111061f293b26850958feb80f56f75f6cf9ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 6 Apr 2021 14:23:31 +0200 +Subject: [PATCH 055/108] vsh: fix memory leak in vshCommandParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +One of the error branches used a plain free where vshCommandFree +was required. + +https://bugzilla.redhat.com/show_bug.cgi?id=1943415 + +Signed-off-by: Ján Tomko +Reviewed-by: Erik Skultety +(cherry picked from commit a131b8b517a88685ddb5f1b17c4d1a16b9a97b61) +--- + tools/vsh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/vsh.c b/tools/vsh.c +index 65f4a48d62..9bb4ff043a 100644 +--- a/tools/vsh.c ++++ b/tools/vsh.c +@@ -1555,7 +1555,7 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser, vshCmd **partial) + + if (!partial && + vshCommandCheckOpts(ctl, c, opts_required, opts_seen) < 0) { +- VIR_FREE(c); ++ vshCommandFree(c); + goto syntaxError; + } + +-- +2.33.0 +