From b647e6427f22126bd5e3f06b65925db0fee8ff89 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Mon, 29 Jul 2024 02:34:57 -0400 Subject: [PATCH] * Mon Jul 29 2024 Miroslav Rezanina - 6.2.0-50.el8.1 - kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch [RHEL-32276] - kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch [RHEL-32276] - kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch [RHEL-32276] - kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch [RHEL-32276] - kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch [RHEL-32276] - kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch [RHEL-32276] - Resolves: RHEL-32276 (CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8]) --- ...erial-bus-Protect-from-DMA-re-entran.patch | 61 +++++++ ...o-gpu-Protect-from-DMA-re-entrancy-b.patch | 160 ++++++++++++++++++ ...troduce-virtio_bh_new_guarded-helper.patch | 86 ++++++++++ ...-crypto-Protect-from-DMA-re-entrancy.patch | 62 +++++++ ...u-free-BHs-by-implementing-unrealize.patch | 92 ++++++++++ ...u-reset-gfx-resources-in-main-thread.patch | 143 ++++++++++++++++ qemu-kvm.spec | 24 ++- 7 files changed, 627 insertions(+), 1 deletion(-) create mode 100644 kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch create mode 100644 kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch create mode 100644 kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch create mode 100644 kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch create mode 100644 kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch create mode 100644 kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch diff --git a/kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch b/kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch new file mode 100644 index 0000000..d684d63 --- /dev/null +++ b/kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch @@ -0,0 +1,61 @@ +From f4623ea611a74c684b0097b98a803cbe7ffb0825 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:26:55 -0400 +Subject: [PATCH 5/6] hw/char/virtio-serial-bus: Protect from DMA re-entrancy + bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/6] fc8a445ebf6e763cd1482cd1f7ee23e5b5bbb388 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit b4295bff25f7b50de1d9cc94a9c6effd40056bca +Author: Philippe Mathieu-Daudé +Date: Thu Apr 4 20:56:35 2024 +0200 + + hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs + + Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() + so the bus and device use the same guard. Otherwise the + DMA-reentrancy protection can be bypassed. + + Fixes: CVE-2024-3446 + Cc: qemu-stable@nongnu.org + Suggested-by: Alexander Bulekov + Reviewed-by: Gerd Hoffmann + Acked-by: Michael S. Tsirkin + Signed-off-by: Philippe Mathieu-Daudé + Reviewed-by: Michael S. Tsirkin + Message-Id: <20240409105537.18308-4-philmd@linaro.org> + +Signed-off-by: Jon Maloy +--- + hw/char/virtio-serial-bus.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index f18124b155..791b7ac59e 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -985,8 +985,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + return; + } + +- port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port, +- &dev->mem_reentrancy_guard); ++ port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port); + port->elem = NULL; + } + +-- +2.39.3 + diff --git a/kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch b/kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch new file mode 100644 index 0000000..8402130 --- /dev/null +++ b/kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch @@ -0,0 +1,160 @@ +From d37035373a266644b241aab1f041ab09c9185540 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:29:54 -0400 +Subject: [PATCH 4/6] hw/display/virtio-gpu: Protect from DMA re-entrancy bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/6] e3cd21742228528a1a74ea62d55b5941d3efb261 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit ba28e0ff4d95b56dc334aac2730ab3651ffc3132 +Author: Philippe Mathieu-Daudé +Date: Thu Apr 4 20:56:27 2024 +0200 + + hw/display/virtio-gpu: Protect from DMA re-entrancy bugs + + Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() + so the bus and device use the same guard. Otherwise the + DMA-reentrancy protection can be bypassed: + + $ cat << EOF | qemu-system-i386 -display none -nodefaults \ + -machine q35,accel=qtest \ + -m 512M \ + -device virtio-gpu \ + -qtest stdio + outl 0xcf8 0x80000820 + outl 0xcfc 0xe0004000 + outl 0xcf8 0x80000804 + outw 0xcfc 0x06 + write 0xe0004030 0x4 0x024000e0 + write 0xe0004028 0x1 0xff + write 0xe0004020 0x4 0x00009300 + write 0xe000401c 0x1 0x01 + write 0x101 0x1 0x04 + write 0x103 0x1 0x1c + write 0x9301c8 0x1 0x18 + write 0x105 0x1 0x1c + write 0x107 0x1 0x1c + write 0x109 0x1 0x1c + write 0x10b 0x1 0x00 + write 0x10d 0x1 0x00 + write 0x10f 0x1 0x00 + write 0x111 0x1 0x00 + write 0x113 0x1 0x00 + write 0x115 0x1 0x00 + write 0x117 0x1 0x00 + write 0x119 0x1 0x00 + write 0x11b 0x1 0x00 + write 0x11d 0x1 0x00 + write 0x11f 0x1 0x00 + write 0x121 0x1 0x00 + write 0x123 0x1 0x00 + write 0x125 0x1 0x00 + write 0x127 0x1 0x00 + write 0x129 0x1 0x00 + write 0x12b 0x1 0x00 + write 0x12d 0x1 0x00 + write 0x12f 0x1 0x00 + write 0x131 0x1 0x00 + write 0x133 0x1 0x00 + write 0x135 0x1 0x00 + write 0x137 0x1 0x00 + write 0x139 0x1 0x00 + write 0xe0007003 0x1 0x00 + EOF + ... + ================================================================= + ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000011178 + at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58 + READ of size 8 at 0x60d000011178 thread T0 + #0 0x562cc3b736c6 in virtio_gpu_ctrl_response hw/display/virtio-gpu.c:180:42 + #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata hw/display/virtio-gpu.c:192:5 + #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd hw/display/virtio-gpu.c:1015:13 + #3 0x562cc3b82873 in virtio_gpu_process_cmdq hw/display/virtio-gpu.c:1050:9 + #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5 + #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 + #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 + #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5 + #8 0x7f36840547a8 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8) + #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9 + #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5 + #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11 + #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9 + #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14 + #14 0x7f3683a6c189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 + #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3 + #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0) + + 0x60d000011178 is located 56 bytes inside of 136-byte region [0x60d000011140,0x60d0000111c8) + freed by thread T0 here: + #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662) + #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9 + #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9 + #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5 + #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5 + #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18 + + previously allocated by thread T0 here: + #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e) + #1 0x7f368405a678 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678) + #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12 + #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16 + #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl hw/display/virtio-gpu.c:1112:15 + #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5 + #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 + #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 + + SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 in virtio_gpu_ctrl_response + + With this change, the same reproducer triggers: + + qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: virtio-pci-common-virtio-gpu at addr: 0x6 + + Fixes: CVE-2024-3446 + Cc: qemu-stable@nongnu.org + Reported-by: Alexander Bulekov + Reported-by: Yongkang Jia + Reported-by: Xiao Lei + Reported-by: Yiming Tao + Buglink: https://bugs.launchpad.net/qemu/+bug/1888606 + Reviewed-by: Gerd Hoffmann + Acked-by: Michael S. Tsirkin + Signed-off-by: Philippe Mathieu-Daudé + Reviewed-by: Michael S. Tsirkin + Message-Id: <20240409105537.18308-3-philmd@linaro.org> + +Signed-off-by: Jon Maloy +--- + hw/display/virtio-gpu.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index c28ce1ea72..64fdc18478 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -1334,10 +1334,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) + + g->ctrl_vq = virtio_get_queue(vdev, 0); + g->cursor_vq = virtio_get_queue(vdev, 1); +- g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g, +- &qdev->mem_reentrancy_guard); +- g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, +- &qdev->mem_reentrancy_guard); ++ g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g); ++ g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g); + g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g); + qemu_cond_init(&g->reset_cond); + QTAILQ_INIT(&g->reslist); +-- +2.39.3 + diff --git a/kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch b/kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch new file mode 100644 index 0000000..cdb03e2 --- /dev/null +++ b/kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch @@ -0,0 +1,86 @@ +From 1b62d61c495bf4cd3a819ab8d1ef024d153e0ece Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:40:29 -0400 +Subject: [PATCH 3/6] hw/virtio: Introduce virtio_bh_new_guarded() helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/6] 1cbde7ddb8393b72e2e8d457b5e2d739116567a9 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit ec0504b989ca61e03636384d3602b7bf07ffe4da +Author: Philippe Mathieu-Daudé +Date: Thu Apr 4 20:56:11 2024 +0200 + + hw/virtio: Introduce virtio_bh_new_guarded() helper + + Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded() + but using the transport memory guard, instead of the device one + (there can only be one virtio device per virtio bus). + + Inspired-by: Gerd Hoffmann + Reviewed-by: Gerd Hoffmann + Acked-by: Michael S. Tsirkin + Signed-off-by: Philippe Mathieu-Daudé + Reviewed-by: Michael S. Tsirkin + Message-Id: <20240409105537.18308-2-philmd@linaro.org> + +Signed-off-by: Jon Maloy +--- + hw/virtio/virtio.c | 10 ++++++++++ + include/hw/virtio/virtio.h | 7 +++++++ + 2 files changed, 17 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index ea7c079fb0..5ae9c44841 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -3874,3 +3874,13 @@ static void virtio_register_types(void) + } + + type_init(virtio_register_types) ++ ++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, ++ QEMUBHFunc *cb, void *opaque, ++ const char *name) ++{ ++ DeviceState *transport = qdev_get_parent_bus(dev)->parent; ++ ++ return qemu_bh_new_full(cb, opaque, name, ++ &transport->mem_reentrancy_guard); ++} +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 8bab9cfb75..731c631a81 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -22,6 +22,7 @@ + #include "standard-headers/linux/virtio_config.h" + #include "standard-headers/linux/virtio_ring.h" + #include "qom/object.h" ++#include "block/aio.h" + + /* A guest should never accept this. It implies negotiation is broken. */ + #define VIRTIO_F_BAD_FEATURE 30 +@@ -397,4 +398,10 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev) + bool virtio_legacy_allowed(VirtIODevice *vdev); + bool virtio_legacy_check_disabled(VirtIODevice *vdev); + ++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, ++ QEMUBHFunc *cb, void *opaque, ++ const char *name); ++#define virtio_bh_new_guarded(dev, cb, opaque) \ ++ virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb))) ++ + #endif +-- +2.39.3 + diff --git a/kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch b/kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch new file mode 100644 index 0000000..9126ae8 --- /dev/null +++ b/kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch @@ -0,0 +1,62 @@ +From 2ecbd673a0e2191821ce88128587f709936ad765 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:21:27 -0400 +Subject: [PATCH 6/6] hw/virtio/virtio-crypto: Protect from DMA re-entrancy + bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/6] 975ac4640fd8e7cbf3820757787ee7b1270173be (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit f4729ec39ad97a42ceaa7b5697f84f440ea6e5dc +Author: Philippe Mathieu-Daudé +Date: Thu Apr 4 20:56:41 2024 +0200 + + hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs + + Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() + so the bus and device use the same guard. Otherwise the + DMA-reentrancy protection can be bypassed. + + Fixes: CVE-2024-3446 + Cc: qemu-stable@nongnu.org + Suggested-by: Alexander Bulekov + Reviewed-by: Gerd Hoffmann + Acked-by: Michael S. Tsirkin + Signed-off-by: Philippe Mathieu-Daudé + Reviewed-by: Michael S. Tsirkin + Message-Id: <20240409105537.18308-5-philmd@linaro.org> + +Signed-off-by: Jon Maloy +--- + hw/virtio/virtio-crypto.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c +index 1be7bb543c..1741d4aba1 100644 +--- a/hw/virtio/virtio-crypto.c ++++ b/hw/virtio/virtio-crypto.c +@@ -817,8 +817,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) + vcrypto->vqs[i].dataq = + virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); + vcrypto->vqs[i].dataq_bh = +- qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], +- &dev->mem_reentrancy_guard); ++ virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh, ++ &vcrypto->vqs[i]); + vcrypto->vqs[i].vcrypto = vcrypto; + } + +-- +2.39.3 + diff --git a/kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch b/kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch new file mode 100644 index 0000000..cd0dab2 --- /dev/null +++ b/kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch @@ -0,0 +1,92 @@ +From 7ad4fc282b1f96d619ce2f9f7ed9049c3b894dd4 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:42:42 -0400 +Subject: [PATCH 1/6] virtio-gpu: free BHs, by implementing unrealize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/6] d05c10426afac428d775669748f0aa689c23e787 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit 957d77863e4564454eb97f8f371096843daf4678 +Author: Marc-André Lureau +Date: Wed Jul 26 21:39:28 2023 +0400 + + virtio-gpu: free BHs, by implementing unrealize + + Acked-by: Dongwon Kim + Signed-off-by: Marc-André Lureau + Message-Id: <20230726173929.690601-2-marcandre.lureau@redhat.com> + +Signed-off-by: Jon Maloy +--- + hw/display/virtio-gpu-base.c | 2 +- + hw/display/virtio-gpu.c | 10 ++++++++++ + include/hw/virtio/virtio-gpu.h | 1 + + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c +index c8da4806e0..e3ff9dcf38 100644 +--- a/hw/display/virtio-gpu-base.c ++++ b/hw/display/virtio-gpu-base.c +@@ -223,7 +223,7 @@ virtio_gpu_base_set_features(VirtIODevice *vdev, uint64_t features) + trace_virtio_gpu_features(((features & virgl) == virgl)); + } + +-static void ++void + virtio_gpu_base_device_unrealize(DeviceState *qdev) + { + VirtIOGPUBase *g = VIRTIO_GPU_BASE(qdev); +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index ecf9079145..e230e5091f 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -1341,6 +1341,15 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) + QTAILQ_INIT(&g->fenceq); + } + ++static void virtio_gpu_device_unrealize(DeviceState *qdev) ++{ ++ VirtIOGPU *g = VIRTIO_GPU(qdev); ++ ++ g_clear_pointer(&g->ctrl_bh, qemu_bh_delete); ++ g_clear_pointer(&g->cursor_bh, qemu_bh_delete); ++ virtio_gpu_base_device_unrealize(qdev); ++} ++ + void virtio_gpu_reset(VirtIODevice *vdev) + { + VirtIOGPU *g = VIRTIO_GPU(vdev); +@@ -1436,6 +1445,7 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data) + vgbc->gl_flushed = virtio_gpu_handle_gl_flushed; + + vdc->realize = virtio_gpu_device_realize; ++ vdc->unrealize = virtio_gpu_device_unrealize; + vdc->reset = virtio_gpu_reset; + vdc->get_config = virtio_gpu_get_config; + vdc->set_config = virtio_gpu_set_config; +diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h +index acfba7c76c..4367d005f1 100644 +--- a/include/hw/virtio/virtio-gpu.h ++++ b/include/hw/virtio/virtio-gpu.h +@@ -235,6 +235,7 @@ bool virtio_gpu_base_device_realize(DeviceState *qdev, + VirtIOHandleOutput ctrl_cb, + VirtIOHandleOutput cursor_cb, + Error **errp); ++void virtio_gpu_base_device_unrealize(DeviceState *qdev); + void virtio_gpu_base_reset(VirtIOGPUBase *g); + void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g, + struct virtio_gpu_resp_display_info *dpy_info); +-- +2.39.3 + diff --git a/kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch b/kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch new file mode 100644 index 0000000..0ec5913 --- /dev/null +++ b/kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch @@ -0,0 +1,143 @@ +From 29328e9693aeae1c980a859d4966deda9f54242d Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 18 Jul 2024 09:36:06 -0400 +Subject: [PATCH 2/6] virtio-gpu: reset gfx resources in main thread +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 380: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability +RH-Jira: RHEL-32276 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/6] a97eef1e6e85b44c08d17adcdc468e857e48a17e (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-32276 +CVE: CVE-2024-3446 +Upstream: Merged + +commit a41e2d97f92b48552988b3cc62dce79d62f60dcc +Author: Marc-André Lureau +Date: Wed Jul 26 21:39:29 2023 +0400 + + virtio-gpu: reset gfx resources in main thread + + Calling OpenGL from different threads can have bad consequences if not + carefully reviewed. It's not generally supported. In my case, I was + debugging a crash in glDeleteTextures from OPENGL32.DLL, where I asked + qemu for gl=es, and thus ANGLE implementation was expected. libepoxy did + resolution of the global pointer for glGenTexture to the GLES version + from the main thread. But it resolved glDeleteTextures to the GL + version, because it was done from a different thread without correct + context. Oops. + + Let's stick to the main thread for GL calls by using a BH. + + Note: I didn't use atomics for reset_finished check, assuming the BQL + will provide enough of sync, but I might be wrong. + + Acked-by: Dongwon Kim + Signed-off-by: Marc-André Lureau + Message-Id: <20230726173929.690601-3-marcandre.lureau@redhat.com> + +Signed-off-by: Jon Maloy +--- + hw/display/virtio-gpu.c | 35 +++++++++++++++++++++++++++++++--- + include/hw/virtio/virtio-gpu.h | 3 +++ + 2 files changed, 35 insertions(+), 3 deletions(-) + +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index e230e5091f..c28ce1ea72 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -14,6 +14,7 @@ + #include "qemu/osdep.h" + #include "qemu/units.h" + #include "qemu/iov.h" ++#include "sysemu/cpus.h" + #include "ui/console.h" + #include "trace.h" + #include "sysemu/dma.h" +@@ -42,6 +43,7 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id, + + static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, + struct virtio_gpu_simple_resource *res); ++static void virtio_gpu_reset_bh(void *opaque); + + void virtio_gpu_update_cursor_data(VirtIOGPU *g, + struct virtio_gpu_scanout *s, +@@ -1336,6 +1338,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) + &qdev->mem_reentrancy_guard); + g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, + &qdev->mem_reentrancy_guard); ++ g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g); ++ qemu_cond_init(&g->reset_cond); + QTAILQ_INIT(&g->reslist); + QTAILQ_INIT(&g->cmdq); + QTAILQ_INIT(&g->fenceq); +@@ -1347,19 +1351,44 @@ static void virtio_gpu_device_unrealize(DeviceState *qdev) + + g_clear_pointer(&g->ctrl_bh, qemu_bh_delete); + g_clear_pointer(&g->cursor_bh, qemu_bh_delete); ++ g_clear_pointer(&g->reset_bh, qemu_bh_delete); ++ qemu_cond_destroy(&g->reset_cond); + virtio_gpu_base_device_unrealize(qdev); + } + +-void virtio_gpu_reset(VirtIODevice *vdev) ++static void virtio_gpu_reset_bh(void *opaque) + { +- VirtIOGPU *g = VIRTIO_GPU(vdev); ++ VirtIOGPU *g = VIRTIO_GPU(opaque); + struct virtio_gpu_simple_resource *res, *tmp; +- struct virtio_gpu_ctrl_command *cmd; ++ int i = 0; + + QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { + virtio_gpu_resource_destroy(g, res); + } + ++ for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { ++ dpy_gfx_replace_surface(g->parent_obj.scanout[i].con, NULL); ++ } ++ ++ g->reset_finished = true; ++ qemu_cond_signal(&g->reset_cond); ++} ++ ++void virtio_gpu_reset(VirtIODevice *vdev) ++{ ++ VirtIOGPU *g = VIRTIO_GPU(vdev); ++ struct virtio_gpu_ctrl_command *cmd; ++ ++ if (qemu_in_vcpu_thread()) { ++ g->reset_finished = false; ++ qemu_bh_schedule(g->reset_bh); ++ while (!g->reset_finished) { ++ qemu_cond_wait_iothread(&g->reset_cond); ++ } ++ } else { ++ virtio_gpu_reset_bh(g); ++ } ++ + while (!QTAILQ_EMPTY(&g->cmdq)) { + cmd = QTAILQ_FIRST(&g->cmdq); + QTAILQ_REMOVE(&g->cmdq, cmd, next); +diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h +index 4367d005f1..f3578c1325 100644 +--- a/include/hw/virtio/virtio-gpu.h ++++ b/include/hw/virtio/virtio-gpu.h +@@ -166,6 +166,9 @@ struct VirtIOGPU { + + QEMUBH *ctrl_bh; + QEMUBH *cursor_bh; ++ QEMUBH *reset_bh; ++ QemuCond reset_cond; ++ bool reset_finished; + + QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; + QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq; +-- +2.39.3 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 866634e..f89e04e 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -83,7 +83,7 @@ Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release} Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 6.2.0 -Release: 50%{?rcrel}%{?dist} +Release: 50%{?rcrel}%{?dist}.1 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -857,6 +857,18 @@ Patch347: kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch Patch348: kvm-block-introduce-bdrv_open_file_child-helper.patch # For RHEL-35616 - CVE-2024-4467 virt:rhel/qemu-kvm: QEMU: 'qemu-img info' leads to host file read/write [rhel-8.10.z] Patch349: kvm-block-Parse-filenames-only-when-explicitly-requested.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch350: kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch351: kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch352: kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch353: kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch354: kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch +# For RHEL-32276 - CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8] +Patch355: kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch BuildRequires: wget BuildRequires: rpm-build @@ -2026,6 +2038,16 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %changelog +* Mon Jul 29 2024 Miroslav Rezanina - 6.2.0-50.el8.1 +- kvm-virtio-gpu-free-BHs-by-implementing-unrealize.patch [RHEL-32276] +- kvm-virtio-gpu-reset-gfx-resources-in-main-thread.patch [RHEL-32276] +- kvm-hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch [RHEL-32276] +- kvm-hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch [RHEL-32276] +- kvm-hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch [RHEL-32276] +- kvm-hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch [RHEL-32276] +- Resolves: RHEL-32276 + (CVE-2024-3446 virt:rhel/qemu-kvm: QEMU: virtio: DMA reentrancy issue leads to double free vulnerability [rhel-8]) + * Thu Jul 04 2024 Miroslav Rezanina - 6.2.0-50 - kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch [RHEL-35616] - kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch [RHEL-35616]