diff --git a/Fixed-integer-overflow-in-e1000e.patch b/Fixed-integer-overflow-in-e1000e.patch new file mode 100644 index 0000000000000000000000000000000000000000..004390fc5a3d60d2aaf4912d0679c4fa471d28a2 --- /dev/null +++ b/Fixed-integer-overflow-in-e1000e.patch @@ -0,0 +1,40 @@ +From 41077af2c4283c15c0a822017ea51612d15b68f8 Mon Sep 17 00:00:00 2001 +From: Andrew Melnychenko +Date: Wed, 4 Mar 2020 16:20:58 +0200 +Subject: [PATCH 1/5] Fixed integer overflow in e1000e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1737400 +Fixed setting max_queue_num if there are no peers in +NICConf. qemu_new_nic() creates NICState with 1 NetClientState(index +0) without peers, set max_queue_num to 0 - It prevents undefined +behavior and possible crashes, especially during pcie hotplug. + +Fixes: 6f3fbe4ed06 ("net: Introduce e1000e device emulation") +Signed-off-by: Andrew Melnychenko +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Dmitry Fleytman +Signed-off-by: Jason Wang +Signed-off-by: Zhenyu Ye +--- + hw/net/e1000e.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c +index 581f7d03..1e827c4f 100644 +--- a/hw/net/e1000e.c ++++ b/hw/net/e1000e.c +@@ -325,7 +325,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) + s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, + object_get_typename(OBJECT(s)), dev->id, s); + +- s->core.max_queue_num = s->conf.peers.queues - 1; ++ s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; + + trace_e1000e_mac_set_permanent(MAC_ARG(macaddr)); + memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac)); +-- +2.22.0.windows.1 + diff --git a/block-Avoid-memleak-on-qcow2-image-info-failure.patch b/block-Avoid-memleak-on-qcow2-image-info-failure.patch new file mode 100644 index 0000000000000000000000000000000000000000..13917f5b61ed267f584feac9041450e6fe9bbca6 --- /dev/null +++ b/block-Avoid-memleak-on-qcow2-image-info-failure.patch @@ -0,0 +1,35 @@ +From 6a39af8880c18fb3bcbfb715aef909c64286524e Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 20 Mar 2020 13:36:20 -0500 +Subject: [PATCH 04/14] block: Avoid memleak on qcow2 image info failure + +If we fail to get bitmap info, we must not leak the encryption info. + +Fixes: b8968c875f403 +Fixes: Coverity CID 1421894 +Signed-off-by: Eric Blake +Message-Id: <20200320183620.1112123-1-eblake@redhat.com> +Reviewed-by: Vladimir Sementsov-Ogievskiy +Reviewed-by: Andrey Shinkevich +Tested-by: Andrey Shinkevich +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 27c54b9905aa..0f4b0940d457 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -4588,6 +4588,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, + if (local_err) { + error_propagate(errp, local_err); + qapi_free_ImageInfoSpecific(spec_info); ++ qapi_free_QCryptoBlockInfo(encrypt_info); + return NULL; + } + *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ +-- +2.26.2 + diff --git a/block-bdrv_set_backing_bs-fix-use-after-free.patch b/block-bdrv_set_backing_bs-fix-use-after-free.patch new file mode 100644 index 0000000000000000000000000000000000000000..93ac72169d8518a8fcadc82c7ee01fcfdfcf94fc --- /dev/null +++ b/block-bdrv_set_backing_bs-fix-use-after-free.patch @@ -0,0 +1,116 @@ +From 3754525eb383f91869634766ccd041cfe40bbf17 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Mon, 16 Mar 2020 09:06:30 +0300 +Subject: [PATCH 05/14] block: bdrv_set_backing_bs: fix use-after-free +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is a use-after-free possible: bdrv_unref_child() leaves +bs->backing freed but not NULL. bdrv_attach_child may produce nested +polling loop due to drain, than access of freed pointer is possible. + +I've produced the following crash on 30 iotest with modified code. It +does not reproduce on master, but still seems possible: + + #0 __strcmp_avx2 () at /lib64/libc.so.6 + #1 bdrv_backing_overridden (bs=0x55c9d3cc2060) at block.c:6350 + #2 bdrv_refresh_filename (bs=0x55c9d3cc2060) at block.c:6404 + #3 bdrv_backing_attach (c=0x55c9d48e5520) at block.c:1063 + #4 bdrv_replace_child_noperm + (child=child@entry=0x55c9d48e5520, + new_bs=new_bs@entry=0x55c9d3cc2060) at block.c:2290 + #5 bdrv_replace_child + (child=child@entry=0x55c9d48e5520, + new_bs=new_bs@entry=0x55c9d3cc2060) at block.c:2320 + #6 bdrv_root_attach_child + (child_bs=child_bs@entry=0x55c9d3cc2060, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + ctx=, perm=, shared_perm=21, + opaque=0x55c9d3c5a3d0, errp=0x7ffd117108e0) at block.c:2424 + #7 bdrv_attach_child + (parent_bs=parent_bs@entry=0x55c9d3c5a3d0, + child_bs=child_bs@entry=0x55c9d3cc2060, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + errp=errp@entry=0x7ffd117108e0) at block.c:5876 + #8 in bdrv_set_backing_hd + (bs=bs@entry=0x55c9d3c5a3d0, + backing_hd=backing_hd@entry=0x55c9d3cc2060, + errp=errp@entry=0x7ffd117108e0) + at block.c:2576 + #9 stream_prepare (job=0x55c9d49d84a0) at block/stream.c:150 + #10 job_prepare (job=0x55c9d49d84a0) at job.c:761 + #11 job_txn_apply (txn=, fn=) at + job.c:145 + #12 job_do_finalize (job=0x55c9d49d84a0) at job.c:778 + #13 job_completed_txn_success (job=0x55c9d49d84a0) at job.c:832 + #14 job_completed (job=0x55c9d49d84a0) at job.c:845 + #15 job_completed (job=0x55c9d49d84a0) at job.c:836 + #16 job_exit (opaque=0x55c9d49d84a0) at job.c:864 + #17 aio_bh_call (bh=0x55c9d471a160) at util/async.c:117 + #18 aio_bh_poll (ctx=ctx@entry=0x55c9d3c46720) at util/async.c:117 + #19 aio_poll (ctx=ctx@entry=0x55c9d3c46720, + blocking=blocking@entry=true) + at util/aio-posix.c:728 + #20 bdrv_parent_drained_begin_single (poll=true, c=0x55c9d3d558f0) + at block/io.c:121 + #21 bdrv_parent_drained_begin_single (c=c@entry=0x55c9d3d558f0, + poll=poll@entry=true) + at block/io.c:114 + #22 bdrv_replace_child_noperm + (child=child@entry=0x55c9d3d558f0, + new_bs=new_bs@entry=0x55c9d3d27300) at block.c:2258 + #23 bdrv_replace_child + (child=child@entry=0x55c9d3d558f0, + new_bs=new_bs@entry=0x55c9d3d27300) at block.c:2320 + #24 bdrv_root_attach_child + (child_bs=child_bs@entry=0x55c9d3d27300, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + ctx=, perm=, shared_perm=21, + opaque=0x55c9d3cc2060, errp=0x7ffd11710c60) at block.c:2424 + #25 bdrv_attach_child + (parent_bs=parent_bs@entry=0x55c9d3cc2060, + child_bs=child_bs@entry=0x55c9d3d27300, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + errp=errp@entry=0x7ffd11710c60) at block.c:5876 + #26 bdrv_set_backing_hd + (bs=bs@entry=0x55c9d3cc2060, + backing_hd=backing_hd@entry=0x55c9d3d27300, + errp=errp@entry=0x7ffd11710c60) + at block.c:2576 + #27 stream_prepare (job=0x55c9d495ead0) at block/stream.c:150 + ... + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200316060631.30052-2-vsementsov@virtuozzo.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: John Snow +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block.c b/block.c +index 29e504b86aff..e834102c87f7 100644 +--- a/block.c ++++ b/block.c +@@ -2549,10 +2549,10 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, + + if (bs->backing) { + bdrv_unref_child(bs, bs->backing); ++ bs->backing = NULL; + } + + if (!backing_hd) { +- bs->backing = NULL; + goto out; + } + +-- +2.26.2 + diff --git a/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch b/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch new file mode 100644 index 0000000000000000000000000000000000000000..d901f1062659223d2899ab5520759a6a5065545a --- /dev/null +++ b/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch @@ -0,0 +1,33 @@ +From 5060ef71fa4621061101a30fa9e0d1690696c5c1 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:59:21 +0300 +Subject: [PATCH 10/14] block: fix bdrv_root_attach_child forget to unref + child_bs + +bdrv_root_attach_child promises to drop child_bs reference on failure. +It does it on first handled failure path, but not on the second. Fix +that. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324155921.23822-1-vsementsov@virtuozzo.com> +Signed-off-by: Kevin Wolf +Signed-off-by: Peng Liang +--- + block.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block.c b/block.c +index e834102c87f7..38880eabf801 100644 +--- a/block.c ++++ b/block.c +@@ -2399,6 +2399,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, + error_propagate(errp, local_err); + g_free(child); + bdrv_abort_perm_update(child_bs); ++ bdrv_unref(child_bs); + return NULL; + } + } +-- +2.26.2 + diff --git a/block-mirror-fix-use-after-free-of-local_err.patch b/block-mirror-fix-use-after-free-of-local_err.patch new file mode 100644 index 0000000000000000000000000000000000000000..ea2f739410164f7df43f020192cd60653a3b8cf0 --- /dev/null +++ b/block-mirror-fix-use-after-free-of-local_err.patch @@ -0,0 +1,34 @@ +From 682d23829adf0a872d5a3ca6eb4b31c424f558fc Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:26 +0300 +Subject: [PATCH 09/14] block/mirror: fix use after free of local_err + +local_err is used again in mirror_exit_common() after +bdrv_set_backing_hd(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-3-vsementsov@virtuozzo.com> +Reviewed-by: Eric Blake +Reviewed-by: John Snow +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/mirror.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/mirror.c b/block/mirror.c +index 681b305de650..ef6c958ff9b3 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -674,6 +674,7 @@ static int mirror_exit_common(Job *job) + bdrv_set_backing_hd(target_bs, backing, &local_err); + if (local_err) { + error_report_err(local_err); ++ local_err = NULL; + ret = -EPERM; + } + } +-- +2.26.2 + diff --git a/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch b/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch new file mode 100644 index 0000000000000000000000000000000000000000..44b0ea19e95b95bbd583034e9c830e3dd6d647e6 --- /dev/null +++ b/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch @@ -0,0 +1,54 @@ +From 88ef4e1862987227f8b87228cff94be3af66d054 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Thu, 27 Feb 2020 09:29:49 +0800 +Subject: [PATCH 01/14] block/qcow2: do free crypto_opts in qcow2_close() + +'crypto_opts' forgot to free in qcow2_close(), this patch fix the bellow leak stack: + +Direct leak of 24 byte(s) in 1 object(s) allocated from: + #0 0x7f0edd81f970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970) + #1 0x7f0edc6d149d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d) + #2 0x55d7eaede63d in qobject_input_start_struct /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qobject-input-visitor.c:295 + #3 0x55d7eaed78b8 in visit_start_struct /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qapi-visit-core.c:49 + #4 0x55d7eaf5140b in visit_type_QCryptoBlockOpenOptions qapi/qapi-visit-crypto.c:290 + #5 0x55d7eae43af3 in block_crypto_open_opts_init /mnt/sdb/qemu-new/qemu_test/qemu/block/crypto.c:163 + #6 0x55d7eacd2924 in qcow2_update_options_prepare /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1148 + #7 0x55d7eacd33f7 in qcow2_update_options /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1232 + #8 0x55d7eacd9680 in qcow2_do_open /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1512 + #9 0x55d7eacdc55e in qcow2_open_entry /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1792 + #10 0x55d7eacdc8fe in qcow2_open /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1819 + #11 0x55d7eac3742d in bdrv_open_driver /mnt/sdb/qemu-new/qemu_test/qemu/block.c:1317 + #12 0x55d7eac3e990 in bdrv_open_common /mnt/sdb/qemu-new/qemu_test/qemu/block.c:1575 + #13 0x55d7eac4442c in bdrv_open_inherit /mnt/sdb/qemu-new/qemu_test/qemu/block.c:3126 + #14 0x55d7eac45c3f in bdrv_open /mnt/sdb/qemu-new/qemu_test/qemu/block.c:3219 + #15 0x55d7ead8e8a4 in blk_new_open /mnt/sdb/qemu-new/qemu_test/qemu/block/block-backend.c:397 + #16 0x55d7eacde74c in qcow2_co_create /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:3534 + #17 0x55d7eacdfa6d in qcow2_co_create_opts /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:3668 + #18 0x55d7eac1c678 in bdrv_create_co_entry /mnt/sdb/qemu-new/qemu_test/qemu/block.c:485 + #19 0x55d7eb0024d2 in coroutine_trampoline /mnt/sdb/qemu-new/qemu_test/qemu/util/coroutine-ucontext.c:115 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Max Reitz +Message-Id: <20200227012950.12256-2-pannengyuan@huawei.com> +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 1909df6e1d24..27c54b9905aa 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -2408,6 +2408,7 @@ static void qcow2_close(BlockDriverState *bs) + + qcrypto_block_free(s->crypto); + s->crypto = NULL; ++ qapi_free_QCryptoBlockOpenOptions(s->crypto_opts); + + g_free(s->unknown_header_fields); + cleanup_unknown_header_ext(bs); +-- +2.26.2 + diff --git a/block-qcow2-threads-fix-qcow2_decompress.patch b/block-qcow2-threads-fix-qcow2_decompress.patch new file mode 100644 index 0000000000000000000000000000000000000000..d2fd9ee74fc5b57fb57ee1f655763895f1fe4356 --- /dev/null +++ b/block-qcow2-threads-fix-qcow2_decompress.patch @@ -0,0 +1,75 @@ +From a583b6b616b086d3fdce93e255d24ab2c865efd3 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Mon, 2 Mar 2020 18:09:30 +0300 +Subject: [PATCH 03/14] block/qcow2-threads: fix qcow2_decompress +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On success path we return what inflate() returns instead of 0. And it +most probably works for Z_STREAM_END as it is positive, but is +definitely broken for Z_BUF_ERROR. + +While being here, switch to errno return code, to be closer to +qcow2_compress API (and usual expectations). + +Revert condition in if to be more positive. Drop dead initialization of +ret. + +Cc: qemu-stable@nongnu.org # v4.0 +Fixes: 341926ab83e2b +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200302150930.16218-1-vsementsov@virtuozzo.com> +Reviewed-by: Alberto Garcia +Reviewed-by: Ján Tomko +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2-threads.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c +index 3b1e63fe414d..449cd3c0a1f4 100644 +--- a/block/qcow2-threads.c ++++ b/block/qcow2-threads.c +@@ -128,12 +128,12 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size, + * @src - source buffer, @src_size bytes + * + * Returns: 0 on success +- * -1 on fail ++ * -EIO on fail + */ + static ssize_t qcow2_decompress(void *dest, size_t dest_size, + const void *src, size_t src_size) + { +- int ret = 0; ++ int ret; + z_stream strm; + + memset(&strm, 0, sizeof(strm)); +@@ -144,17 +144,19 @@ static ssize_t qcow2_decompress(void *dest, size_t dest_size, + + ret = inflateInit2(&strm, -12); + if (ret != Z_OK) { +- return -1; ++ return -EIO; + } + + ret = inflate(&strm, Z_FINISH); +- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) { ++ if ((ret == Z_STREAM_END || ret == Z_BUF_ERROR) && strm.avail_out == 0) { + /* + * We approve Z_BUF_ERROR because we need @dest buffer to be filled, but + * @src buffer may be processed partly (because in qcow2 we know size of + * compressed data with precision of one sector) + */ +- ret = -1; ++ ret = 0; ++ } else { ++ ret = -EIO; + } + + inflateEnd(&strm); +-- +2.26.2 + diff --git a/char-fix-use-after-free-with-dup-chardev-reconnect.patch b/char-fix-use-after-free-with-dup-chardev-reconnect.patch new file mode 100644 index 0000000000000000000000000000000000000000..fd81015a18beced443caef903d0ec1f2a1fd8850 --- /dev/null +++ b/char-fix-use-after-free-with-dup-chardev-reconnect.patch @@ -0,0 +1,126 @@ +From 902a8192600ff81681a162509e23bf95619d1f04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 Apr 2020 13:20:12 +0200 +Subject: [PATCH] char: fix use-after-free with dup chardev & reconnect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With a reconnect socket, qemu_char_open() will start a background +thread. It should keep a reference on the chardev. + +Fixes invalid read: +READ of size 8 at 0x6040000ac858 thread T7 + #0 0x5555598d37b8 in unix_connect_saddr /home/elmarco/src/qq/util/qemu-sockets.c:954 + #1 0x5555598d4751 in socket_connect /home/elmarco/src/qq/util/qemu-sockets.c:1109 + #2 0x555559707c34 in qio_channel_socket_connect_sync /home/elmarco/src/qq/io/channel-socket.c:145 + #3 0x5555596adebb in tcp_chr_connect_client_task /home/elmarco/src/qq/chardev/char-socket.c:1104 + #4 0x555559723d55 in qio_task_thread_worker /home/elmarco/src/qq/io/task.c:123 + #5 0x5555598a6731 in qemu_thread_start /home/elmarco/src/qq/util/qemu-thread-posix.c:519 + #6 0x7ffff40d4431 in start_thread (/lib64/libpthread.so.0+0x9431) + #7 0x7ffff40029d2 in __clone (/lib64/libc.so.6+0x1019d2) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Daniel P. Berrangé +Message-Id: <20200420112012.567284-1-marcandre.lureau@redhat.com> +Signed-off-by: Zhenyu Ye +--- + chardev/char-socket.c | 3 ++- + tests/test-char.c | 53 ++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 54 insertions(+), 2 deletions(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 7ca5d97a..701b62f9 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -1118,7 +1118,8 @@ static void tcp_chr_connect_client_async(Chardev *chr) + */ + s->connect_task = qio_task_new(OBJECT(sioc), + qemu_chr_socket_connected, +- chr, NULL); ++ object_ref(OBJECT(chr)), ++ (GDestroyNotify)object_unref); + qio_task_run_in_thread(s->connect_task, + tcp_chr_connect_client_task, + s->addr, +diff --git a/tests/test-char.c b/tests/test-char.c +index f9440cdc..0e4069fb 100644 +--- a/tests/test-char.c ++++ b/tests/test-char.c +@@ -871,6 +871,53 @@ typedef struct { + } CharSocketClientTestConfig; + + ++static void char_socket_client_dupid_test(gconstpointer opaque) ++{ ++ const CharSocketClientTestConfig *config = opaque; ++ QIOChannelSocket *ioc; ++ char *optstr; ++ Chardev *chr1, *chr2; ++ SocketAddress *addr; ++ QemuOpts *opts; ++ Error *local_err = NULL; ++ ++ /* ++ * Setup a listener socket and determine get its address ++ * so we know the TCP port for the client later ++ */ ++ ioc = qio_channel_socket_new(); ++ g_assert_nonnull(ioc); ++ qio_channel_socket_listen_sync(ioc, config->addr, &error_abort); ++ addr = qio_channel_socket_get_local_address(ioc, &error_abort); ++ g_assert_nonnull(addr); ++ ++ /* ++ * Populate the chardev address based on what the server ++ * is actually listening on ++ */ ++ optstr = char_socket_addr_to_opt_str(addr, ++ config->fd_pass, ++ config->reconnect, ++ false); ++ ++ opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), ++ optstr, true); ++ g_assert_nonnull(opts); ++ chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort); ++ g_assert_nonnull(chr1); ++ ++ chr2 = qemu_chr_new_from_opts(opts, NULL, &local_err); ++ g_assert_null(chr2); ++ error_free_or_abort(&local_err); ++ ++ object_unref(OBJECT(ioc)); ++ qemu_opts_del(opts); ++ object_unparent(OBJECT(chr1)); ++ qapi_free_SocketAddress(addr); ++ g_free(optstr); ++} ++ ++ + static void char_socket_client_test(gconstpointer opaque) + { + const CharSocketClientTestConfig *config = opaque; +@@ -1425,6 +1472,8 @@ int main(int argc, char **argv) + { addr, NULL, false, true }; \ + CharSocketClientTestConfig client6 ## name = \ + { addr, NULL, true, true }; \ ++ CharSocketClientTestConfig client7 ## name = \ ++ { addr, ",reconnect=1", false, false }; \ + g_test_add_data_func("/char/socket/client/mainloop/" # name, \ + &client1 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn/" # name, \ +@@ -1436,7 +1485,9 @@ int main(int argc, char **argv) + g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \ + &client5 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \ +- &client6 ##name, char_socket_client_test) ++ &client6 ##name, char_socket_client_test); \ ++ g_test_add_data_func("/char/socket/client/dupid-reconnect/" # name, \ ++ &client7 ##name, char_socket_client_dupid_test) + + SOCKET_SERVER_TEST(tcp, &tcpaddr); + SOCKET_CLIENT_TEST(tcp, &tcpaddr); +-- +2.22.0.windows.1 + diff --git a/chardev-tcp-Fix-error-message-double-free-error.patch b/chardev-tcp-Fix-error-message-double-free-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..175ddfe2dea85111016d162aa0cd95d79a49a492 --- /dev/null +++ b/chardev-tcp-Fix-error-message-double-free-error.patch @@ -0,0 +1,43 @@ +From 4488ab4700d344b049ddef808a64eda4b5867902 Mon Sep 17 00:00:00 2001 +From: lichun +Date: Mon, 22 Jun 2020 05:30:17 +0800 +Subject: [PATCH 06/11] chardev/tcp: Fix error message double free error + +Errors are already freed by error_report_err, so we only need to call +error_free when that function is not called. + +Cc: qemu-stable@nongnu.org +Signed-off-by: lichun +Message-Id: <20200621213017.17978-1-lichun@ruijie.com.cn> +Reviewed-by: Markus Armbruster +[Commit message improved, cc: qemu-stable] +Signed-off-by: Markus Armbruster +Signed-off-by: BiaoXiang Ye +--- + chardev/char-socket.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 701b62f9..9b06c8aa 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -141,6 +141,8 @@ static void check_report_connect_error(Chardev *chr, + error_report("Unable to connect character device %s: %s", + chr->label, error_get_pretty(err)); + s->connect_err_reported = true; ++ } else { ++ error_free(err); + } + qemu_chr_socket_restart_timer(chr); + } +@@ -1074,7 +1076,6 @@ static void qemu_chr_socket_connected(QIOTask *task, void *opaque) + if (qio_task_propagate_error(task, &err)) { + tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); + check_report_connect_error(chr, err); +- error_free(err); + goto cleanup; + } + +-- +2.27.0.dirty + diff --git a/colo-compare-Fix-memory-leak-in-packet_enqueue.patch b/colo-compare-Fix-memory-leak-in-packet_enqueue.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca5e43c49a6ad18fa7c6d204c1eabfac7ed6ddd5 --- /dev/null +++ b/colo-compare-Fix-memory-leak-in-packet_enqueue.patch @@ -0,0 +1,90 @@ +From 19afb1431bd730a1e4e09e3c0835c35572517268 Mon Sep 17 00:00:00 2001 +From: Derek Su +Date: Fri, 22 May 2020 15:53:57 +0800 +Subject: [PATCH 07/11] colo-compare: Fix memory leak in packet_enqueue() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The patch is to fix the "pkt" memory leak in packet_enqueue(). +The allocated "pkt" needs to be freed if the colo compare +primary or secondary queue is too big. + +Replace the error_report of full queue with a trace event. + +Signed-off-by: Derek Su +Reviewed-by: Zhang Chen +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Zhang Chen +Signed-off-by: Jason Wang +Signed-off-by: BiaoXiang Ye +--- + net/colo-compare.c | 23 +++++++++++++++-------- + net/trace-events | 1 + + 2 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/net/colo-compare.c b/net/colo-compare.c +index 7ee17f2c..3168407e 100644 +--- a/net/colo-compare.c ++++ b/net/colo-compare.c +@@ -120,6 +120,10 @@ enum { + SECONDARY_IN, + }; + ++static const char *colo_mode[] = { ++ [PRIMARY_IN] = "primary", ++ [SECONDARY_IN] = "secondary", ++}; + + static int compare_chr_send(CompareState *s, + const uint8_t *buf, +@@ -215,6 +219,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) + ConnectionKey key; + Packet *pkt = NULL; + Connection *conn; ++ int ret; + + if (mode == PRIMARY_IN) { + pkt = packet_new(s->pri_rs.buf, +@@ -243,16 +248,18 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) + } + + if (mode == PRIMARY_IN) { +- if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) { +- error_report("colo compare primary queue size too big," +- "drop packet"); +- } ++ ret = colo_insert_packet(&conn->primary_list, pkt, &conn->pack); + } else { +- if (!colo_insert_packet(&conn->secondary_list, pkt, &conn->sack)) { +- error_report("colo compare secondary queue size too big," +- "drop packet"); +- } ++ ret = colo_insert_packet(&conn->secondary_list, pkt, &conn->sack); + } ++ ++ if (!ret) { ++ trace_colo_compare_drop_packet(colo_mode[mode], ++ "queue size too big, drop packet"); ++ packet_destroy(pkt, NULL); ++ pkt = NULL; ++ } ++ + *con = conn; + + return 0; +diff --git a/net/trace-events b/net/trace-events +index ac570564..a9995387 100644 +--- a/net/trace-events ++++ b/net/trace-events +@@ -12,6 +12,7 @@ colo_proxy_main(const char *chr) ": %s" + + # colo-compare.c + colo_compare_main(const char *chr) ": %s" ++colo_compare_drop_packet(const char *queue, const char *chr) ": %s: %s" + colo_compare_udp_miscompare(const char *sta, int size) ": %s = %d" + colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d" + colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s" +-- +2.27.0.dirty + diff --git a/cris-do-not-leak-struct-cris_disasm_data.patch b/cris-do-not-leak-struct-cris_disasm_data.patch new file mode 100644 index 0000000000000000000000000000000000000000..fa7623fe1878eca815805e853d64ff9b2d8a88a3 --- /dev/null +++ b/cris-do-not-leak-struct-cris_disasm_data.patch @@ -0,0 +1,139 @@ +From d0586065e67b5df2611f4cf61eb791d48b78ff77 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:42:59 +0800 +Subject: [PATCH] cris: do not leak struct cris_disasm_data + +Use a stack-allocated struct to avoid a memory leak. + +Signed-off-by: Paolo Bonzini +--- + disas/cris.c | 65 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 35 insertions(+), 30 deletions(-) + +diff --git a/disas/cris.c b/disas/cris.c +index 2f43c9b2..f3ff44ba 100644 +--- a/disas/cris.c ++++ b/disas/cris.c +@@ -1294,24 +1294,17 @@ static int cris_constraint + /* Parse disassembler options and store state in info. FIXME: For the + time being, we abuse static variables. */ + +-static bfd_boolean +-cris_parse_disassembler_options (disassemble_info *info, ++static void ++cris_parse_disassembler_options (struct cris_disasm_data *disdata, ++ char *disassembler_options, + enum cris_disass_family distype) + { +- struct cris_disasm_data *disdata; +- +- info->private_data = calloc (1, sizeof (struct cris_disasm_data)); +- disdata = (struct cris_disasm_data *) info->private_data; +- if (disdata == NULL) +- return false; +- + /* Default true. */ + disdata->trace_case +- = (info->disassembler_options == NULL +- || (strcmp (info->disassembler_options, "nocase") != 0)); ++ = (disassembler_options == NULL ++ || (strcmp (disassembler_options, "nocase") != 0)); + + disdata->distype = distype; +- return true; + } + + static const struct cris_spec_reg * +@@ -2736,9 +2729,11 @@ static int + print_insn_cris_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v0_v10); ++ + return print_insn_cris_generic (vma, info, true); + } + /* Disassemble, prefixing register names with `$'. CRIS v32. */ +@@ -2747,9 +2742,11 @@ static int + print_insn_crisv32_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v32); ++ + return print_insn_cris_generic (vma, info, true); + } + +@@ -2761,9 +2758,11 @@ static int + print_insn_crisv10_v32_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_common_v10_v32); ++ + return print_insn_cris_generic (vma, info, true); + } + +@@ -2773,9 +2772,11 @@ static int + print_insn_cris_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v0_v10); ++ + return print_insn_cris_generic (vma, info, false); + } + +@@ -2785,9 +2786,11 @@ static int + print_insn_crisv32_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v32); ++ + return print_insn_cris_generic (vma, info, false); + } + +@@ -2798,9 +2801,11 @@ static int + print_insn_crisv10_v32_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_common_v10_v32); ++ + return print_insn_cris_generic (vma, info, false); + } + #endif +-- +2.19.1 + diff --git a/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch b/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch new file mode 100644 index 0000000000000000000000000000000000000000..28c1e3bc6837063888bb8c862fb1e629f70de8be --- /dev/null +++ b/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch @@ -0,0 +1,31 @@ +From 94be73a20d42482cdf30115e672c36af2fe9068d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 17 Jul 2020 12:54:26 +0200 +Subject: [PATCH 5/5] file-posix: Fix leaked fd in raw_open_common() error path + +Signed-off-by: Kevin Wolf +Message-Id: <20200717105426.51134-4-kwolf@redhat.com> +Reviewed-by: Max Reitz +Signed-off-by: Kevin Wolf +Signed-off-by: Zhenyu Ye +--- + block/file-posix.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 2184aa98..1259bf58 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -671,6 +671,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; + ret = 0; + fail: ++ if (ret < 0 && s->fd != -1) { ++ qemu_close(s->fd); ++ } + if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { + unlink(filename); + } +-- +2.22.0.windows.1 + diff --git a/fix-vhost_user_blk_watch-crash.patch b/fix-vhost_user_blk_watch-crash.patch new file mode 100644 index 0000000000000000000000000000000000000000..905cbe3c2542b7d59f8d69da720bf0639a4be9bb --- /dev/null +++ b/fix-vhost_user_blk_watch-crash.patch @@ -0,0 +1,81 @@ +From 0b77995819a596f96c621697643e83624126e668 Mon Sep 17 00:00:00 2001 +From: Li Feng +Date: Mon, 23 Mar 2020 13:29:24 +0800 +Subject: [PATCH 13/14] fix vhost_user_blk_watch crash + +the G_IO_HUP is watched in tcp_chr_connect, and the callback +vhost_user_blk_watch is not needed, because tcp_chr_hup is registered as +callback. And it will close the tcp link. + +Signed-off-by: Li Feng +Message-Id: <20200323052924.29286-1-fengli@smartx.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/block/vhost-user-blk.c | 19 ------------------- + include/hw/virtio/vhost-user-blk.h | 1 - + 2 files changed, 20 deletions(-) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index 85bc4017e7e9..dc66f8a5febd 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -346,18 +346,6 @@ static void vhost_user_blk_disconnect(DeviceState *dev) + vhost_dev_cleanup(&s->dev); + } + +-static gboolean vhost_user_blk_watch(GIOChannel *chan, GIOCondition cond, +- void *opaque) +-{ +- DeviceState *dev = opaque; +- VirtIODevice *vdev = VIRTIO_DEVICE(dev); +- VHostUserBlk *s = VHOST_USER_BLK(vdev); +- +- qemu_chr_fe_disconnect(&s->chardev); +- +- return true; +-} +- + static void vhost_user_blk_event(void *opaque, int event) + { + DeviceState *dev = opaque; +@@ -370,15 +358,9 @@ static void vhost_user_blk_event(void *opaque, int event) + qemu_chr_fe_disconnect(&s->chardev); + return; + } +- s->watch = qemu_chr_fe_add_watch(&s->chardev, G_IO_HUP, +- vhost_user_blk_watch, dev); + break; + case CHR_EVENT_CLOSED: + vhost_user_blk_disconnect(dev); +- if (s->watch) { +- g_source_remove(s->watch); +- s->watch = 0; +- } + break; + } + } +@@ -419,7 +401,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) + + s->inflight = g_new0(struct vhost_inflight, 1); + s->vqs = g_new(struct vhost_virtqueue, s->num_queues); +- s->watch = 0; + s->connected = false; + + qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event, +diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h +index 8dbf11c6f071..ad9b742a644c 100644 +--- a/include/hw/virtio/vhost-user-blk.h ++++ b/include/hw/virtio/vhost-user-blk.h +@@ -38,7 +38,6 @@ typedef struct VHostUserBlk { + struct vhost_inflight *inflight; + VhostUserState vhost_user; + struct vhost_virtqueue *vqs; +- guint watch; + bool connected; + } VHostUserBlk; + +-- +2.26.2 + diff --git a/hmp-vnc-Fix-info-vnc-list-leak.patch b/hmp-vnc-Fix-info-vnc-list-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..ccc4e1db511a18c5da864a1d8b2732e9a4cd8a1f --- /dev/null +++ b/hmp-vnc-Fix-info-vnc-list-leak.patch @@ -0,0 +1,48 @@ +From 6cb599f75b7844aefd7823ad97fc3bae70eff11f Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Mon, 23 Mar 2020 12:08:22 +0000 +Subject: [PATCH 06/14] hmp/vnc: Fix info vnc list leak + +We're iterating the list, and then freeing the iteration pointer rather +than the list head. + +Fixes: 0a9667ecdb6d ("hmp: Update info vnc") +Reported-by: Coverity (CID 1421932) +Signed-off-by: Dr. David Alan Gilbert +Message-Id: <20200323120822.51266-1-dgilbert@redhat.com> +Reviewed-by: Peter Maydell +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + monitor/hmp-cmds.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 5ca3ebe94272..fc5d6b92c4b6 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -745,10 +745,11 @@ static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server) + + void hmp_info_vnc(Monitor *mon, const QDict *qdict) + { +- VncInfo2List *info2l; ++ VncInfo2List *info2l, *info2l_head; + Error *err = NULL; + + info2l = qmp_query_vnc_servers(&err); ++ info2l_head = info2l; + if (err) { + hmp_handle_error(mon, &err); + return; +@@ -777,7 +778,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict) + info2l = info2l->next; + } + +- qapi_free_VncInfo2List(info2l); ++ qapi_free_VncInfo2List(info2l_head); + + } + #endif +-- +2.26.2 + diff --git a/hppa-fix-leak-from-g_strdup_printf.patch b/hppa-fix-leak-from-g_strdup_printf.patch new file mode 100644 index 0000000000000000000000000000000000000000..b04193e380fe58ef14e91cb56d162abc264dce9b --- /dev/null +++ b/hppa-fix-leak-from-g_strdup_printf.patch @@ -0,0 +1,54 @@ +From b7ef7e6fb5a2b08268f4b19c07c07abd4fbb2064 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:48:49 +0800 +Subject: [PATCH] hppa: fix leak from g_strdup_printf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +memory_region_init_* takes care of copying the name into memory it owns. +Free it in the caller. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/hppa/dino.c | 1 + + hw/hppa/machine.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c +index e94614ab..ef923b49 100644 +--- a/hw/hppa/dino.c ++++ b/hw/hppa/dino.c +@@ -485,6 +485,7 @@ PCIBus *dino_init(MemoryRegion *addr_space, + memory_region_init_alias(&s->pci_mem_alias[i], OBJECT(s), + name, &s->pci_mem, addr, + DINO_MEM_CHUNK_SIZE); ++ g_free(name); + } + + /* Set up PCI view of memory: Bus master address space. */ +diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c +index 662838d8..9e25660e 100644 +--- a/hw/hppa/machine.c ++++ b/hw/hppa/machine.c +@@ -78,13 +78,15 @@ static void machine_hppa_init(MachineState *machine) + + /* Create CPUs. */ + for (i = 0; i < smp_cpus; i++) { ++ char *name = g_strdup_printf("cpu%ld-io-eir", i); + cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); + + cpu_region = g_new(MemoryRegion, 1); + memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, +- cpu[i], g_strdup_printf("cpu%ld-io-eir", i), 4); ++ cpu[i], name, 4); + memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000, + cpu_region); ++ g_free(name); + } + + /* Limit main memory. */ +-- +2.19.1 + diff --git a/hw-arm-virt-Init-PMU-for-hotplugged-vCPU.patch b/hw-arm-virt-Init-PMU-for-hotplugged-vCPU.patch new file mode 100644 index 0000000000000000000000000000000000000000..c124df5394121fdb0415b3b85d04fc3417a747aa --- /dev/null +++ b/hw-arm-virt-Init-PMU-for-hotplugged-vCPU.patch @@ -0,0 +1,73 @@ +From acc5162f1d1591ee4830f9b67934fc6d8a9ebbc1 Mon Sep 17 00:00:00 2001 +From: Keqian Zhu +Date: Tue, 8 Sep 2020 22:09:44 +0800 +Subject: [PATCH] hw/arm/virt: Init PMU for hotplugged vCPU + +Factor out PMU init code from fdt_add_pmu_nodes and +do PMU init for hotplugged vCPU. + +Signed-off-by: Keqian Zhu +--- + hw/arm/virt.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 7afc6c5e..7506d0ff 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -605,6 +605,23 @@ static void fdt_add_gic_node(VirtMachineState *vms) + g_free(nodename); + } + ++static bool virt_cpu_init_pmu(const VirtMachineState *vms, CPUState *cpu) ++{ ++ ARMCPU *armcpu = ARM_CPU(cpu); ++ ++ if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU)) { ++ return false; ++ } ++ if (kvm_enabled()) { ++ if (kvm_irqchip_in_kernel()) { ++ kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ)); ++ } ++ kvm_arm_pmu_init(cpu); ++ } ++ ++ return true; ++} ++ + static void fdt_add_pmu_nodes(const VirtMachineState *vms) + { + CPUState *cpu; +@@ -612,16 +629,9 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) + uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; + + CPU_FOREACH(cpu) { +- armcpu = ARM_CPU(cpu); +- if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU)) { ++ if (!virt_cpu_init_pmu(vms, cpu)) { + return; + } +- if (kvm_enabled()) { +- if (kvm_irqchip_in_kernel()) { +- kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ)); +- } +- kvm_arm_pmu_init(cpu); +- } + } + + if (vms->gic_version == 2) { +@@ -2248,6 +2258,9 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, + agcc->cpu_hotplug_realize(gicv3, ncpu); + connect_gic_cpu_irqs(vms, ncpu); + ++ /* Init PMU part */ ++ virt_cpu_init_pmu(vms, cs); ++ + /* Register CPU reset and trigger it manually */ + cpu_synchronize_state(cs); + cpu_hotplug_register_reset(ncpu); +-- +2.23.0 + + diff --git a/hw-block-nvme-fix-pci-doorbell-size-calculation.patch b/hw-block-nvme-fix-pci-doorbell-size-calculation.patch new file mode 100644 index 0000000000000000000000000000000000000000..f0aa09670e471a344c220ae38b8f5ba43b263eaf --- /dev/null +++ b/hw-block-nvme-fix-pci-doorbell-size-calculation.patch @@ -0,0 +1,62 @@ +From 1aa42c9269c762ad1b7efa41e92f734b093dce1c Mon Sep 17 00:00:00 2001 +From: Klaus Jensen +Date: Tue, 9 Jun 2020 21:03:12 +0200 +Subject: [PATCH 10/11] hw/block/nvme: fix pci doorbell size calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The size of the BAR is 0x1000 (main registers) + 8 bytes for each +queue. Currently, the size of the BAR is calculated like so: + + n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4); + +Since the 'num_queues' parameter already accounts for the admin queue, +this should in any case not need to be incremented by one. Also, the +size should be initialized to (0x1000). + + n->reg_size = pow2ceil(0x1000 + 2 * n->num_queues * 4); + +This, with the default value of num_queues (64), we will set aside room +for 1 admin queue and 63 I/O queues (4 bytes per doorbell, 2 doorbells +per queue). + +Signed-off-by: Klaus Jensen +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Maxim Levitsky +Reviewed-by: Keith Busch +Message-Id: <20200609190333.59390-2-its@irrelevant.dk> +Signed-off-by: Kevin Wolf +Signed-off-by: BiaoXiang Ye +--- + hw/block/nvme.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hw/block/nvme.c b/hw/block/nvme.c +index 417068d8..edac2f1d 100644 +--- a/hw/block/nvme.c ++++ b/hw/block/nvme.c +@@ -42,6 +42,9 @@ + #include "trace.h" + #include "nvme.h" + ++#define NVME_REG_SIZE 0x1000 ++#define NVME_DB_SIZE 4 ++ + #define NVME_GUEST_ERR(trace, fmt, ...) \ + do { \ + (trace_##trace)(__VA_ARGS__); \ +@@ -1348,7 +1351,9 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) + pcie_endpoint_cap_init(pci_dev, 0x80); + + n->num_namespaces = 1; +- n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4); ++ ++ /* num_queues is really number of pairs, so each has two doorbells */ ++ n->reg_size = pow2ceil(NVME_REG_SIZE + 2 * n->num_queues * NVME_DB_SIZE); + n->ns_size = bs_size / (uint64_t)n->num_namespaces; + + n->namespaces = g_new0(NvmeNamespace, n->num_namespaces); +-- +2.27.0.dirty + diff --git a/hw-block-nvme-fix-pin-based-interrupt-behavior.patch b/hw-block-nvme-fix-pin-based-interrupt-behavior.patch new file mode 100644 index 0000000000000000000000000000000000000000..1fe1213d998869c0f87eabd5d75fc62c3750f06b --- /dev/null +++ b/hw-block-nvme-fix-pin-based-interrupt-behavior.patch @@ -0,0 +1,87 @@ +From 74ef18c90684f0ae18aef071b9e11a5e8796177b Mon Sep 17 00:00:00 2001 +From: alexchen +Date: Tue, 8 Sep 2020 11:17:20 +0000 +Subject: [PATCH] hw/block/nvme: fix pin-based interrupt behavior + +First, since the device only supports MSI-X or pin-based interrupt, if +MSI-X is not enabled, it should not accept interrupt vectors different +from 0 when creating completion queues. + +Secondly, the irq_status NvmeCtrl member is meant to be compared to the +INTMS register, so it should only be 32 bits wide. And it is really only +useful when used with multi-message MSI. + +Third, since we do not force a 1-to-1 correspondence between cqid and +interrupt vector, the irq_status register should not have bits set +according to cqid, but according to the associated interrupt vector. + +Fix these issues, but keep irq_status available so we can easily support +multi-message MSI down the line. + +Fixes: 5e9aa92eb1a5 ("hw/block: Fix pin-based interrupt behaviour of NVMe") +Cc: "Michael S. Tsirkin" +Cc: Marcel Apfelbaum +Signed-off-by: Klaus Jensen +Reviewed-by: Keith Busch +Message-Id: <20200609190333.59390-8-its@irrelevant.dk> +Signed-off-by: Kevin Wolf +Signed-off-by: BiaoXiang Ye +Signed-off-by: Zhenyu Ye +--- + hw/block/nvme.c | 12 ++++++++---- + hw/block/nvme.h | 2 +- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/hw/block/nvme.c b/hw/block/nvme.c +index 36d6a8bb..e35c2e10 100644 +--- a/hw/block/nvme.c ++++ b/hw/block/nvme.c +@@ -115,8 +115,8 @@ static void nvme_irq_assert(NvmeCtrl *n, NvmeCQueue *cq) + msix_notify(&(n->parent_obj), cq->vector); + } else { + trace_nvme_irq_pin(); +- assert(cq->cqid < 64); +- n->irq_status |= 1 << cq->cqid; ++ assert(cq->vector < 32); ++ n->irq_status |= 1 << cq->vector; + nvme_irq_check(n); + } + } else { +@@ -130,8 +130,8 @@ static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq) + if (msix_enabled(&(n->parent_obj))) { + return; + } else { +- assert(cq->cqid < 64); +- n->irq_status &= ~(1 << cq->cqid); ++ assert(cq->vector < 32); ++ n->irq_status &= ~(1 << cq->vector); + nvme_irq_check(n); + } + } +@@ -630,6 +630,10 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd) + trace_nvme_err_invalid_create_cq_addr(prp1); + return NVME_INVALID_FIELD | NVME_DNR; + } ++ if (unlikely(!msix_enabled(&n->parent_obj) && vector)) { ++ trace_nvme_err_invalid_create_cq_vector(vector); ++ return NVME_INVALID_IRQ_VECTOR | NVME_DNR; ++ } + if (unlikely(vector > n->num_queues)) { + trace_nvme_err_invalid_create_cq_vector(vector); + return NVME_INVALID_IRQ_VECTOR | NVME_DNR; +diff --git a/hw/block/nvme.h b/hw/block/nvme.h +index 557194ee..f4c1ff91 100644 +--- a/hw/block/nvme.h ++++ b/hw/block/nvme.h +@@ -78,7 +78,7 @@ typedef struct NvmeCtrl { + uint32_t cmbsz; + uint32_t cmbloc; + uint8_t *cmbuf; +- uint64_t irq_status; ++ uint32_t irq_status; + uint64_t host_timestamp; /* Timestamp sent by the host */ + uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */ + +-- +2.23.0 + diff --git a/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch b/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch new file mode 100644 index 0000000000000000000000000000000000000000..76497d9ef4f4e111baba53cdd84ac7b7dbecb112 --- /dev/null +++ b/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch @@ -0,0 +1,67 @@ +From 595a0d0a0f21cd73863ea3b78ecccb6e0ea8b7a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Mon, 1 Jun 2020 16:29:25 +0200 +Subject: [PATCH 2/5] hw/pci/pci_bridge: Correct pci_bridge_io memory region + size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +memory_region_set_size() handle the 16 Exabytes limit by +special-casing the UINT64_MAX value. This is not a problem +for the 32-bit maximum, 4 GiB. +By using the UINT32_MAX value, the pci_bridge_io MemoryRegion +ends up missing 1 byte: + + (qemu) info mtree + memory-region: pci_bridge_io + 0000000000000000-00000000fffffffe (prio 0, i/o): pci_bridge_io + 0000000000000060-0000000000000060 (prio 0, i/o): i8042-data + 0000000000000064-0000000000000064 (prio 0, i/o): i8042-cmd + 00000000000001ce-00000000000001d1 (prio 0, i/o): vbe + 0000000000000378-000000000000037f (prio 0, i/o): parallel + 00000000000003b4-00000000000003b5 (prio 0, i/o): vga + ... + +Fix by using the correct value. We now have: + + memory-region: pci_bridge_io + 0000000000000000-00000000ffffffff (prio 0, i/o): pci_bridge_io + 0000000000000060-0000000000000060 (prio 0, i/o): i8042-data + 0000000000000064-0000000000000064 (prio 0, i/o): i8042-cmd + ... + +Reviewed-by: Peter Maydell +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20200601142930.29408-4-f4bug@amsat.org> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Richard Henderson +--- + hw/pci/pci_bridge.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c +index 715b9a4f..d67c691d 100644 +--- a/hw/pci/pci_bridge.c ++++ b/hw/pci/pci_bridge.c +@@ -30,6 +30,7 @@ + */ + + #include "qemu/osdep.h" ++#include "qemu/units.h" + #include "hw/pci/pci_bridge.h" + #include "hw/pci/pci_bus.h" + #include "qemu/module.h" +@@ -381,7 +382,7 @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename) + memory_region_init(&br->address_space_mem, OBJECT(br), "pci_bridge_pci", UINT64_MAX); + sec_bus->address_space_io = &br->address_space_io; + memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io", +- UINT32_MAX); ++ 4 * GiB); + br->windows = pci_bridge_region_init(br); + QLIST_INIT(&sec_bus->child); + QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); +-- +2.23.0 + diff --git a/ide-fix-leak-from-qemu_allocate_irqs.patch b/ide-fix-leak-from-qemu_allocate_irqs.patch new file mode 100644 index 0000000000000000000000000000000000000000..dce6e906ce92e7e303d2198d7a612905ca0632c1 --- /dev/null +++ b/ide-fix-leak-from-qemu_allocate_irqs.patch @@ -0,0 +1,28 @@ +From df35f8fe2687df32cb65f6a03b8dd80314cc4c53 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 15:00:08 +0800 +Subject: [PATCH] ide: fix leak from qemu_allocate_irqs + +The array returned by qemu_allocate_irqs is malloced, free it. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Thomas Huth +--- + hw/ide/cmd646.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c +index ed23aabf..a149cd6c 100644 +--- a/hw/ide/cmd646.c ++++ b/hw/ide/cmd646.c +@@ -299,6 +299,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) + d->bmdma[i].bus = &d->bus[i]; + ide_register_restart_cb(&d->bus[i]); + } ++ g_free(irq); + + vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); + qemu_register_reset(cmd646_reset, d); +-- +2.19.1 + diff --git a/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch b/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d0c6abf3d233a0694cec23a2097011c39d4fd1f --- /dev/null +++ b/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch @@ -0,0 +1,34 @@ +From 7b4aded3f772ef43e2b600594f755eadd5da5958 Mon Sep 17 00:00:00 2001 +From: Jonathan Marler +Date: Sat, 2 May 2020 10:12:25 -0600 +Subject: [PATCH 3/5] linux-user/mmap.c: fix integer underflow in target_mremap + +Fixes: https://bugs.launchpad.net/bugs/1876373 + +This code path in mmap occurs when a page size is decreased with mremap. When a section of pages is shrunk, qemu calls mmap_reserve on the pages that were released. However, it has the diff operation reversed, subtracting the larger old_size from the smaller new_size. Instead, it should be subtracting the smaller new_size from the larger old_size. You can also see in the previous line of the change that this mmap_reserve call only occurs when old_size > new_size. + +Bug: https://bugs.launchpad.net/qemu/+bug/1876373 +Signed-off-by: Jonathan Marler +Reviewded-by: Laurent Vivier +Message-Id: <20200502161225.14346-1-johnnymarler@gmail.com> +Signed-off-by: Laurent Vivier +--- + linux-user/mmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/linux-user/mmap.c b/linux-user/mmap.c +index 46a6e3a7..2a9ca0c3 100644 +--- a/linux-user/mmap.c ++++ b/linux-user/mmap.c +@@ -740,7 +740,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, + if (prot == 0) { + host_addr = mremap(g2h(old_addr), old_size, new_size, flags); + if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) { +- mmap_reserve(old_addr + old_size, new_size - old_size); ++ mmap_reserve(old_addr + old_size, old_size - new_size); + } + } else { + errno = ENOMEM; +-- +2.23.0 + diff --git a/lm32-do-not-leak-memory-on-object_new-object_unref.patch b/lm32-do-not-leak-memory-on-object_new-object_unref.patch new file mode 100644 index 0000000000000000000000000000000000000000..7ccc53684bb3d3224757209a4c1710883214fcc8 --- /dev/null +++ b/lm32-do-not-leak-memory-on-object_new-object_unref.patch @@ -0,0 +1,77 @@ +From d50be5295c49be1b6024f5902948b52e683b4c23 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:18:35 +0800 +Subject: [PATCH] lm32: do not leak memory on object_new/object_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bottom halves and ptimers are malloced, but nothing in these +files is freeing memory allocated by instance_init. Since +these are sysctl devices that are never unrealized, just moving +the allocations to realize is enough to avoid the leak in +practice (and also to avoid upsetting asan when running +device-introspect-test). + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/timer/lm32_timer.c | 6 +++--- + hw/timer/milkymist-sysctl.c | 10 +++++----- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c +index 6ce876c6..13f15825 100644 +--- a/hw/timer/lm32_timer.c ++++ b/hw/timer/lm32_timer.c +@@ -184,9 +184,6 @@ static void lm32_timer_init(Object *obj) + + sysbus_init_irq(dev, &s->irq); + +- s->bh = qemu_bh_new(timer_hit, s); +- s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); +- + memory_region_init_io(&s->iomem, obj, &timer_ops, s, + "timer", R_MAX * 4); + sysbus_init_mmio(dev, &s->iomem); +@@ -196,6 +193,9 @@ static void lm32_timer_realize(DeviceState *dev, Error **errp) + { + LM32TimerState *s = LM32_TIMER(dev); + ++ s->bh = qemu_bh_new(timer_hit, s); ++ s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); ++ + ptimer_set_freq(s->ptimer, s->freq_hz); + } + +diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c +index a9d25087..2f1ecc6d 100644 +--- a/hw/timer/milkymist-sysctl.c ++++ b/hw/timer/milkymist-sysctl.c +@@ -280,11 +280,6 @@ static void milkymist_sysctl_init(Object *obj) + sysbus_init_irq(dev, &s->timer0_irq); + sysbus_init_irq(dev, &s->timer1_irq); + +- s->bh0 = qemu_bh_new(timer0_hit, s); +- s->bh1 = qemu_bh_new(timer1_hit, s); +- s->ptimer0 = ptimer_init(s->bh0, PTIMER_POLICY_DEFAULT); +- s->ptimer1 = ptimer_init(s->bh1, PTIMER_POLICY_DEFAULT); +- + memory_region_init_io(&s->regs_region, obj, &sysctl_mmio_ops, s, + "milkymist-sysctl", R_MAX * 4); + sysbus_init_mmio(dev, &s->regs_region); +@@ -294,6 +289,11 @@ static void milkymist_sysctl_realize(DeviceState *dev, Error **errp) + { + MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev); + ++ s->bh0 = qemu_bh_new(timer0_hit, s); ++ s->bh1 = qemu_bh_new(timer1_hit, s); ++ s->ptimer0 = ptimer_init(s->bh0, PTIMER_POLICY_DEFAULT); ++ s->ptimer1 = ptimer_init(s->bh1, PTIMER_POLICY_DEFAULT); ++ + ptimer_set_freq(s->ptimer0, s->freq_hz); + ptimer_set_freq(s->ptimer1, s->freq_hz); + } +-- +2.19.1 + diff --git a/make-check-unit-use-after-free-in-test-opts-visitor.patch b/make-check-unit-use-after-free-in-test-opts-visitor.patch new file mode 100644 index 0000000000000000000000000000000000000000..590970004769b464b68977639a0e5e823bb9b9ac --- /dev/null +++ b/make-check-unit-use-after-free-in-test-opts-visitor.patch @@ -0,0 +1,102 @@ +From e3dfb5d2848975e9e947cb894afac87ce386a2bc Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 15:18:52 +0800 +Subject: [PATCH] make check-unit: use after free in test-opts-visitor + +In the struct OptsVisitor, the 'repeated_opts' member points to a list +in the 'unprocessed_opts' hash table after the list has been destroyed. +A subsequent call to visit_type_int() references the deleted list. +It results in use-after-free issue reproduced by running the test case +under the Valgrind: valgrind tests/test-opts-visitor. +A new mode ListMode::LM_TRAVERSED is declared to mark the list +traversal completed. + +Suggested-by: Markus Armbruster +Signed-off-by: Andrey Shinkevich +Message-Id: <1565024586-387112-1-git-send-email-andrey.shinkevich@virtuozzo.com> +--- + qapi/opts-visitor.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c +index 324b1974..42d87df6 100644 +--- a/qapi/opts-visitor.c ++++ b/qapi/opts-visitor.c +@@ -24,7 +24,8 @@ enum ListMode + { + LM_NONE, /* not traversing a list of repeated options */ + +- LM_IN_PROGRESS, /* opts_next_list() ready to be called. ++ LM_IN_PROGRESS, /* ++ * opts_next_list() ready to be called. + * + * Generating the next list link will consume the most + * recently parsed QemuOpt instance of the repeated +@@ -36,7 +37,8 @@ enum ListMode + * LM_UNSIGNED_INTERVAL. + */ + +- LM_SIGNED_INTERVAL, /* opts_next_list() has been called. ++ LM_SIGNED_INTERVAL, /* ++ * opts_next_list() has been called. + * + * Generating the next list link will consume the most + * recently stored element from the signed interval, +@@ -48,7 +50,14 @@ enum ListMode + * next element of the signed interval. + */ + +- LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */ ++ LM_UNSIGNED_INTERVAL, /* Same as above, only for an unsigned interval. */ ++ ++ LM_TRAVERSED /* ++ * opts_next_list() has been called. ++ * ++ * No more QemuOpt instance in the list. ++ * The traversal has been completed. ++ */ + }; + + typedef enum ListMode ListMode; +@@ -238,6 +247,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size) + OptsVisitor *ov = to_ov(v); + + switch (ov->list_mode) { ++ case LM_TRAVERSED: ++ return NULL; + case LM_SIGNED_INTERVAL: + case LM_UNSIGNED_INTERVAL: + if (ov->list_mode == LM_SIGNED_INTERVAL) { +@@ -258,6 +269,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size) + opt = g_queue_pop_head(ov->repeated_opts); + if (g_queue_is_empty(ov->repeated_opts)) { + g_hash_table_remove(ov->unprocessed_opts, opt->name); ++ ov->repeated_opts = NULL; ++ ov->list_mode = LM_TRAVERSED; + return NULL; + } + break; +@@ -289,7 +302,8 @@ opts_end_list(Visitor *v, void **obj) + + assert(ov->list_mode == LM_IN_PROGRESS || + ov->list_mode == LM_SIGNED_INTERVAL || +- ov->list_mode == LM_UNSIGNED_INTERVAL); ++ ov->list_mode == LM_UNSIGNED_INTERVAL || ++ ov->list_mode == LM_TRAVERSED); + ov->repeated_opts = NULL; + ov->list_mode = LM_NONE; + } +@@ -306,6 +320,10 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp) + list = lookup_distinct(ov, name, errp); + return list ? g_queue_peek_tail(list) : NULL; + } ++ if (ov->list_mode == LM_TRAVERSED) { ++ error_setg(errp, "Fewer list elements than expected"); ++ return NULL; ++ } + assert(ov->list_mode == LM_IN_PROGRESS); + return g_queue_peek_head(ov->repeated_opts); + } +-- +2.19.1 + diff --git a/mcf5208-fix-leak-from-qemu_allocate_irqs.patch b/mcf5208-fix-leak-from-qemu_allocate_irqs.patch new file mode 100644 index 0000000000000000000000000000000000000000..7e254f577e4f08bc332bb94dda769ce9a584c623 --- /dev/null +++ b/mcf5208-fix-leak-from-qemu_allocate_irqs.patch @@ -0,0 +1,29 @@ +From 07b7cdb648124748c34be299fbfdfe3b6e38a521 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:53:00 +0800 +Subject: [PATCH] mcf5208: fix leak from qemu_allocate_irqs + +The array returned by qemu_allocate_irqs is malloced, free it. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Thomas Huth +--- + hw/m68k/mcf5208.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c +index 6f6efae9..cc765eac 100644 +--- a/hw/m68k/mcf5208.c ++++ b/hw/m68k/mcf5208.c +@@ -270,6 +270,8 @@ static void mcf5208evb_init(MachineState *machine) + 0xfc030000, pic + 36); + } + ++ g_free(pic); ++ + /* 0xfc000000 SCM. */ + /* 0xfc004000 XBS. */ + /* 0xfc008000 FlexBus CS. */ +-- +2.19.1 + diff --git a/microblaze-fix-leak-of-fdevice-tree-blob.patch b/microblaze-fix-leak-of-fdevice-tree-blob.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd845e80cef5f3315e44417f3b7eeaa60ce6b8bb --- /dev/null +++ b/microblaze-fix-leak-of-fdevice-tree-blob.patch @@ -0,0 +1,32 @@ +From 2ff9c28e2b72cd359a0c4e931412e355baee8e1e Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:55:11 +0800 +Subject: [PATCH] microblaze: fix leak of fdevice tree blob +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The device tree blob returned by load_device_tree is malloced. +Free it before returning. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/microblaze/boot.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c +index a7af4c07..0fcc4e9d 100644 +--- a/hw/microblaze/boot.c ++++ b/hw/microblaze/boot.c +@@ -99,6 +99,7 @@ static int microblaze_load_dtb(hwaddr addr, + } + + cpu_physical_memory_write(addr, fdt, fdt_size); ++ g_free(fdt); + return fdt_size; + } + +-- +2.19.1 + diff --git a/migration-Count-new_dirty-instead-of-real_dirty.patch b/migration-Count-new_dirty-instead-of-real_dirty.patch new file mode 100644 index 0000000000000000000000000000000000000000..a9ff297ffac9fb42ce63ef8a256e648adf1166dd --- /dev/null +++ b/migration-Count-new_dirty-instead-of-real_dirty.patch @@ -0,0 +1,74 @@ +From 63320ae36834e4ff2f0d139f205c464caa3887b4 Mon Sep 17 00:00:00 2001 +From: Keqian Zhu +Date: Mon, 22 Jun 2020 11:20:37 +0800 +Subject: [PATCH 04/11] migration: Count new_dirty instead of real_dirty + +real_dirty_pages becomes equal to total ram size after dirty log sync +in ram_init_bitmaps, the reason is that the bitmap of ramblock is +initialized to be all set, so old path counts them as "real dirty" at +beginning. + +This causes wrong dirty rate and false positive throttling. + +Signed-off-by: Keqian Zhu +Message-Id: <20200622032037.31112-1-zhukeqian1@huawei.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: BiaoXiang Ye +--- + include/exec/ram_addr.h | 5 +---- + migration/ram.c | 8 +++++--- + 2 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h +index b7b2e60f..52344066 100644 +--- a/include/exec/ram_addr.h ++++ b/include/exec/ram_addr.h +@@ -485,8 +485,7 @@ static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, + static inline + uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + ram_addr_t start, +- ram_addr_t length, +- uint64_t *real_dirty_pages) ++ ram_addr_t length) + { + ram_addr_t addr; + unsigned long word = BIT_WORD((start + rb->offset) >> TARGET_PAGE_BITS); +@@ -512,7 +511,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + if (src[idx][offset]) { + unsigned long bits = atomic_xchg(&src[idx][offset], 0); + unsigned long new_dirty; +- *real_dirty_pages += ctpopl(bits); + new_dirty = ~dest[k]; + dest[k] |= bits; + new_dirty &= bits; +@@ -545,7 +543,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + start + addr + offset, + TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION)) { +- *real_dirty_pages += 1; + long k = (start + addr) >> TARGET_PAGE_BITS; + if (!test_and_set_bit(k, dest)) { + num_dirty++; +diff --git a/migration/ram.c b/migration/ram.c +index 840e3548..83cabec6 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1765,9 +1765,11 @@ static inline bool migration_bitmap_clear_dirty(RAMState *rs, + static void migration_bitmap_sync_range(RAMState *rs, RAMBlock *rb, + ram_addr_t length) + { +- rs->migration_dirty_pages += +- cpu_physical_memory_sync_dirty_bitmap(rb, 0, length, +- &rs->num_dirty_pages_period); ++ uint64_t new_dirty_pages = ++ cpu_physical_memory_sync_dirty_bitmap(rb, 0, rb->used_length); ++ ++ rs->migration_dirty_pages += new_dirty_pages; ++ rs->num_dirty_pages_period += new_dirty_pages; + } + + /** +-- +2.27.0.dirty + diff --git a/migration-colo-fix-use-after-free-of-local_err.patch b/migration-colo-fix-use-after-free-of-local_err.patch new file mode 100644 index 0000000000000000000000000000000000000000..c03ceb5120bc3069ac123cc9c2702653c4d2da17 --- /dev/null +++ b/migration-colo-fix-use-after-free-of-local_err.patch @@ -0,0 +1,33 @@ +From 663e9b5f25d22834260a0686f77a27c957cd7b2f Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:28 +0300 +Subject: [PATCH 07/14] migration/colo: fix use after free of local_err + +local_err is used again in secondary_vm_do_failover() after +replication_stop_all(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-5-vsementsov@virtuozzo.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + migration/colo.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/migration/colo.c b/migration/colo.c +index 9f84b1fa3c0f..761b3544d472 100644 +--- a/migration/colo.c ++++ b/migration/colo.c +@@ -89,6 +89,7 @@ static void secondary_vm_do_failover(void) + replication_stop_all(true, &local_err); + if (local_err) { + error_report_err(local_err); ++ local_err = NULL; + } + + /* Notify all filters of all NIC to do checkpoint */ +-- +2.26.2 + diff --git a/migration-fix-cleanup_bh-leak-on-resume.patch b/migration-fix-cleanup_bh-leak-on-resume.patch new file mode 100644 index 0000000000000000000000000000000000000000..6b75ed01b8faa4c3d5b9d1e17e6d3d205daa2396 --- /dev/null +++ b/migration-fix-cleanup_bh-leak-on-resume.patch @@ -0,0 +1,64 @@ +From 1d7c227bbb24665cea03f96a984ad6be223ac40c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 25 Mar 2020 19:47:21 +0100 +Subject: [PATCH 2/5] migration: fix cleanup_bh leak on resume +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since commit 8c6b0356b53977bcfdea5299db07884915425b0c ("util/async: +make bh_aio_poll() O(1)"), migration-test reveals a leak: + +QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 +tests/qtest/migration-test -p /x86_64/migration/postcopy/recovery +tests/qtest/libqtest.c:140: kill_qemu() tried to terminate QEMU +process but encountered exit status 1 (expected 0) + +================================================================= +==2082571==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 40 byte(s) in 1 object(s) allocated from: + #0 0x7f25971dfc58 in __interceptor_malloc (/lib64/libasan.so.5+0x10dc58) + #1 0x7f2596d08358 in g_malloc (/lib64/libglib-2.0.so.0+0x57358) + #2 0x560970d006f8 in qemu_bh_new /home/elmarco/src/qemu/util/main-loop.c:532 + #3 0x5609704afa02 in migrate_fd_connect +/home/elmarco/src/qemu/migration/migration.c:3407 + #4 0x5609704b6b6f in migration_channel_connect +/home/elmarco/src/qemu/migration/channel.c:92 + #5 0x5609704b2bfb in socket_outgoing_migration +/home/elmarco/src/qemu/migration/socket.c:108 + #6 0x560970b9bd6c in qio_task_complete /home/elmarco/src/qemu/io/task.c:196 + #7 0x560970b9aa97 in qio_task_thread_result +/home/elmarco/src/qemu/io/task.c:111 + #8 0x7f2596cfee3a (/lib64/libglib-2.0.so.0+0x4de3a) + +Signed-off-by: Marc-André Lureau +Message-Id: <20200325184723.2029630-2-marcandre.lureau@redhat.com> +Reviewed-by: Juan Quintela +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + migration/migration.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 8f2fc2b4..7949f2a4 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -3313,7 +3313,12 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED; + + s->expected_downtime = s->parameters.downtime_limit; +- s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); ++ if (resume) { ++ assert(s->cleanup_bh); ++ } else { ++ assert(!s->cleanup_bh); ++ s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); ++ } + if (error_in) { + migrate_fd_error(s, error_in); + migrate_fd_cleanup(s); +-- +2.22.0.windows.1 + diff --git a/migration-fix-multifd_send_pages-next-channel.patch b/migration-fix-multifd_send_pages-next-channel.patch new file mode 100644 index 0000000000000000000000000000000000000000..4bb113c644c4175386636e02a5d7188e8c2e408c --- /dev/null +++ b/migration-fix-multifd_send_pages-next-channel.patch @@ -0,0 +1,50 @@ +From c11a23b92334ae86eddfdc2b155d404293891985 Mon Sep 17 00:00:00 2001 +From: alexchen +Date: Tue, 8 Sep 2020 11:18:50 +0000 +Subject: [PATCH 08/11] migration: fix multifd_send_pages() next channel + +multifd_send_pages() loops around the available channels, +the next channel to use between two calls to multifd_send_pages() is stored +inside a local static variable, next_channel. + +It works well, except if the number of channels decreases between two calls +to multifd_send_pages(). In this case, the loop can try to access the +data of a channel that doesn't exist anymore. + +The problem can be triggered if we start a migration with a given number of +channels and then we cancel the migration to restart it with a lower number. +This ends generally with an error like: +qemu-system-ppc64: .../util/qemu-thread-posix.c:77: qemu_mutex_lock_impl: Assertion `mutex->initialized' failed. + +This patch fixes the error by capping next_channel with the current number +of channels before using it. + +Signed-off-by: Laurent Vivier +Message-Id: <20200617113154.593233-1-lvivier@redhat.com> +Reviewed-by: Juan Quintela +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: BiaoXiang Ye +--- + migration/ram.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 83cabec6..ac033f22 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -931,6 +931,12 @@ static int multifd_send_pages(RAMState *rs) + uint64_t transferred; + + qemu_sem_wait(&multifd_send_state->channels_ready); ++ /* ++ * next_channel can remain from a previous migration that was ++ * using more channels, so ensure it doesn't overflow if the ++ * limit is lower now. ++ */ ++ next_channel %= migrate_multifd_channels(); + for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) { + p = &multifd_send_state->params[i]; + +-- +2.27.0.dirty + diff --git a/migration-ram-fix-use-after-free-of-local_err.patch b/migration-ram-fix-use-after-free-of-local_err.patch new file mode 100644 index 0000000000000000000000000000000000000000..f74e3b18df98ae0e5a88ff9224fa06c8ea24197a --- /dev/null +++ b/migration-ram-fix-use-after-free-of-local_err.patch @@ -0,0 +1,33 @@ +From 019526f7f7b42a7d1b8a74e1db6a8050adf9e1fb Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:29 +0300 +Subject: [PATCH 08/14] migration/ram: fix use after free of local_err + +local_err is used again in migration_bitmap_sync_precopy() after +precopy_notify(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-6-vsementsov@virtuozzo.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + migration/ram.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 840e35480b04..5d1ae7570018 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1912,6 +1912,7 @@ static void migration_bitmap_sync_precopy(RAMState *rs) + */ + if (precopy_notify(PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC, &local_err)) { + error_report_err(local_err); ++ local_err = NULL; + } + + migration_bitmap_sync(rs); +-- +2.26.2 + diff --git a/migration-rdma-cleanup-rdma-context-before-g_free-to.patch b/migration-rdma-cleanup-rdma-context-before-g_free-to.patch new file mode 100644 index 0000000000000000000000000000000000000000..a39894ada540a713645b0735b719eb4d5a3edbff --- /dev/null +++ b/migration-rdma-cleanup-rdma-context-before-g_free-to.patch @@ -0,0 +1,58 @@ +From 9867dc6fc3f131324b73664b9617376270d8d013 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Fri, 8 May 2020 06:07:55 -0400 +Subject: [PATCH 4/5] migration/rdma: cleanup rdma context before g_free to + avoid memleaks + +When error happen in initializing 'rdma_return_path', we should cleanup rdma context +before g_free(rdma) to avoid some memleaks. This patch fix that. + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Message-Id: <20200508100755.7875-3-pannengyuan@huawei.com> +Reviewed-by: Juan Quintela +Signed-off-by: Dr. David Alan Gilbert +--- + migration/rdma.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/migration/rdma.c b/migration/rdma.c +index 3036221e..bb24dac5 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -4103,20 +4103,20 @@ void rdma_start_outgoing_migration(void *opaque, + rdma_return_path = qemu_rdma_data_init(host_port, errp); + + if (rdma_return_path == NULL) { +- goto err; ++ goto return_path_err; + } + + ret = qemu_rdma_source_init(rdma_return_path, + s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); + + if (ret) { +- goto err; ++ goto return_path_err; + } + + ret = qemu_rdma_connect(rdma_return_path, errp); + + if (ret) { +- goto err; ++ goto return_path_err; + } + + rdma->return_path = rdma_return_path; +@@ -4129,6 +4129,8 @@ void rdma_start_outgoing_migration(void *opaque, + s->to_dst_file = qemu_fopen_rdma(rdma, "wb"); + migrate_fd_connect(s, NULL); + return; ++return_path_err: ++ qemu_rdma_cleanup(rdma); + err: + g_free(rdma); + g_free(rdma_return_path); +-- +2.23.0 + diff --git a/object-return-self-in-object_ref.patch b/object-return-self-in-object_ref.patch new file mode 100644 index 0000000000000000000000000000000000000000..e851fb30d20a4c56b65bb7ce1c6ddb9109c643aa --- /dev/null +++ b/object-return-self-in-object_ref.patch @@ -0,0 +1,58 @@ +From b77ade9bb37b2e9813a42008cb21d0c743aa50a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 10 Jan 2020 19:30:31 +0400 +Subject: [PATCH] object: return self in object_ref() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allow for simpler assignment with ref: foo = object_ref(bar) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20200110153039.1379601-19-marcandre.lureau@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + include/qom/object.h | 3 ++- + qom/object.c | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/include/qom/object.h b/include/qom/object.h +index 5e2f60d4b0..18660fde1c 100644 +--- a/include/qom/object.h ++++ b/include/qom/object.h +@@ -1005,8 +1005,9 @@ GSList *object_class_get_list_sorted(const char *implements_type, + * + * Increase the reference count of a object. A object cannot be freed as long + * as its reference count is greater than zero. ++ * Returns: @obj + */ +-void object_ref(Object *obj); ++Object *object_ref(Object *obj); + + /** + * object_unref: +diff --git a/qom/object.c b/qom/object.c +index 66c4a5f1cb..555c8b9d07 100644 +--- a/qom/object.c ++++ b/qom/object.c +@@ -1107,12 +1107,13 @@ GSList *object_class_get_list_sorted(const char *implements_type, + object_class_cmp); + } + +-void object_ref(Object *obj) ++Object *object_ref(Object *obj) + { + if (!obj) { +- return; ++ return NULL; + } + atomic_inc(&obj->ref); ++ return obj; + } + + void object_unref(Object *obj) +-- +2.22.0.windows.1 + diff --git a/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch b/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e29f08d69c56a2907892008c9c4ce177778c097 --- /dev/null +++ b/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch @@ -0,0 +1,34 @@ +From d2bb5b4c4ed3b1dbc0096deb195b6df33f813f23 Mon Sep 17 00:00:00 2001 +From: Yifan Luo +Date: Wed, 14 Aug 2019 14:14:26 +0800 +Subject: [PATCH 5/5] pc-bios/s390-ccw/net: fix a possible memory leak in + get_uuid() + +There is a possible memory leak in get_uuid(). Should free allocated mem +before +return NULL. + +Signed-off-by: Yifan Luo +Message-Id: <02cf01d55267$86cf2850$946d78f0$@cmss.chinamobile.com> +Reviewed-by: Thomas Huth +Reviewed-by: Cornelia Huck +Signed-off-by: Thomas Huth +--- + pc-bios/s390-ccw/netmain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index f3542cb2..f2dcc01e 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -269,6 +269,7 @@ static const char *get_uuid(void) + : "d" (r0), "d" (r1), [addr] "a" (buf) + : "cc", "memory"); + if (cc) { ++ free(mem); + return NULL; + } + +-- +2.23.0 + diff --git a/qemu-img-free-memory-before-re-assign.patch b/qemu-img-free-memory-before-re-assign.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d46d64b1b9664b66efc76ea6490a1bc22663137 --- /dev/null +++ b/qemu-img-free-memory-before-re-assign.patch @@ -0,0 +1,33 @@ +From d22af5cb41c16829dbf3ed3c611ef56ceeb840ff Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Thu, 27 Feb 2020 09:29:50 +0800 +Subject: [PATCH 02/14] qemu-img: free memory before re-assign + +collect_image_check() is called twice in img_check(), the filename/format will be alloced without free the original memory. +It is not a big deal since the process will exit anyway, but seems like a clean code and it will remove the warning spotted by asan. + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Message-Id: <20200227012950.12256-3-pannengyuan@huawei.com> +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + qemu-img.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/qemu-img.c b/qemu-img.c +index 79983772de39..2e9cc5db7c4c 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -808,6 +808,8 @@ static int img_check(int argc, char **argv) + check->corruptions_fixed); + } + ++ qapi_free_ImageCheck(check); ++ check = g_new0(ImageCheck, 1); + ret = collect_image_check(bs, check, filename, fmt, 0); + + check->leaks_fixed = leaks_fixed; +-- +2.26.2 + diff --git a/qemu.spec b/qemu.spec index 74162a1452e2384333f19e7b15cdd56a6b783efa..5e8ad573515027fc8245e863da31a4885d901ca3 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 23 +Release: 19 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY @@ -175,59 +175,16 @@ Patch0162: migration-Compat-virtual-timer-adjust-for-v4.0.1-and.patch Patch0163: vtimer-Drop-vtimer-virtual-timer-adjust.patch Patch0164: target-arm-Add-the-kvm_adjvtime-vcpu-property-for-Co.patch Patch0165: target-arm-Fix-PAuth-sbox-functions.patch -Patch0166: tests-Disalbe-filemonitor-testcase.patch -Patch0167: es1370-check-total-frame-count-against-current-frame.patch -Patch0168: exec-set-map-length-to-zero-when-returning-NULL.patch -Patch0169: ati-vga-check-mm_index-before-recursive-call-CVE-202.patch -Patch0170: megasas-use-unsigned-type-for-reply_queue_head-and-c.patch -Patch0171: megasas-avoid-NULL-pointer-dereference.patch -Patch0172: megasas-use-unsigned-type-for-positive-numeric-field.patch -Patch0173: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch -Patch0174: hw-arm-acpi-enable-SHPC-native-hot-plug.patch -Patch0175: hw-tpm-rename-Error-parameter-to-more-common-errp.patch -Patch0176: tpm-ppi-page-align-PPI-RAM.patch -Patch0177: tpm-Move-tpm_tis_show_buffer-to-tpm_util.c.patch -Patch0178: spapr-Implement-get_dt_compatible-callback.patch -Patch0179: delete-the-in-tpm.txt.patch -Patch0180: tpm_spapr-Support-TPM-for-ppc64-using-CRQ-based-inte.patch -Patch0181: tpm_spapr-Support-suspend-and-resume.patch -Patch0182: hw-ppc-Kconfig-Enable-TPM_SPAPR-as-part-of-PSERIES-c.patch -Patch0183: docs-specs-tpm-reST-ify-TPM-documentation.patch -Patch0184: tpm-rename-TPM_TIS-into-TPM_TIS_ISA.patch -Patch0185: tpm-Use-TPMState-as-a-common-struct.patch -Patch0186: tpm-Separate-tpm_tis-common-functions-from-isa-code.patch -Patch0187: tpm-Separate-TPM_TIS-and-TPM_TIS_ISA-configs.patch -Patch0188: tpm-Add-the-SysBus-TPM-TIS-device.patch -Patch0189: hw-arm-virt-vTPM-support.patch -Patch0190: docs-specs-tpm-Document-TPM_TIS-sysbus-device-for-AR.patch -Patch0191: test-tpm-pass-optional-machine-options-to-swtpm-test.patch -Patch0192: test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch -Patch0193: test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch -Patch0194: build-smt-processor-structure-to-support-smt-topolog.patch -Patch0195: target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch -Patch0196: target-arm-Add-ID_AA64MMFR2_EL1.patch -Patch0197: target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch -Patch0198: target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch -Patch0199: target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch -Patch0200: target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch -Patch0201: target-arm-Stop-assuming-DBGDIDR-always-exists.patch -Patch0202: target-arm-Move-DBGDIDR-into-ARMISARegisters.patch -Patch0203: target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch -Patch0204: target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch -Patch0205: target-arm-Read-debug-related-ID-registers-from-KVM.patch -Patch0206: target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch -Patch0207: target-arm-monitor-query-cpu-model-expansion-crashed.patch -Patch0208: target-arm-convert-isar-regs-to-array.patch -Patch0209: target-arm-parse-cpu-feature-related-options.patch -Patch0210: target-arm-register-CPU-features-for-property.patch -Patch0211: target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch -Patch0212: target-arm-introduce-CPU-feature-dependency-mechanis.patch -Patch0213: target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch -Patch0214: target-arm-Add-CPU-features-to-query-cpu-model-expan.patch -Patch0215: target-arm-Update-ID-fields.patch -Patch0216: target-arm-Add-more-CPU-features.patch -Patch0217: hw-usb-core-fix-buffer-overflow.patch -Patch0218: target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch +Patch0166: es1370-check-total-frame-count-against-current-frame.patch +Patch0167: exec-set-map-length-to-zero-when-returning-NULL.patch +Patch0168: ati-vga-check-mm_index-before-recursive-call-CVE-202.patch +Patch0169: megasas-use-unsigned-type-for-reply_queue_head-and-c.patch +Patch0170: megasas-avoid-NULL-pointer-dereference.patch +Patch0171: megasas-use-unsigned-type-for-positive-numeric-field.patch +Patch0172: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch +Patch0173: hw-arm-acpi-enable-SHPC-native-hot-plug.patch +PATCH0174: hw-usb-core-fix-buffer-overflow.patch +Patch0173: slirp-networking-fix-out-of-bounds-read-information.patch BuildRequires: flex BuildRequires: bison @@ -574,48 +531,16 @@ getent passwd qemu >/dev/null || \ %endif %changelog -* Tue Sep 08 2020 Huawei Technologies Co., Ltd -- target/arm: ignore evtstrm and cpuid CPU features +* Thu Sep 10 2020 Huawei Technologies Co., LTD +- slirp/src/ip6_input.c: fix out-of-bounds read information -* Fri Aug 21 2020 Huawei Technologies Co., Ltd +* Thu Aug 27 2020 Huawei Technologies Co., Ltd - hw/usb/core.c: fix buffer overflow in do_token_setup function -* Wed Aug 19 2020 Huawei Technologies Co., Ltd -- target-arm-convert-isar-regs-to-array.patch -- target-arm-parse-cpu-feature-related-options.patch -- target-arm-register-CPU-features-for-property.patch -- target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch -- target-arm-introduce-CPU-feature-dependency-mechanis.patch -- target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch -- target-arm-Add-CPU-features-to-query-cpu-model-expan.patch -- target-arm-Update-ID-fields.patch -- target-arm-Add-more-CPU-features.patch - -* Wed Aug 19 2020 Huawei Technologies Co., Ltd -- target-arm-Add-isar_feature-tests-for-PAN-ATS1E1.patch -- target-arm-Add-ID_AA64MMFR2_EL1.patch -- target-arm-Add-and-use-FIELD-definitions-for-ID_AA64.patch -- target-arm-Use-FIELD-macros-for-clearing-ID_DFR0-PER.patch -- target-arm-Define-an-aa32_pmu_8_1-isar-feature-test-.patch -- target-arm-Add-_aa64_-and-_any_-versions-of-pmu_8_1-.patch -- target-arm-Stop-assuming-DBGDIDR-always-exists.patch -- target-arm-Move-DBGDIDR-into-ARMISARegisters.patch -- target-arm-Enable-ARMv8.2-ATS1E1-in-cpu-max.patch -- target-arm-Test-correct-register-in-aa32_pan-and-aa3.patch -- target-arm-Read-debug-related-ID-registers-from-KVM.patch -- target-arm-monitor-Introduce-qmp_query_cpu_model_exp.patch -- target-arm-monitor-query-cpu-model-expansion-crashed.patch - -* Tue Aug 18 2020 Huawei Technologies Co., Ltd -- hw/acpi/aml-build.c: build smt processor structure to support smt topology - -* Thu Aug 13 2020 Huawei Technologies Co., Ltd --target/arm: Aarch64 support vtpm - * Wed Aug 12 2020 Huawei Technologies Co., Ltd - backport upstream patch to support SHPCHotplug in arm -* Thu Aug 6 2020 Huawei Technologies Co., Ltd +* Fri Jul 24 2020 Huawei Technologies Co., Ltd - es1370: check total frame count against current frame - exec: set map length to zero when returning NULL - ati-vga: check mm_index before recursive call (CVE-2020-13800) @@ -624,9 +549,6 @@ getent passwd qemu >/dev/null || \ - megasas: use unsigned type for positive numeric fields - hw/scsi/megasas: Fix possible out-of-bounds array access in tracepoints -* Thu Aug 6 2020 Huawei Technologies Co., Ltd -- tests: Disalbe filemonitor testcase - * Sat Jun 20 2020 Huawei Technologies Co., Ltd - target/arm: Fix PAuth sbox functions - fix two patches' format which can cause git am failed diff --git a/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch b/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch new file mode 100644 index 0000000000000000000000000000000000000000..a901a500181bb9a36f9bd307d8bdee5929b6144f --- /dev/null +++ b/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch @@ -0,0 +1,40 @@ +From 1580682eafb489eaf417456778267662629cf696 Mon Sep 17 00:00:00 2001 +From: Markus Armbruster +Date: Tue, 30 Jun 2020 11:03:33 +0200 +Subject: [PATCH 05/11] qga: Plug unlikely memory leak in + guest-set-memory-blocks + +transfer_memory_block() leaks an Error object when reading file +/sys/devices/system/memory/memory/state fails with errno other +than ENOENT, and @sys2memblk is false, i.e. when the state file exists +but cannot be read (seems quite unlikely), and this is +guest-set-memory-blocks, not guest-get-memory-blocks. + +Plug the leak. + +Fixes: bd240fca42d5f072fb758a71720d9de9990ac553 +Cc: Michael Roth +Cc: Hailiang Zhang +Signed-off-by: Markus Armbruster +Reviewed-by: zhanghailiang +Message-Id: <20200630090351.1247703-9-armbru@redhat.com> +Signed-off-by: BiaoXiang Ye +--- + qga/commands-posix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index dfc05f5b..c318cee7 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -2420,6 +2420,7 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk, + if (sys2memblk) { + error_propagate(errp, local_err); + } else { ++ error_free(local_err); + result->response = + GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED; + } +-- +2.27.0.dirty + diff --git a/qga-commands-posix-fix-use-after-free-of-local_err.patch b/qga-commands-posix-fix-use-after-free-of-local_err.patch new file mode 100644 index 0000000000000000000000000000000000000000..9628d0c59445c9d29ddaa39e6fb271fe73a5c274 --- /dev/null +++ b/qga-commands-posix-fix-use-after-free-of-local_err.patch @@ -0,0 +1,49 @@ +From 15847279f29b0bd67b95daefff395cab8fad80d3 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:30 +0300 +Subject: [PATCH 4/5] qga/commands-posix: fix use after free of local_err + +local_err is used several times in guest_suspend(). Setting non-NULL +local_err will crash, so let's zero it after freeing. Also fix possible +leak of local_err in final if(). + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-7-vsementsov@virtuozzo.com> +Reviewed-by: Richard Henderson +Signed-off-by: Markus Armbruster +Signed-off-by: Zhenyu Ye +--- + qga/commands-posix.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index dfc05f5b..66164e6c 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -1760,6 +1760,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + error_free(local_err); ++ local_err = NULL; + + if (pmutils_supports_mode(mode, &local_err)) { + mode_supported = true; +@@ -1771,6 +1772,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + error_free(local_err); ++ local_err = NULL; + + if (linux_sys_state_supports_mode(mode, &local_err)) { + mode_supported = true; +@@ -1778,6 +1780,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + if (!mode_supported) { ++ error_free(local_err); + error_setg(errp, + "the requested suspend mode is not supported by the guest"); + } else { +-- +2.22.0.windows.1 + diff --git a/qga-fix-assert-regression-on-guest-shutdown.patch b/qga-fix-assert-regression-on-guest-shutdown.patch new file mode 100644 index 0000000000000000000000000000000000000000..c5f1e1069b5097ff1adf2328bea6a25e9483cda1 --- /dev/null +++ b/qga-fix-assert-regression-on-guest-shutdown.patch @@ -0,0 +1,47 @@ +From aeccff89333c565c7a894f99c17c0044d7d43be2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 4 Jun 2020 11:44:25 +0200 +Subject: [PATCH 02/11] qga: fix assert regression on guest-shutdown +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since commit 781f2b3d1e ("qga: process_event() simplification"), +send_response() is called unconditionally, but will assert when "rsp" is +NULL. This may happen with QCO_NO_SUCCESS_RESP commands, such as +"guest-shutdown". + +Fixes: 781f2b3d1e5ef389b44016a897fd55e7a780bf35 +Cc: Michael Roth +Reported-by: Christian Ehrhardt +Signed-off-by: Marc-André Lureau +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael Roth +Signed-off-by: BiaoXiang Ye +--- + qga/main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/qga/main.c b/qga/main.c +index c35c2a21..12fa463f 100644 +--- a/qga/main.c ++++ b/qga/main.c +@@ -529,7 +529,11 @@ static int send_response(GAState *s, const QDict *rsp) + QString *payload_qstr, *response_qstr; + GIOStatus status; + +- g_assert(rsp && s->channel); ++ g_assert(s->channel); ++ ++ if (!rsp) { ++ return 0; ++ } + + payload_qstr = qobject_to_json(QOBJECT(rsp)); + if (!payload_qstr) { +-- +2.27.0.dirty + diff --git a/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch b/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch new file mode 100644 index 0000000000000000000000000000000000000000..1ceb1e70b84f1e1a9a3f785ff2d4d55b697a7cb4 --- /dev/null +++ b/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch @@ -0,0 +1,47 @@ +From 1f1949368d4ac7a18973aa83a074daf01daf97ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 25 Mar 2020 19:47:22 +0100 +Subject: [PATCH 3/5] qmp: fix leak on callbacks that return both value and + error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Direct leak of 4120 byte(s) in 1 object(s) allocated from: + #0 0x7fa114931887 in __interceptor_calloc (/lib64/libasan.so.6+0xb0887) + #1 0x7fa1144ad8f0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x588f0) + #2 0x561e3c9c8897 in qmp_object_add /home/elmarco/src/qemu/qom/qom-qmp-cmds.c:291 + #3 0x561e3cf48736 in qmp_dispatch /home/elmarco/src/qemu/qapi/qmp-dispatch.c:155 + #4 0x561e3c8efb36 in monitor_qmp_dispatch /home/elmarco/src/qemu/monitor/qmp.c:145 + #5 0x561e3c8f09ed in monitor_qmp_bh_dispatcher /home/elmarco/src/qemu/monitor/qmp.c:234 + #6 0x561e3d08c993 in aio_bh_call /home/elmarco/src/qemu/util/async.c:136 + #7 0x561e3d08d0a5 in aio_bh_poll /home/elmarco/src/qemu/util/async.c:164 + #8 0x561e3d0a535a in aio_dispatch /home/elmarco/src/qemu/util/aio-posix.c:380 + #9 0x561e3d08e3ca in aio_ctx_dispatch /home/elmarco/src/qemu/util/async.c:298 + #10 0x7fa1144a776e in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x5276e) + +Signed-off-by: Marc-André Lureau +Message-Id: <20200325184723.2029630-3-marcandre.lureau@redhat.com> +Reviewed-by: Markus Armbruster +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + qapi/qmp-dispatch.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c +index 6dfdad57..a635abb9 100644 +--- a/qapi/qmp-dispatch.c ++++ b/qapi/qmp-dispatch.c +@@ -189,6 +189,8 @@ QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, + + ret = do_qmp_dispatch(cmds, request, allow_oob, &err); + if (err) { ++ /* or assert(!ret) after reviewing all handlers: */ ++ qobject_unref(ret); + rsp = qmp_error_response(err); + } else if (ret) { + rsp = qdict_new(); +-- +2.22.0.windows.1 + diff --git a/slirp-networking-fix-out-of-bounds-read-information.patch b/slirp-networking-fix-out-of-bounds-read-information.patch new file mode 100644 index 0000000000000000000000000000000000000000..a720042222793aa8011f470f54ecad62c946c423 --- /dev/null +++ b/slirp-networking-fix-out-of-bounds-read-information.patch @@ -0,0 +1,36 @@ +From 353521693d409d3800fa9bb29981bf15b7be9729 Mon Sep 17 00:00:00 2001 +From: Jiajie Li +Date: Thu, 10 Sep 2020 10:49:36 +0800 +Subject: [PATCH] Init slirp/src/ip6_input.c + +Drop Ipv6 message shorter than what's mentioned in the payload +length header (+ the size of the IPv6 header). Ther're invalid and could +lead to data leakage in icmp6_send_echoreply(). + +Signed-off-by Ralf Haferkamp + +--- + qemu-4.0.0/slirp/src/ip6_input.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/qemu-4.0.0/slirp/src/ip6_input.c b/qemu-4.0.0/slirp/src/ip6_input.c +index c966d91..d9d2b7e 100644 +--- a/qemu-4.0.0/slirp/src/ip6_input.c ++++ b/qemu-4.0.0/slirp/src/ip6_input.c +@@ -49,13 +49,6 @@ void ip6_input(struct mbuf *m) + goto bad; + } + +- // Check if the message size is big enough to hold what's +- // set in the payload length header. If not this is an invalid +- // packet +- if(m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)){ +- goto bad; +- } +- + /* check ip_ttl for a correct ICMP reply */ + if (ip6->ip_hl == 0) { + icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS); +-- +1.8.3.1 + diff --git a/usbredir-fix-buffer-overflow-on-vmload.patch b/usbredir-fix-buffer-overflow-on-vmload.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a43c35cad37bcece9822ddf61033c18dd7edfc4 --- /dev/null +++ b/usbredir-fix-buffer-overflow-on-vmload.patch @@ -0,0 +1,54 @@ +From 66fce891aecec3969d1ba979cf0a9a6df70afecd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 7 Aug 2019 12:40:48 +0400 +Subject: [PATCH] usbredir: fix buffer-overflow on vmload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If interface_count is NO_INTERFACE_INFO, let's not access the arrays +out-of-bounds. + +==994==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x625000243930 at pc 0x5642068086a8 bp 0x7f0b6f9ffa50 sp 0x7f0b6f9ffa40 +READ of size 1 at 0x625000243930 thread T0 + #0 0x5642068086a7 in usbredir_check_bulk_receiving /home/elmarco/src/qemu/hw/usb/redirect.c:1503 + #1 0x56420681301c in usbredir_post_load /home/elmarco/src/qemu/hw/usb/redirect.c:2154 + #2 0x5642068a56c2 in vmstate_load_state /home/elmarco/src/qemu/migration/vmstate.c:168 + #3 0x56420688e2ac in vmstate_load /home/elmarco/src/qemu/migration/savevm.c:829 + #4 0x5642068980cb in qemu_loadvm_section_start_full /home/elmarco/src/qemu/migration/savevm.c:2211 + #5 0x564206899645 in qemu_loadvm_state_main /home/elmarco/src/qemu/migration/savevm.c:2395 + #6 0x5642068998cf in qemu_loadvm_state /home/elmarco/src/qemu/migration/savevm.c:2467 + #7 0x56420685f3e9 in process_incoming_migration_co /home/elmarco/src/qemu/migration/migration.c:449 + #8 0x564207106c47 in coroutine_trampoline /home/elmarco/src/qemu/util/coroutine-ucontext.c:115 + #9 0x7f0c0604e37f (/lib64/libc.so.6+0x4d37f) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Liam Merwick +Reviewed-by: Li Qiang +Reviewed-by: Philippe Mathieu-Daudé +Message-id: 20190807084048.4258-1-marcandre.lureau@redhat.com +Signed-off-by: Gerd Hoffmann +Signed-off-by: Zhenyu Ye +--- + hw/usb/redirect.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 998fc6e4..9764a579 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -1495,6 +1495,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev) + for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) { + dev->endpoint[i].bulk_receiving_enabled = 0; + } ++ ++ if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { ++ return; ++ } ++ + for (i = 0; i < dev->interface_info.interface_count; i++) { + quirks = usb_get_quirks(dev->device_info.vendor_id, + dev->device_info.product_id, +-- +2.22.0.windows.1 + diff --git a/vhost-user-blk-delay-vhost_user_blk_disconnect.patch b/vhost-user-blk-delay-vhost_user_blk_disconnect.patch new file mode 100644 index 0000000000000000000000000000000000000000..422e2a17b028d83690cc620a57829260c76aab52 --- /dev/null +++ b/vhost-user-blk-delay-vhost_user_blk_disconnect.patch @@ -0,0 +1,90 @@ +From 632a841b6ba547906b475250f5c2cb46774ab4af Mon Sep 17 00:00:00 2001 +From: Dima Stepanov +Date: Thu, 28 May 2020 12:11:19 +0300 +Subject: [PATCH 14/14] vhost-user-blk: delay vhost_user_blk_disconnect + +A socket write during vhost-user communication may trigger a disconnect +event, calling vhost_user_blk_disconnect() and clearing all the +vhost_dev structures holding data that vhost-user functions expect to +remain valid to roll back initialization correctly. Delay the cleanup to +keep vhost_dev structure valid. +There are two possible states to handle: +1. RUN_STATE_PRELAUNCH: skip bh oneshot call and perform disconnect in +the caller routine. +2. RUN_STATE_RUNNING: delay by using bh + +BH changes are based on the similar changes for the vhost-user-net +device: + commit e7c83a885f865128ae3cf1946f8cb538b63cbfba + "vhost-user: delay vhost_user_stop" + +Signed-off-by: Dima Stepanov +Message-Id: <69b73b94dcd066065595266c852810e0863a0895.1590396396.git.dimastep@yandex-team.ru> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Li Feng +Reviewed-by: Raphael Norwitz +Signed-off-by: Peng Liang +--- + hw/block/vhost-user-blk.c | 38 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 37 insertions(+), 1 deletion(-) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index dc66f8a5febd..6b719d1d80e1 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -346,6 +346,19 @@ static void vhost_user_blk_disconnect(DeviceState *dev) + vhost_dev_cleanup(&s->dev); + } + ++static void vhost_user_blk_event(void *opaque, int event); ++ ++static void vhost_user_blk_chr_closed_bh(void *opaque) ++{ ++ DeviceState *dev = opaque; ++ VirtIODevice *vdev = VIRTIO_DEVICE(dev); ++ VHostUserBlk *s = VHOST_USER_BLK(vdev); ++ ++ vhost_user_blk_disconnect(dev); ++ qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event, ++ NULL, opaque, NULL, true); ++} ++ + static void vhost_user_blk_event(void *opaque, int event) + { + DeviceState *dev = opaque; +@@ -360,7 +373,30 @@ static void vhost_user_blk_event(void *opaque, int event) + } + break; + case CHR_EVENT_CLOSED: +- vhost_user_blk_disconnect(dev); ++ /* ++ * A close event may happen during a read/write, but vhost ++ * code assumes the vhost_dev remains setup, so delay the ++ * stop & clear. There are two possible paths to hit this ++ * disconnect event: ++ * 1. When VM is in the RUN_STATE_PRELAUNCH state. The ++ * vhost_user_blk_device_realize() is a caller. ++ * 2. In tha main loop phase after VM start. ++ * ++ * For p2 the disconnect event will be delayed. We can't ++ * do the same for p1, because we are not running the loop ++ * at this moment. So just skip this step and perform ++ * disconnect in the caller function. ++ * ++ * TODO: maybe it is a good idea to make the same fix ++ * for other vhost-user devices. ++ */ ++ if (runstate_is_running()) { ++ AioContext *ctx = qemu_get_current_aio_context(); ++ ++ qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, NULL, ++ NULL, NULL, false); ++ aio_bh_schedule_oneshot(ctx, vhost_user_blk_chr_closed_bh, opaque); ++ } + break; + } + } +-- +2.26.2 + diff --git a/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch b/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch new file mode 100644 index 0000000000000000000000000000000000000000..205f663470d3aa594910bd19e2be8547d226e1a8 --- /dev/null +++ b/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch @@ -0,0 +1,45 @@ +From ec8a25fec9898f46a6a94aa4f328fe02948b3d59 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Sat, 28 Mar 2020 08:57:04 +0800 +Subject: [PATCH 12/14] virtio-blk: delete vqs on the error path in realize() + +virtio_vqs forgot to free on the error path in realize(). Fix that. + +The asan stack: +Direct leak of 14336 byte(s) in 1 object(s) allocated from: + #0 0x7f58b93fd970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970) + #1 0x7f58b858249d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d) + #2 0x5562cc627f49 in virtio_add_queue /mnt/sdb/qemu/hw/virtio/virtio.c:2413 + #3 0x5562cc4b524a in virtio_blk_device_realize /mnt/sdb/qemu/hw/block/virtio-blk.c:1202 + #4 0x5562cc613050 in virtio_device_realize /mnt/sdb/qemu/hw/virtio/virtio.c:3615 + #5 0x5562ccb7a568 in device_set_realized /mnt/sdb/qemu/hw/core/qdev.c:891 + #6 0x5562cd39cd45 in property_set_bool /mnt/sdb/qemu/qom/object.c:2238 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Stefano Garzarella +Message-Id: <20200328005705.29898-2-pannengyuan@huawei.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/block/virtio-blk.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index cbb3729158fe..703ed4c93bff 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -1173,6 +1173,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) + virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err); + if (err != NULL) { + error_propagate(errp, err); ++ for (i = 0; i < conf->num_queues; i++) { ++ virtio_del_queue(vdev, i); ++ } + virtio_cleanup(vdev); + return; + } +-- +2.26.2 + diff --git a/virtio-pci-fix-queue_enable-write.patch b/virtio-pci-fix-queue_enable-write.patch new file mode 100644 index 0000000000000000000000000000000000000000..481b41bbf11f4ebb94ae8fd746b13ad4ac41555d --- /dev/null +++ b/virtio-pci-fix-queue_enable-write.patch @@ -0,0 +1,58 @@ +From aebd6a1512e03ba51f6824fcdbaa09f67e9ff5e2 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 10 Jun 2020 13:43:51 +0800 +Subject: [PATCH 11/11] virtio-pci: fix queue_enable write + +Spec said: The driver uses this to selectively prevent the device from +executing requests from this virtqueue. 1 - enabled; 0 - disabled. + +Though write 0 to queue_enable is forbidden by the spec, we should not +assume that the value is 1. + +Fix this by ignore the write value other than 1. + +Signed-off-by: Jason Wang +Message-Id: <20200610054351.15811-1-jasowang@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Stefano Garzarella +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: BiaoXiang Ye +--- + hw/virtio/virtio-pci.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index b4b0ed26..4b8845a6 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -1259,16 +1259,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, + virtio_queue_set_vector(vdev, vdev->queue_sel, val); + break; + case VIRTIO_PCI_COMMON_Q_ENABLE: +- virtio_queue_set_num(vdev, vdev->queue_sel, +- proxy->vqs[vdev->queue_sel].num); +- virtio_queue_set_rings(vdev, vdev->queue_sel, ++ if (val == 1) { ++ virtio_queue_set_num(vdev, vdev->queue_sel, ++ proxy->vqs[vdev->queue_sel].num); ++ virtio_queue_set_rings(vdev, vdev->queue_sel, + ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 | + proxy->vqs[vdev->queue_sel].desc[0], + ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 | + proxy->vqs[vdev->queue_sel].avail[0], + ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 | + proxy->vqs[vdev->queue_sel].used[0]); +- proxy->vqs[vdev->queue_sel].enabled = 1; ++ proxy->vqs[vdev->queue_sel].enabled = 1; ++ } else { ++ virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val); ++ } + break; + case VIRTIO_PCI_COMMON_Q_DESCLO: + proxy->vqs[vdev->queue_sel].desc[0] = val; +-- +2.27.0.dirty + diff --git a/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch b/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch new file mode 100644 index 0000000000000000000000000000000000000000..02069901b096cd09b0f30dbef9d55e3fe6dc920d --- /dev/null +++ b/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch @@ -0,0 +1,65 @@ +From 0d93f5455489274201b1054d987b12f8e8a6206e Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Mon, 9 Mar 2020 10:17:38 +0800 +Subject: [PATCH 11/14] virtio-serial-bus: Plug memory leak on realize() error + paths + +We neglect to free port->bh on the error paths. Fix that. +Reproducer: + {'execute': 'device_add', 'arguments': {'id': 'virtio_serial_pci0', 'driver': 'virtio-serial-pci', 'bus': 'pci.0', 'addr': '0x5'}, 'id': 'yVkZcGgV'} + {'execute': 'device_add', 'arguments': {'id': 'port1', 'driver': 'virtserialport', 'name': 'port1', 'chardev': 'channel1', 'bus': 'virtio_serial_pci0.0', 'nr': 1}, 'id': '3dXdUgJA'} + {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 'virtio_serial_pci0.0', 'nr': 1}, 'id': 'qLzcCkob'} + {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 'virtio_serial_pci0.0', 'nr': 2}, 'id': 'qLzcCkob'} + +The leak stack: +Direct leak of 40 byte(s) in 1 object(s) allocated from: + #0 0x7f04a8008ae8 in __interceptor_malloc (/lib64/libasan.so.5+0xefae8) + #1 0x7f04a73cf1d5 in g_malloc (/lib64/libglib-2.0.so.0+0x531d5) + #2 0x56273eaee484 in aio_bh_new /mnt/sdb/backup/qemu/util/async.c:125 + #3 0x56273eafe9a8 in qemu_bh_new /mnt/sdb/backup/qemu/util/main-loop.c:532 + #4 0x56273d52e62e in virtser_port_device_realize /mnt/sdb/backup/qemu/hw/char/virtio-serial-bus.c:946 + #5 0x56273dcc5040 in device_set_realized /mnt/sdb/backup/qemu/hw/core/qdev.c:891 + #6 0x56273e5ebbce in property_set_bool /mnt/sdb/backup/qemu/qom/object.c:2238 + #7 0x56273e5e5a9c in object_property_set /mnt/sdb/backup/qemu/qom/object.c:1324 + #8 0x56273e5ef5f8 in object_property_set_qobject /mnt/sdb/backup/qemu/qom/qom-qobject.c:26 + #9 0x56273e5e5e6a in object_property_set_bool /mnt/sdb/backup/qemu/qom/object.c:1390 + #10 0x56273daa40de in qdev_device_add /mnt/sdb/backup/qemu/qdev-monitor.c:680 + #11 0x56273daa53e9 in qmp_device_add /mnt/sdb/backup/qemu/qdev-monitor.c:805 + +Fixes: 199646d81522509ac2dba6d28c31e8c7d807bc93 +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Markus Armbruster +Reviewed-by: Amit Shah +Message-Id: <20200309021738.30072-1-pannengyuan@huawei.com> +Reviewed-by: Laurent Vivier +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/char/virtio-serial-bus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index f7a54f261b21..2d23dae6d2b7 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -940,7 +940,6 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + Error *err = NULL; + + port->vser = bus->vser; +- port->bh = qemu_bh_new(flush_queued_data_bh, port); + + assert(vsc->have_data); + +@@ -989,6 +988,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + return; + } + ++ port->bh = qemu_bh_new(flush_queued_data_bh, port); + port->elem = NULL; + } + +-- +2.26.2 + diff --git a/xhci-fix-valid.max_access_size-to-access-address-reg.patch b/xhci-fix-valid.max_access_size-to-access-address-reg.patch new file mode 100644 index 0000000000000000000000000000000000000000..466cbf2667efaf26cc65c160c8223659abb0c288 --- /dev/null +++ b/xhci-fix-valid.max_access_size-to-access-address-reg.patch @@ -0,0 +1,62 @@ +From a71d1847aa780b3c4062e582ab400a7fea0413b3 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Tue, 21 Jul 2020 10:33:22 +0200 +Subject: [PATCH 01/11] xhci: fix valid.max_access_size to access address + registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU XHCI advertises AC64 (64-bit addressing) but doesn't allow +64-bit mode access in "runtime" and "operational" MemoryRegionOps. + +Set the max_access_size based on sizeof(dma_addr_t) as AC64 is set. + +XHCI specs: +"If the xHC supports 64-bit addressing (AC64 = ‘1’), then software +should write 64-bit registers using only Qword accesses. If a +system is incapable of issuing Qword accesses, then writes to the +64-bit address fields shall be performed using 2 Dword accesses; +low Dword-first, high-Dword second. If the xHC supports 32-bit +addressing (AC64 = ‘0’), then the high Dword of registers containing +64-bit address fields are unused and software should write addresses +using only Dword accesses" + +The problem has been detected with SLOF, as linux kernel always accesses +registers using 32-bit access even if AC64 is set and revealed by +5d971f9e6725 ("memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"") + +Suggested-by: Alexey Kardashevskiy +Signed-off-by: Laurent Vivier +Message-id: 20200721083322.90651-1-lvivier@redhat.com +Signed-off-by: Gerd Hoffmann +Signed-off-by: BiaoXiang Ye +--- + hw/usb/hcd-xhci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index a21485fe..24565de1 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -3171,7 +3171,7 @@ static const MemoryRegionOps xhci_oper_ops = { + .read = xhci_oper_read, + .write = xhci_oper_write, + .valid.min_access_size = 4, +- .valid.max_access_size = 4, ++ .valid.max_access_size = sizeof(dma_addr_t), + .endianness = DEVICE_LITTLE_ENDIAN, + }; + +@@ -3187,7 +3187,7 @@ static const MemoryRegionOps xhci_runtime_ops = { + .read = xhci_runtime_read, + .write = xhci_runtime_write, + .valid.min_access_size = 4, +- .valid.max_access_size = 4, ++ .valid.max_access_size = sizeof(dma_addr_t), + .endianness = DEVICE_LITTLE_ENDIAN, + }; + +-- +2.27.0.dirty +