* Mon Sep 23 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 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)
This commit is contained in:
Danilo C. L. de Paula 2019-09-23 21:47:12 +01:00
parent a05903a904
commit 58b71dc108
5 changed files with 477 additions and 1 deletions

View File

@ -0,0 +1,72 @@
From 49dd008d58d7527a98981d96106949b2913fb4d9 Mon Sep 17 00:00:00 2001
From: Sergio Lopez Pascual <slp@redhat.com>
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 <slp@redhat.com>
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 <sgarzare@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
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 <slp@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190911100316.32282-1-mreitz@redhat.com
Reviewed-by: Sergio Lopez <slp@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f)
Signed-off-by: Sergio Lopez <slp@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
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

View File

@ -0,0 +1,70 @@
From c7c95a2f14d94eb8213ce7cab03acdef40fed093 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
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 <stefanha@redhat.com>
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 <pbonzini@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
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 <stefanha@redhat.com>
Message-Id: <20190823135632.25010-1-stefanha@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(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 <stefanha@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
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

View File

@ -0,0 +1,254 @@
From 9d6d365abaea5e068f060b8a70d5b8fab43a9f7f Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
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 <stefanha@redhat.com>
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 <pbonzini@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
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 <stefanha@redhat.com>
Message-Id: <20190830093056.12572-1-stefanha@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 72d41eb4b8f923de91e8f06dc20aa86b0a9155fb)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
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

View File

@ -0,0 +1,56 @@
From 84728251439a3b73a57a8d72cc4d39307207cc01 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
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 <pbonzini@redhat.com>
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é <philmd@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
From: Markus Armbruster <armbru@redhat.com>
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 <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
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

View File

@ -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 <ddepaula@redhat.com> - 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 <ddepaula@redhat.com> - 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]