[pve-devel] [PATCH qemu 2/2] stable fixes for corner case in i386 emulation and crash with VNC clipboard

Fiona Ebner f.ebner at proxmox.com
Tue Jan 30 15:14:38 CET 2024

Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
 ...sgx_epc_get_section-stub-is-reachabl.patch | 34 ++++++++
 ...k-type-as-not-available-when-there-i.patch | 86 +++++++++++++++++++
 debian/patches/series                         |  2 +
 3 files changed, 122 insertions(+)
 create mode 100644 debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch
 create mode 100644 debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch

diff --git a/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch b/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch
new file mode 100644
index 0000000..194635f
--- /dev/null
+++ b/debian/patches/extra/0008-target-i386-the-sgx_epc_get_section-stub-is-reachabl.patch
@@ -0,0 +1,34 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Tue, 1 Feb 2022 20:09:41 +0100
+Subject: [PATCH] target/i386: the sgx_epc_get_section stub is reachable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+The sgx_epc_get_section stub is reachable from cpu_x86_cpuid.  It
+should not assert, instead it should just return true just like
+the "real" sgx_epc_get_section does when SGX is disabled.
+Reported-by: Vladimír Beneš <vbenes at redhat.com>
+Cc: qemu-stable at nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+Message-ID: <20220201190941.106001-1-pbonzini at redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry-picked from commit 219615740425d9683588207b40a365e6741691a6)
+Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
+ hw/i386/sgx-stub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c
+index 26833eb233..16b1dfd90b 100644
+--- a/hw/i386/sgx-stub.c
++++ b/hw/i386/sgx-stub.c
+@@ -34,5 +34,5 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
+ bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size)
+ {
+-    g_assert_not_reached();
++    return true;
+ }
diff --git a/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch b/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch
new file mode 100644
index 0000000..4b09063
--- /dev/null
+++ b/debian/patches/extra/0009-ui-clipboard-mark-type-as-not-available-when-there-i.patch
@@ -0,0 +1,86 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner at proxmox.com>
+Date: Wed, 24 Jan 2024 11:57:48 +0100
+Subject: [PATCH] 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
+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
+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 at nongnu.org
+Fixes: CVE-2023-6683
+Reported-by: Markus Frank <m.frank at proxmox.com>
+Suggested-by: Marc-André Lureau <marcandre.lureau at redhat.com>
+Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau at redhat.com>
+Tested-by: Markus Frank <m.frank at proxmox.com>
+(picked from https://lists.nongnu.org/archive/html/qemu-stable/2024-01/msg00228.html)
+Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
+ ui/clipboard.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+diff --git a/ui/clipboard.c b/ui/clipboard.c
+index 3d14bffaf8..b3f6fa3c9e 100644
+--- a/ui/clipboard.c
++++ b/ui/clipboard.c
+@@ -163,9 +163,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);
diff --git a/debian/patches/series b/debian/patches/series
index c37e3b9..381ff8c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -5,6 +5,8 @@ extra/0004-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch

More information about the pve-devel mailing list