diff --git a/kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch b/kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch new file mode 100644 index 0000000..5e0a568 --- /dev/null +++ b/kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch @@ -0,0 +1,72 @@ +From 49dd008d58d7527a98981d96106949b2913fb4d9 Mon Sep 17 00:00:00 2001 +From: Sergio Lopez Pascual +Date: Wed, 18 Sep 2019 11:34:14 +0100 +Subject: [PATCH 1/4] blockjob: update nodes head while removing all bdrv + +RH-Author: Sergio Lopez Pascual +Message-id: <20190918113414.24522-2-slp@redhat.com> +Patchwork-id: 90748 +O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH 1/1] blockjob: update nodes head while removing all bdrv +Bugzilla: 1746631 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Max Reitz +RH-Acked-by: Kevin Wolf + +block_job_remove_all_bdrv() iterates through job->nodes, calling +bdrv_root_unref_child() for each entry. The call to the latter may +reach child_job_[can_]set_aio_ctx(), which will also attempt to +traverse job->nodes, potentially finding entries that where freed +on previous iterations. + +To avoid this situation, update job->nodes head on each iteration to +ensure that already freed entries are no longer linked to the list. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631 +Signed-off-by: Sergio Lopez +Cc: qemu-stable@nongnu.org +Signed-off-by: Max Reitz +Message-id: 20190911100316.32282-1-mreitz@redhat.com +Reviewed-by: Sergio Lopez +Signed-off-by: Max Reitz +(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f) +Signed-off-by: Sergio Lopez +Signed-off-by: Danilo C. L. de Paula +--- + blockjob.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/blockjob.c b/blockjob.c +index 20b7f55..74abb97 100644 +--- a/blockjob.c ++++ b/blockjob.c +@@ -186,14 +186,23 @@ static const BdrvChildRole child_job = { + + void block_job_remove_all_bdrv(BlockJob *job) + { +- GSList *l; +- for (l = job->nodes; l; l = l->next) { ++ /* ++ * bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(), ++ * which will also traverse job->nodes, so consume the list one by ++ * one to make sure that such a concurrent access does not attempt ++ * to process an already freed BdrvChild. ++ */ ++ while (job->nodes) { ++ GSList *l = job->nodes; + BdrvChild *c = l->data; ++ ++ job->nodes = l->next; ++ + bdrv_op_unblock_all(c->bs, job->blocker); + bdrv_root_unref_child(c); ++ ++ g_slist_free_1(l); + } +- g_slist_free(job->nodes); +- job->nodes = NULL; + } + + bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs) +-- +1.8.3.1 + diff --git a/kvm-hostmem-file-fix-pmem-file-size-check.patch b/kvm-hostmem-file-fix-pmem-file-size-check.patch new file mode 100644 index 0000000..2fc5e43 --- /dev/null +++ b/kvm-hostmem-file-fix-pmem-file-size-check.patch @@ -0,0 +1,70 @@ +From c7c95a2f14d94eb8213ce7cab03acdef40fed093 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 18 Sep 2019 15:10:06 +0100 +Subject: [PATCH 2/4] hostmem-file: fix pmem file size check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +Message-id: <20190918151007.27973-2-stefanha@redhat.com> +Patchwork-id: 90763 +O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH 1/2] hostmem-file: fix pmem file size check +Bugzilla: 1724008 1736788 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Igor Mammedov +RH-Acked-by: Eduardo Habkost + +Commit 314aec4a6e06844937f1677f6cba21981005f389 ("hostmem-file: reject +invalid pmem file sizes") added a file size check that verifies the +hostmem object's size parameter against the actual devdax pmem file. +This is useful because getting the size wrong results in confusing +errors inside the guest. + +However, the code doesn't work properly for files where struct +stat::st_size is zero. Hostmem-file's ->alloc() function returns early +without setting an Error, causing the following assertion failure: + + qemu/memory.c:2215: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed. + +This patch handles the case where qemu_get_pmem_size() returns 0 but +there is no error. + +Fixes: 314aec4a6e06844937f1677f6cba21981005f389 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20190823135632.25010-1-stefanha@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 7faae95ebc966c2981b78cf7c25009dfa32d4b72) + +Note that this commit will be effectively reverted by the next one but I +backported it to avoid conflicts. + +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Danilo C. L. de Paula +--- + backends/hostmem-file.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c +index 29e55c9..ecc15e3 100644 +--- a/backends/hostmem-file.c ++++ b/backends/hostmem-file.c +@@ -67,12 +67,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) + uint64_t size; + + size = qemu_get_pmem_size(fb->mem_path, &local_err); +- if (!size) { ++ if (local_err) { + error_propagate(errp, local_err); + return; + } + +- if (backend->size > size) { ++ if (size && backend->size > size) { + error_setg(errp, "size property %" PRIu64 " is larger than " + "pmem file \"%s\" size %" PRIu64, backend->size, + fb->mem_path, size); +-- +1.8.3.1 + diff --git a/kvm-memory-fetch-pmem-size-in-get_file_size.patch b/kvm-memory-fetch-pmem-size-in-get_file_size.patch new file mode 100644 index 0000000..80a2e15 --- /dev/null +++ b/kvm-memory-fetch-pmem-size-in-get_file_size.patch @@ -0,0 +1,254 @@ +From 9d6d365abaea5e068f060b8a70d5b8fab43a9f7f Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 18 Sep 2019 15:10:07 +0100 +Subject: [PATCH 3/4] memory: fetch pmem size in get_file_size() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +Message-id: <20190918151007.27973-3-stefanha@redhat.com> +Patchwork-id: 90762 +O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH 2/2] memory: fetch pmem size in get_file_size() +Bugzilla: 1724008 1736788 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Igor Mammedov +RH-Acked-by: Eduardo Habkost + +Neither stat(2) nor lseek(2) report the size of Linux devdax pmem +character device nodes. Commit 314aec4a6e06844937f1677f6cba21981005f389 +("hostmem-file: reject invalid pmem file sizes") added code to +hostmem-file.c to fetch the size from sysfs and compare against the +user-provided size=NUM parameter: + + if (backend->size > size) { + error_setg(errp, "size property %" PRIu64 " is larger than " + "pmem file \"%s\" size %" PRIu64, backend->size, + fb->mem_path, size); + return; + } + +It turns out that exec.c:qemu_ram_alloc_from_fd() already has an +equivalent size check but it skips devdax pmem character devices because +lseek(2) returns 0: + + if (file_size > 0 && file_size < size) { + error_setg(errp, "backing store %s size 0x%" PRIx64 + " does not match 'size' option 0x" RAM_ADDR_FMT, + mem_path, file_size, size); + return NULL; + } + +This patch moves the devdax pmem file size code into get_file_size() so +that we check the memory size in a single place: +qemu_ram_alloc_from_fd(). This simplifies the code and makes it more +general. + +This also fixes the problem that hostmem-file only checks the devdax +pmem file size when the pmem=on parameter is given. An unchecked +size=NUM parameter can lead to SIGBUS in QEMU so we must always fetch +the file size for Linux devdax pmem character device nodes. + +Signed-off-by: Stefan Hajnoczi +Message-Id: <20190830093056.12572-1-stefanha@redhat.com> +Reviewed-by: Eduardo Habkost +Signed-off-by: Paolo Bonzini +(cherry picked from commit 72d41eb4b8f923de91e8f06dc20aa86b0a9155fb) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Danilo C. L. de Paula +--- + backends/hostmem-file.c | 22 -------------------- + exec.c | 34 ++++++++++++++++++++++++++++++- + include/qemu/osdep.h | 13 ------------ + util/oslib-posix.c | 54 ------------------------------------------------- + util/oslib-win32.c | 6 ------ + 5 files changed, 33 insertions(+), 96 deletions(-) + +diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c +index ecc15e3..be64020 100644 +--- a/backends/hostmem-file.c ++++ b/backends/hostmem-file.c +@@ -58,28 +58,6 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) + return; + } + +- /* +- * Verify pmem file size since starting a guest with an incorrect size +- * leads to confusing failures inside the guest. +- */ +- if (fb->is_pmem) { +- Error *local_err = NULL; +- uint64_t size; +- +- size = qemu_get_pmem_size(fb->mem_path, &local_err); +- if (local_err) { +- error_propagate(errp, local_err); +- return; +- } +- +- if (size && backend->size > size) { +- error_setg(errp, "size property %" PRIu64 " is larger than " +- "pmem file \"%s\" size %" PRIu64, backend->size, +- fb->mem_path, size); +- return; +- } +- } +- + backend->force_prealloc = mem_prealloc; + name = host_memory_backend_get_name(backend); + memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), +diff --git a/exec.c b/exec.c +index 3e78de3..3c03edf 100644 +--- a/exec.c ++++ b/exec.c +@@ -1813,7 +1813,39 @@ long qemu_maxrampagesize(void) + #ifdef CONFIG_POSIX + static int64_t get_file_size(int fd) + { +- int64_t size = lseek(fd, 0, SEEK_END); ++ int64_t size; ++#if defined(__linux__) ++ struct stat st; ++ ++ if (fstat(fd, &st) < 0) { ++ return -errno; ++ } ++ ++ /* Special handling for devdax character devices */ ++ if (S_ISCHR(st.st_mode)) { ++ g_autofree char *subsystem_path = NULL; ++ g_autofree char *subsystem = NULL; ++ ++ subsystem_path = g_strdup_printf("/sys/dev/char/%d:%d/subsystem", ++ major(st.st_rdev), minor(st.st_rdev)); ++ subsystem = g_file_read_link(subsystem_path, NULL); ++ ++ if (subsystem && g_str_has_suffix(subsystem, "/dax")) { ++ g_autofree char *size_path = NULL; ++ g_autofree char *size_str = NULL; ++ ++ size_path = g_strdup_printf("/sys/dev/char/%d:%d/size", ++ major(st.st_rdev), minor(st.st_rdev)); ++ ++ if (g_file_get_contents(size_path, &size_str, NULL, NULL)) { ++ return g_ascii_strtoll(size_str, NULL, 0); ++ } ++ } ++ } ++#endif /* defined(__linux__) */ ++ ++ /* st.st_size may be zero for special files yet lseek(2) works */ ++ size = lseek(fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } +diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h +index af2b91f..c7d242f 100644 +--- a/include/qemu/osdep.h ++++ b/include/qemu/osdep.h +@@ -571,19 +571,6 @@ void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus, + Error **errp); + + /** +- * qemu_get_pmem_size: +- * @filename: path to a pmem file +- * @errp: pointer to a NULL-initialized error object +- * +- * Determine the size of a persistent memory file. Besides supporting files on +- * DAX file systems, this function also supports Linux devdax character +- * devices. +- * +- * Returns: the size or 0 on failure +- */ +-uint64_t qemu_get_pmem_size(const char *filename, Error **errp); +- +-/** + * qemu_get_pid_name: + * @pid: pid of a process + * +diff --git a/util/oslib-posix.c b/util/oslib-posix.c +index fe0309c..d772da8 100644 +--- a/util/oslib-posix.c ++++ b/util/oslib-posix.c +@@ -513,60 +513,6 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, + } + } + +-uint64_t qemu_get_pmem_size(const char *filename, Error **errp) +-{ +- struct stat st; +- +- if (stat(filename, &st) < 0) { +- error_setg(errp, "unable to stat pmem file \"%s\"", filename); +- return 0; +- } +- +-#if defined(__linux__) +- /* Special handling for devdax character devices */ +- if (S_ISCHR(st.st_mode)) { +- char *subsystem_path = NULL; +- char *subsystem = NULL; +- char *size_path = NULL; +- char *size_str = NULL; +- uint64_t ret = 0; +- +- subsystem_path = g_strdup_printf("/sys/dev/char/%d:%d/subsystem", +- major(st.st_rdev), minor(st.st_rdev)); +- subsystem = g_file_read_link(subsystem_path, NULL); +- if (!subsystem) { +- error_setg(errp, "unable to read subsystem for pmem file \"%s\"", +- filename); +- goto devdax_err; +- } +- +- if (!g_str_has_suffix(subsystem, "/dax")) { +- error_setg(errp, "pmem file \"%s\" is not a dax device", filename); +- goto devdax_err; +- } +- +- size_path = g_strdup_printf("/sys/dev/char/%d:%d/size", +- major(st.st_rdev), minor(st.st_rdev)); +- if (!g_file_get_contents(size_path, &size_str, NULL, NULL)) { +- error_setg(errp, "unable to read size for pmem file \"%s\"", +- size_path); +- goto devdax_err; +- } +- +- ret = g_ascii_strtoull(size_str, NULL, 0); +- +-devdax_err: +- g_free(size_str); +- g_free(size_path); +- g_free(subsystem); +- g_free(subsystem_path); +- return ret; +- } +-#endif /* defined(__linux__) */ +- +- return st.st_size; +-} +- + char *qemu_get_pid_name(pid_t pid) + { + char *name = NULL; +diff --git a/util/oslib-win32.c b/util/oslib-win32.c +index 9583fb4..c62cd43 100644 +--- a/util/oslib-win32.c ++++ b/util/oslib-win32.c +@@ -562,12 +562,6 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, + } + } + +-uint64_t qemu_get_pmem_size(const char *filename, Error **errp) +-{ +- error_setg(errp, "pmem support not available"); +- return 0; +-} +- + char *qemu_get_pid_name(pid_t pid) + { + /* XXX Implement me */ +-- +1.8.3.1 + diff --git a/kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch b/kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch new file mode 100644 index 0000000..42c4cd9 --- /dev/null +++ b/kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch @@ -0,0 +1,56 @@ +From 84728251439a3b73a57a8d72cc4d39307207cc01 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 20 Sep 2019 16:48:41 +0100 +Subject: [PATCH 4/4] pr-manager: Fix invalid g_free() crash bug +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Paolo Bonzini +Message-id: <20190920164841.10424-1-pbonzini@redhat.com> +Patchwork-id: 90824 +O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH v2] pr-manager: Fix invalid g_free() crash bug +Bugzilla: 1753992 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Kevin Wolf +RH-Acked-by: Markus Armbruster + +From: Markus Armbruster + +BZ: 1753992 +BRANCH: rhel-av-8.1.0/master-4.1.0 +Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23612762 +Upstream: 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3 + +pr_manager_worker() passes its @opaque argument to g_free(). Wrong; +it points to pr_manager_worker()'s automatic @data. Broken when +commit 2f3a7ab39be converted @data from heap- to stack-allocated. Fix +by deleting the g_free(). + +Fixes: 2f3a7ab39bec4ba8022dc4d42ea641165b004e3e +Cc: qemu-stable@nongnu.org +Signed-off-by: Markus Armbruster +Reviewed-by: Philippe Mathieu-Daudé +Acked-by: Paolo Bonzini +Signed-off-by: Kevin Wolf +(cherry picked from commit 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3) +Signed-off-by: Danilo C. L. de Paula +--- + scsi/pr-manager.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c +index ee43663..0c866e8 100644 +--- a/scsi/pr-manager.c ++++ b/scsi/pr-manager.c +@@ -39,7 +39,6 @@ static int pr_manager_worker(void *opaque) + int fd = data->fd; + int r; + +- g_free(data); + trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]); + + /* The reference was taken in pr_manager_execute. */ +-- +1.8.3.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 6afdda6..697bb0c 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -67,7 +67,7 @@ Obsoletes: %1-rhev Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 4.1.0 -Release: 10%{?dist} +Release: 11%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -198,6 +198,16 @@ Patch57: kvm-block-create-Do-not-abort-if-a-block-driver-is-not-a.patch Patch58: kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch # For bz#1749737 - CVE-2019-15890 qemu-kvm: QEMU: Slirp: use-after-free during packet reassembly [rhel-av-8] Patch59: kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch +# For bz#1746631 - Qemu core dump when do block commit under stress +Patch60: kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch +# For bz#1724008 - QEMU core dumped "memory_region_get_ram_ptr: Assertion `mr->ram_block' failed" +# For bz#1736788 - QEMU core dumped if boot guest with nvdimm backed by /dev/dax0.0 and option pmem=off +Patch61: kvm-hostmem-file-fix-pmem-file-size-check.patch +# For bz#1724008 - QEMU core dumped "memory_region_get_ram_ptr: Assertion `mr->ram_block' failed" +# For bz#1736788 - QEMU core dumped if boot guest with nvdimm backed by /dev/dax0.0 and option pmem=off +Patch62: kvm-memory-fetch-pmem-size-in-get_file_size.patch +# For bz#1753992 - core dump when testing persistent reservation in guest +Patch63: kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch BuildRequires: wget BuildRequires: rpm-build @@ -1139,6 +1149,20 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog +* Mon Sep 23 2019 Danilo Cesar Lemes de Paula - 4.1.0-11.el8 +- kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch [bz#1746631] +- kvm-hostmem-file-fix-pmem-file-size-check.patch [bz#1724008 bz#1736788] +- kvm-memory-fetch-pmem-size-in-get_file_size.patch [bz#1724008 bz#1736788] +- kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch [bz#1753992] +- Resolves: bz#1724008 + (QEMU core dumped "memory_region_get_ram_ptr: Assertion `mr->ram_block' failed") +- Resolves: bz#1736788 + (QEMU core dumped if boot guest with nvdimm backed by /dev/dax0.0 and option pmem=off) +- Resolves: bz#1746631 + (Qemu core dump when do block commit under stress) +- Resolves: bz#1753992 + (core dump when testing persistent reservation in guest) + * Mon Sep 16 2019 Danilo Cesar Lemes de Paula - 4.1.0-10.el8 - kvm-spapr-xive-Mask-the-EAS-when-allocating-an-IRQ.patch [bz#1748725] - kvm-block-create-Do-not-abort-if-a-block-driver-is-not-a.patch [bz#1746267]