From nobody Sat Nov 23 21:32:06 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1731147837687906.5019984758968; Sat, 9 Nov 2024 02:23:57 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9iXf-0008Gf-4N; Sat, 09 Nov 2024 05:18:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9iVZ-0004xC-Io; Sat, 09 Nov 2024 05:15:58 -0500 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9iVX-0007q6-QL; Sat, 09 Nov 2024 05:15:57 -0500 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id F1D84A13F4; Sat, 9 Nov 2024 13:13:49 +0300 (MSK) Received: from think4mjt.tls.msk.ru (mjtthink.wg.tls.msk.ru [192.168.177.146]) by tsrv.corpit.ru (Postfix) with ESMTP id 9F22C167EE0; Sat, 9 Nov 2024 13:14:44 +0300 (MSK) From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Akihiko Odaki , Michael Tokarev Subject: [Stable-8.2.8 16/49] ui/win32: fix potential use-after-free with dbus shared memory Date: Sat, 9 Nov 2024 13:14:07 +0300 Message-Id: <20241109101443.312701-16-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.5 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1731147838483116600 From: Marc-Andr=C3=A9 Lureau 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=C3=A9 Lureau Reviewed-by: Akihiko Odaki Message-ID: <20241008125028.1177932-5-marcandre.lureau@redhat.com> (cherry picked from commit 330ef31deb2e5461cff907488b710f5bd9cd2327) Signed-off-by: Michael Tokarev diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index a7b16ba072..746160a175 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; } =20 -#ifdef WIN32 -static void -win32_pixman_image_destroy(pixman_image_t *image, void *data) -{ - HANDLE handle =3D 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_ima= ge_destroy, res->handle); + pixman_image_set_destroy_function(res->image, qemu_pixman_win3= 2_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_d= estroy, res->handle); + pixman_image_set_destroy_function(res->image, qemu_pixman_win32_im= age_destroy, res->handle); #endif =20 res->addrs =3D g_new(uint64_t, res->iov_cnt); diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index ef13a8210c..e3dd72b9e3 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, =20 void qemu_pixman_image_unref(pixman_image_t *image); =20 +void qemu_pixman_win32_image_destroy(pixman_image_t *image, void *data); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref) =20 #endif /* QEMU_PIXMAN_H */ diff --git a/ui/console.c b/ui/console.c index 832055675c..c462b8f228 100644 --- a/ui/console.c +++ b/ui/console.c @@ -504,24 +504,6 @@ void qemu_displaysurface_win32_set_handle(DisplaySurfa= ce *surface, surface->handle =3D h; surface->handle_offset =3D offset; } - -static void -win32_pixman_image_destroy(pixman_image_t *image, void *data) -{ - DisplaySurface *surface =3D data; - - if (!surface->handle) { - return; - } - - assert(surface->handle_offset =3D=3D 0); - - qemu_win32_map_free( - pixman_image_get_data(surface->image), - surface->handle, - &error_warn - ); -} #endif =20 DisplaySurface *qemu_create_displaysurface(int width, int height) @@ -547,6 +529,8 @@ DisplaySurface *qemu_create_displaysurface(int width, i= nt height) =20 #ifdef WIN32 qemu_displaysurface_win32_set_handle(surface, handle, 0); + pixman_image_set_destroy_function(surface->image, + qemu_pixman_win32_image_destroy, han= dle); #endif return surface; } @@ -562,10 +546,6 @@ DisplaySurface *qemu_create_displaysurface_from(int wi= dth, int height, width, height, (void *)data, linesize); assert(surface->image !=3D NULL); -#ifdef WIN32 - pixman_image_set_destroy_function(surface->image, - win32_pixman_image_destroy, surface); -#endif =20 return surface; } diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c index 5ca55dd199..de6c88151c 100644 --- a/ui/qemu-pixman.c +++ b/ui/qemu-pixman.c @@ -4,6 +4,7 @@ */ =20 #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 =3D data; + + qemu_win32_map_free( + pixman_image_get_data(image), + handle, + &error_warn + ); +} +#endif --=20 2.39.5