From 23c55ec32973e0a75d723e3f37769dd711c9c59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 22 Jul 2020 18:20:14 +0200 Subject: [PATCH xserver] xwayland: Hold a pixmap reference in struct xwl_present_event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the log of the commit below, I claimed this wasn't necessary on the 1.20 branch, but this turned out to be wrong: It meant that event->buffer could already be destroyed in xwl_present_free_event, resulting in use-after-free and likely a crash. Fixes: 22c0808ac88f "xwayland: Free all remaining events in xwl_present_cleanup" Signed-off-by: Michel Dänzer --- hw/xwayland/xwayland-present.c | 17 +++++++++++++---- hw/xwayland/xwayland.h | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index 2cec63f59..f003170a9 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -117,8 +117,16 @@ xwl_present_free_event(struct xwl_present_event *event) if (!event) return; - if (event->buffer) - wl_buffer_set_user_data(event->buffer, NULL); + if (event->pixmap) { + if (!event->buffer_released) { + struct wl_buffer *buffer = + xwl_glamor_pixmap_get_wl_buffer(event->pixmap, NULL); + + wl_buffer_set_user_data(buffer, NULL); + } + + dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id); + } xorg_list_del(&event->list); free(event); @@ -348,7 +356,7 @@ xwl_present_queue_vblank(WindowPtr present_window, return BadAlloc; event->event_id = event_id; - event->buffer = NULL; + event->pixmap = NULL; event->xwl_present_window = xwl_present_window; event->target_msc = msc; @@ -453,11 +461,12 @@ xwl_present_flip(WindowPtr present_window, if (!event) return FALSE; + pixmap->refcnt++; buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created); event->event_id = event_id; event->xwl_present_window = xwl_present_window; - event->buffer = buffer; + event->pixmap = pixmap; event->target_msc = target_msc; event->pending = TRUE; event->abort = FALSE; diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index bc5836ec4..b9495b313 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -215,7 +215,7 @@ struct xwl_present_event { Bool buffer_released; struct xwl_present_window *xwl_present_window; - struct wl_buffer *buffer; + PixmapPtr pixmap; struct xorg_list list; }; -- 2.26.2