mirror of
https://github.com/Motorhead1991/qemu.git
synced 2026-01-06 22:47:41 -07:00
ui/win32: fix potential use-after-free with dbus shared memory
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 <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241008125028.1177932-5-marcandre.lureau@redhat.com>
(cherry picked from commit 330ef31deb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
parent
9391f419c7
commit
e1324ec946
4 changed files with 21 additions and 34 deletions
|
|
@ -238,16 +238,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)
|
||||
{
|
||||
|
|
@ -308,7 +298,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
|
||||
}
|
||||
|
|
@ -1327,7 +1317,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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
24
ui/console.c
24
ui/console.c
|
|
@ -461,24 +461,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)
|
||||
|
|
@ -504,6 +486,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;
|
||||
}
|
||||
|
|
@ -519,10 +503,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue