diff --git a/kvm-glib-compat-Introduce-g_memdup2-wrapper.patch b/kvm-glib-compat-Introduce-g_memdup2-wrapper.patch new file mode 100644 index 0000000..e60f200 --- /dev/null +++ b/kvm-glib-compat-Introduce-g_memdup2-wrapper.patch @@ -0,0 +1,105 @@ +From 939c75ab92ac608893cad0e46f55527950518a57 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Tue, 5 Mar 2024 11:36:15 -0500 +Subject: [PATCH 1/3] glib-compat: Introduce g_memdup2() wrapper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 353: ui/clipboard: mark type as not available when there is no data +RH-Jira: RHEL-19628 +RH-Acked-by: Marc-André Lureau +RH-Acked-by: Gerd Hoffmann +RH-Commit: [1/2] f401c63303ef558bfcbb36e4c8fcc8bf2b1c3eb4 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-19628 +CVE: CVE-2023-6683 +Upstream: Merged + +commit 2c674fada72079583a3f2cc1790b16a0259c4fa0 +Author: Philippe Mathieu-Daudé +Date: Fri Sep 3 19:44:44 2021 +0200 + + glib-compat: Introduce g_memdup2() wrapper + When experimenting raising GLIB_VERSION_MIN_REQUIRED to 2.68 + (Fedora 34 provides GLib 2.68.1) we get: + + hw/virtio/virtio-crypto.c:245:24: error: 'g_memdup' is deprecated: Use 'g_memdup2' instead [-Werror,-Wdeprecated-declarations] + ... + + g_memdup() has been updated by g_memdup2() to fix eventual security + issues (size argument is 32-bit and could be truncated / wrapping). + GLib recommends to copy their static inline version of g_memdup2(): + https://discourse.gnome.org/t/port-your-module-from-g-memdup-to-g-memdup2-now/5538 + + Our glib-compat.h provides a comment explaining how to deal with + these deprecated declarations (see commit e71e8cc0355 + "glib: enforce the minimum required version and warn about old APIs"). + + Following this comment suggestion, implement the g_memdup2_qemu() + wrapper to g_memdup2(), and use the safer equivalent inlined when + we are using pre-2.68 GLib. + + Reported-by: Eric Blake + Signed-off-by: Philippe Mathieu-Daudé + Reviewed-by: Eric Blake + Message-Id: <20210903174510.751630-3-philmd@redhat.com> + Signed-off-by: Laurent Vivier + +Signed-off-by: Jon Maloy +--- + include/glib-compat.h | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/include/glib-compat.h b/include/glib-compat.h +index 9e95c888f5..8d01a8c01f 100644 +--- a/include/glib-compat.h ++++ b/include/glib-compat.h +@@ -68,6 +68,43 @@ + * without generating warnings. + */ + ++/* ++ * g_memdup2_qemu: ++ * @mem: (nullable): the memory to copy. ++ * @byte_size: the number of bytes to copy. ++ * ++ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it ++ * from @mem. If @mem is %NULL it returns %NULL. ++ * ++ * This replaces g_memdup(), which was prone to integer overflows when ++ * converting the argument from a #gsize to a #guint. ++ * ++ * This static inline version is a backport of the new public API from ++ * GLib 2.68, kept internal to GLib for backport to older stable releases. ++ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319. ++ * ++ * Returns: (nullable): a pointer to the newly-allocated copy of the memory, ++ * or %NULL if @mem is %NULL. ++ */ ++static inline gpointer g_memdup2_qemu(gconstpointer mem, gsize byte_size) ++{ ++#if GLIB_CHECK_VERSION(2, 68, 0) ++ return g_memdup2(mem, byte_size); ++#else ++ gpointer new_mem; ++ ++ if (mem && byte_size != 0) { ++ new_mem = g_malloc(byte_size); ++ memcpy(new_mem, mem, byte_size); ++ } else { ++ new_mem = NULL; ++ } ++ ++ return new_mem; ++#endif ++} ++#define g_memdup2(m, s) g_memdup2_qemu(m, s) ++ + #if defined(G_OS_UNIX) + /* + * Note: The fallback implementation is not MT-safe, and it returns a copy of +-- +2.41.0 + diff --git a/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch b/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch new file mode 100644 index 0000000..8ddcb2c --- /dev/null +++ b/kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch @@ -0,0 +1,118 @@ +From 4069f8f55d070b5a1eb2bf894a517ea9fb648bbd Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Tue, 5 Mar 2024 11:36:15 -0500 +Subject: [PATCH 2/3] ui/clipboard: mark type as not available when there is no + data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Jon Maloy +RH-MergeRequest: 353: ui/clipboard: mark type as not available when there is no data +RH-Jira: RHEL-19628 +RH-Acked-by: Marc-André Lureau +RH-Acked-by: Gerd Hoffmann +RH-Commit: [2/2] fa0edf7a362a16978e2377cf61f36ff227d186b2 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-19628 +CVE: CVE-2023-6683 +Upstream: Merged +Conflicts: + - The function g_memdup2() is used by this commit, but is not present in + this code version. It looks safe to introduce it in a preceding commit, + instead of reverting to the less safe g_memdup(), so that is what we do. + - There is a second upstream commit covering this CVE: + commit 9c416582611b ("ui/clipboard: add asserts for update and request") + which is based on several other previous commits not present in this version. + Re-applying these, or trying to adapt the code, is too intrusive and risky + given that it only introduces two diagnostic asserts which are not essential + for solving the CVE. + We therefore omit that commit. + +commit 405484b29f6548c7b86549b0f961b906337aa68a +Author: Fiona Ebner +Date: Wed Jan 24 11:57:48 2024 +0100 + + ui/clipboard: mark type as not available when there is no data + + With VNC, a client can send a non-extended VNC_MSG_CLIENT_CUT_TEXT + message with len=0. In qemu_clipboard_set_data(), the clipboard info + will be updated setting data to NULL (because g_memdup(data, size) + returns NULL when size is 0). If the client does not set the + VNC_ENCODING_CLIPBOARD_EXT feature when setting up the encodings, then + the 'request' callback for the clipboard peer is not initialized. + Later, because data is NULL, qemu_clipboard_request() can be reached + via vdagent_chr_write() and vdagent_clipboard_recv_request() and + there, the clipboard owner's 'request' callback will be attempted to + be called, but that is a NULL pointer. + + In particular, this can happen when using the KRDC (22.12.3) VNC + client. + + Another scenario leading to the same issue is with two clients (say + noVNC and KRDC): + + The noVNC client sets the extension VNC_FEATURE_CLIPBOARD_EXT and + initializes its cbpeer. + + The KRDC client does not, but triggers a vnc_client_cut_text() (note + it's not the _ext variant)). There, a new clipboard info with it as + the 'owner' is created and via qemu_clipboard_set_data() is called, + which in turn calls qemu_clipboard_update() with that info. + + In qemu_clipboard_update(), the notifier for the noVNC client will be + called, i.e. vnc_clipboard_notify() and also set vs->cbinfo for the + noVNC client. The 'owner' in that clipboard info is the clipboard peer + for the KRDC client, which did not initialize the 'request' function. + That sounds correct to me, it is the owner of that clipboard info. + + Then when noVNC sends a VNC_MSG_CLIENT_CUT_TEXT message (it did set + the VNC_FEATURE_CLIPBOARD_EXT feature correctly, so a check for it + passes), that clipboard info is passed to qemu_clipboard_request() and + the original segfault still happens. + + Fix the issue by handling updates with size 0 differently. In + particular, mark in the clipboard info that the type is not available. + + While at it, switch to g_memdup2(), because g_memdup() is deprecated. + + Cc: qemu-stable@nongnu.org + Fixes: CVE-2023-6683 + Reported-by: Markus Frank + Suggested-by: Marc-André Lureau + Signed-off-by: Fiona Ebner + Reviewed-by: Marc-André Lureau + Tested-by: Markus Frank + Message-ID: <20240124105749.204610-1-f.ebner@proxmox.com> + +Signed-off-by: Jon Maloy +--- + ui/clipboard.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/ui/clipboard.c b/ui/clipboard.c +index d7b008d62a..b8c795f2e2 100644 +--- a/ui/clipboard.c ++++ b/ui/clipboard.c +@@ -123,9 +123,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer, + } + + g_free(info->types[type].data); +- info->types[type].data = g_memdup(data, size); +- info->types[type].size = size; +- info->types[type].available = true; ++ if (size) { ++ info->types[type].data = g_memdup2(data, size); ++ info->types[type].size = size; ++ info->types[type].available = true; ++ } else { ++ info->types[type].data = NULL; ++ info->types[type].size = 0; ++ info->types[type].available = false; ++ } + + if (update) { + qemu_clipboard_update(info); +-- +2.41.0 + diff --git a/kvm-virtio-net-correctly-copy-vnet-header-when-flushing-.patch b/kvm-virtio-net-correctly-copy-vnet-header-when-flushing-.patch new file mode 100644 index 0000000..f030abb --- /dev/null +++ b/kvm-virtio-net-correctly-copy-vnet-header-when-flushing-.patch @@ -0,0 +1,90 @@ +From c3146dd39fb274ffbd70d20f8ba9e13562fb21ad Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Tue, 5 Mar 2024 16:38:49 -0500 +Subject: [PATCH 3/3] virtio-net: correctly copy vnet header when flushing TX + +RH-Author: Jon Maloy +RH-MergeRequest: 354: virtio-net: correctly copy vnet header when flushing TX +RH-Jira: RHEL-19496 +RH-Acked-by: Jason Wang +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/1] 445b601da86a64298b776879fa0f30a4bf6c16f5 (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2) + +JIRA: https://issues.redhat.com/browse/RHEL-19496 +CVE: CVE-2023-6693 +Upstream: Merged + +commit 2220e8189fb94068dbad333228659fbac819abb0 +Author: Jason Wang +Date: Tue Jan 2 11:29:01 2024 +0800 + + virtio-net: correctly copy vnet header when flushing TX + + When HASH_REPORT is negotiated, the guest_hdr_len might be larger than + the size of the mergeable rx buffer header. Using + virtio_net_hdr_mrg_rxbuf during the header swap might lead a stack + overflow in this case. Fixing this by using virtio_net_hdr_v1_hash + instead. + + Reported-by: Xiao Lei + Cc: Yuri Benditovich + Cc: qemu-stable@nongnu.org + Cc: Mauro Matteo Cascella + Fixes: CVE-2023-6693 + Fixes: e22f0603fb2f ("virtio-net: reference implementation of hash report") + Reviewed-by: Michael Tokarev + Signed-off-by: Jason Wang + +Signed-off-by: Jon Maloy +--- + hw/net/virtio-net.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index f5f07f8e63..7d459726d4 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -602,6 +602,11 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs, + + n->mergeable_rx_bufs = mergeable_rx_bufs; + ++ /* ++ * Note: when extending the vnet header, please make sure to ++ * change the vnet header copying logic in virtio_net_flush_tx() ++ * as well. ++ */ + if (version_1) { + n->guest_hdr_len = hash_report ? + sizeof(struct virtio_net_hdr_v1_hash) : +@@ -2535,7 +2540,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + ssize_t ret; + unsigned int out_num; + struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg; +- struct virtio_net_hdr_mrg_rxbuf mhdr; ++ struct virtio_net_hdr_v1_hash vhdr; + + elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement)); + if (!elem) { +@@ -2552,7 +2557,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + } + + if (n->has_vnet_hdr) { +- if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) < ++ if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) < + n->guest_hdr_len) { + virtio_error(vdev, "virtio-net header incorrect"); + virtqueue_detach_element(q->tx_vq, elem, 0); +@@ -2560,8 +2565,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) + return -EINVAL; + } + if (n->needs_vnet_hdr_swap) { +- virtio_net_hdr_swap(vdev, (void *) &mhdr); +- sg2[0].iov_base = &mhdr; ++ virtio_net_hdr_swap(vdev, (void *) &vhdr); ++ sg2[0].iov_base = &vhdr; + sg2[0].iov_len = n->guest_hdr_len; + out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, + out_sg, out_num, +-- +2.41.0 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 1aca466..991f09b 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: 48%{?rcrel}%{?dist} +Release: 49%{?rcrel}%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -841,6 +841,12 @@ Patch339: kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch Patch340: kvm-monitor-only-run-coroutine-commands-in-qemu_aio_cont.patch # For RHEL-7353 - [qemu-kvm] no response with QMP command device_add when repeatedly hotplug/unplug virtio disks [RHEL-8] Patch341: kvm-iotests-Make-144-deterministic-again.patch +# For RHEL-19628 - CVE-2023-6683 virt:rhel/qemu-kvm: QEMU: VNC: NULL pointer dereference in qemu_clipboard_request() [rhel-8] +Patch342: kvm-glib-compat-Introduce-g_memdup2-wrapper.patch +# For RHEL-19628 - CVE-2023-6683 virt:rhel/qemu-kvm: QEMU: VNC: NULL pointer dereference in qemu_clipboard_request() [rhel-8] +Patch343: kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch +# For RHEL-19496 - CVE-2023-6693 virt:rhel/qemu-kvm: QEMU: virtio-net: stack buffer overflow in virtio_net_flush_tx() [rhel-8] +Patch344: kvm-virtio-net-correctly-copy-vnet-header-when-flushing-.patch BuildRequires: wget BuildRequires: rpm-build @@ -2010,6 +2016,15 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %changelog +* Thu Mar 14 2024 Jon Maloy - 6.2.0-49 +- kvm-glib-compat-Introduce-g_memdup2-wrapper.patch [RHEL-19628] +- kvm-ui-clipboard-mark-type-as-not-available-when-there-i.patch [RHEL-19628] +- kvm-virtio-net-correctly-copy-vnet-header-when-flushing-.patch [RHEL-19496] +- Resolves: RHEL-19628 + (CVE-2023-6683 virt:rhel/qemu-kvm: QEMU: VNC: NULL pointer dereference in qemu_clipboard_request() [rhel-8]) +- Resolves: RHEL-19496 + (CVE-2023-6693 virt:rhel/qemu-kvm: QEMU: virtio-net: stack buffer overflow in virtio_net_flush_tx() [rhel-8]) + * Mon Feb 26 2024 Miroslav Rezanina - 6.2.0-48 - kvm-iotests-add-filter_qmp_generated_node_ids.patch [RHEL-7353] - kvm-iotests-port-141-to-Python-for-reliable-QMP-testing.patch [RHEL-7353]