From d18dcecbe08a9ff22e43f12b6b7679a6ef1a6eb0 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 2 Nov 2020 10:24:45 +0100 Subject: [PATCH] xwayland: Clean up pending eglstream on pixmap destroy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EGLStream implementation in Xwayland keeps a list of pending streams for a window. If the windows's pixmap is destroyed while there is a pending stream, the pending stream will point to freed memory once the callback is triggered. Make sure to cancel the pending stream if there's one when the pixmap is destroyed. v2: * Use xorg_list_for_each_entry() instead of the safe variant (Michel Dänzer ) Signed-off-by: Olivier Fourdan Tested-by: Karol Szuster Acked-by: Michel Dänzer Closes https://gitlab.freedesktop.org/xorg/xserver/-/issues/1096 --- hw/xwayland/xwayland-glamor-eglstream.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c index 0bbffd50b..c99d70744 100644 --- a/hw/xwayland/xwayland-glamor-eglstream.c +++ b/hw/xwayland/xwayland-glamor-eglstream.c @@ -298,12 +298,32 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap) free(xwl_pixmap); } +static void +xwl_glamor_eglstream_del_pending_stream_cb(struct xwl_pixmap *xwl_pixmap) +{ + struct xwl_eglstream_private *xwl_eglstream = + xwl_eglstream_get(xwl_pixmap->xwl_screen); + struct xwl_eglstream_pending_stream *pending; + + xorg_list_for_each_entry(pending, + &xwl_eglstream->pending_streams, link) { + if (pending->xwl_pixmap == xwl_pixmap) { + wl_callback_destroy(pending->cb); + xwl_eglstream_window_set_pending(pending->window, NULL); + xorg_list_del(&pending->link); + free(pending); + break; + } + } +} + static Bool xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap) { struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); if (xwl_pixmap && pixmap->refcnt == 1) { + xwl_glamor_eglstream_del_pending_stream_cb(xwl_pixmap); xwl_pixmap_del_buffer_release_cb(pixmap); xwl_eglstream_unref_pixmap_stream(xwl_pixmap); }