diff --git a/1059-fix-potential-use-after-free-with-dbus-shared-memory.patch b/1059-fix-potential-use-after-free-with-dbus-shared-memory.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7b995d918f3245785dd4fe4d6b2879a7fd799f5 --- /dev/null +++ b/1059-fix-potential-use-after-free-with-dbus-shared-memory.patch @@ -0,0 +1,167 @@ +From 5910eb9d0a7d42bb73c271a79a738108831a2ad3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 8 Oct 2024 16:50:13 +0400 +Subject: [PATCH] ui/win32: fix potential use-after-free with dbus shared + memory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +DisplaySurface may be free before the pixman image is freed, since the +image is refcounted and used by different objects, including pending +dbus messages. + +Furthermore, setting the destroy function in +create_displaysurface_from() isn't appropriate, as it may not be used, +and may be overriden as in ramfb. + +Set the destroy function when the shared handle is set, use the HANDLE +directly for destroy data, using a single common helper +qemu_pixman_win32_image_destroy(). + +Signed-off-by: Marc-André Lureau +Reviewed-by: Akihiko Odaki +Message-ID: <20241008125028.1177932-5-marcandre.lureau@redhat.com> +(cherry picked from commit 330ef31deb2e5461cff907488b710f5bd9cd2327) +Signed-off-by: Michael Tokarev +--- + hw/display/virtio-gpu.c | 14 ++------------ + include/ui/qemu-pixman.h | 2 ++ + ui/console.c | 24 ++---------------------- + ui/qemu-pixman.c | 15 +++++++++++++++ + 4 files changed, 21 insertions(+), 34 deletions(-) + +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index a7b16ba072e..746160a1758 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -239,16 +239,6 @@ static uint32_t calc_image_hostmem(pixman_format_code_t pformat, + return height * stride; + } + +-#ifdef WIN32 +-static void +-win32_pixman_image_destroy(pixman_image_t *image, void *data) +-{ +- HANDLE handle = data; +- +- qemu_win32_map_free(pixman_image_get_data(image), handle, &error_warn); +-} +-#endif +- + static void virtio_gpu_resource_create_2d(VirtIOGPU *g, + struct virtio_gpu_ctrl_command *cmd) + { +@@ -309,7 +299,7 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g, + bits, c2d.height ? res->hostmem / c2d.height : 0); + #ifdef WIN32 + if (res->image) { +- pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle); ++ pixman_image_set_destroy_function(res->image, qemu_pixman_win32_image_destroy, res->handle); + } + #endif + } +@@ -1303,7 +1293,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, + return -EINVAL; + } + #ifdef WIN32 +- pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle); ++ pixman_image_set_destroy_function(res->image, qemu_pixman_win32_image_destroy, res->handle); + #endif + + res->addrs = g_new(uint64_t, res->iov_cnt); +diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h +index ef13a8210cc..e3dd72b9e38 100644 +--- a/include/ui/qemu-pixman.h ++++ b/include/ui/qemu-pixman.h +@@ -97,6 +97,8 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph, + + void qemu_pixman_image_unref(pixman_image_t *image); + ++void qemu_pixman_win32_image_destroy(pixman_image_t *image, void *data); ++ + G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref) + + #endif /* QEMU_PIXMAN_H */ +diff --git a/ui/console.c b/ui/console.c +index 832055675c5..c462b8f2280 100644 +--- a/ui/console.c ++++ b/ui/console.c +@@ -504,24 +504,6 @@ void qemu_displaysurface_win32_set_handle(DisplaySurface *surface, + surface->handle = h; + surface->handle_offset = offset; + } +- +-static void +-win32_pixman_image_destroy(pixman_image_t *image, void *data) +-{ +- DisplaySurface *surface = data; +- +- if (!surface->handle) { +- return; +- } +- +- assert(surface->handle_offset == 0); +- +- qemu_win32_map_free( +- pixman_image_get_data(surface->image), +- surface->handle, +- &error_warn +- ); +-} + #endif + + DisplaySurface *qemu_create_displaysurface(int width, int height) +@@ -547,6 +529,8 @@ DisplaySurface *qemu_create_displaysurface(int width, int height) + + #ifdef WIN32 + qemu_displaysurface_win32_set_handle(surface, handle, 0); ++ pixman_image_set_destroy_function(surface->image, ++ qemu_pixman_win32_image_destroy, handle); + #endif + return surface; + } +@@ -562,10 +546,6 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height, + width, height, + (void *)data, linesize); + assert(surface->image != NULL); +-#ifdef WIN32 +- pixman_image_set_destroy_function(surface->image, +- win32_pixman_image_destroy, surface); +-#endif + + return surface; + } +diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c +index 5ca55dd1998..de6c88151c2 100644 +--- a/ui/qemu-pixman.c ++++ b/ui/qemu-pixman.c +@@ -4,6 +4,7 @@ + */ + + #include "qemu/osdep.h" ++#include "qapi/error.h" + #include "ui/console.h" + #include "standard-headers/drm/drm_fourcc.h" + #include "trace.h" +@@ -268,3 +269,17 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph, + pixman_image_unref(ibg); + } + #endif /* CONFIG_PIXMAN */ ++ ++#ifdef WIN32 ++void ++qemu_pixman_win32_image_destroy(pixman_image_t *image, void *data) ++{ ++ HANDLE handle = data; ++ ++ qemu_win32_map_free( ++ pixman_image_get_data(image), ++ handle, ++ &error_warn ++ ); ++} ++#endif +-- +GitLab + diff --git a/qemu.spec b/qemu.spec index 69a317305277abba51d0e6cb4c2bcf3326069a72..a5dd2f122d0f8408aa5bbcdea487d794f6856e7a 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,4 +1,4 @@ -%define anolis_release 18 +%define anolis_release 19 %bcond_with check @@ -369,6 +369,9 @@ Patch1056: 0002-CVE-2023-6693.patch Patch1057: 0003-CVE-2024-26327.patch Patch1058: 1058-fix-CVE-2024-3446.patch +# https://gitlab.com/qemu-project/qemu/-/commit/5910eb9d0a7d42bb73c271a79a738108831a2ad3 +Patch1059: 1059-fix-potential-use-after-free-with-dbus-shared-memory.patch + ExclusiveArch: x86_64 aarch64 loongarch64 BuildRequires: meson >= %{meson_version}