xwayland: Force disposal of windows buffers for root on destroy

With explicit buffer synchronization in use, the window buffers use a
file descriptor for event notification to keep the buffer alive for
synchronization purpose.

When running rootful, the root window (which is visible) is destroyed
directly from the resource manager on server reset, and the window
buffer's eventfd will trigger after the window is destroyed, leading to
a use after free and a crash of the xserver.

To avoid the issue, check whether the window being destroyed is the root
window in rootless mode, and make sure to force the disposal of the
window buffers in that case.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1699
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1589>
This commit is contained in:
Olivier Fourdan 2024-07-02 18:54:10 +02:00 committed by Marge Bot
parent fa04e15afc
commit a5e863963e

View File

@ -1649,6 +1649,7 @@ xwl_window_dispose(struct xwl_window *xwl_window)
struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
struct xwl_seat *xwl_seat; struct xwl_seat *xwl_seat;
WindowPtr window = xwl_window->toplevel; WindowPtr window = xwl_window->toplevel;
ScreenPtr screen = xwl_screen->screen;
compUnredirectWindow(serverClient, window, CompositeRedirectManual); compUnredirectWindow(serverClient, window, CompositeRedirectManual);
@ -1691,7 +1692,9 @@ xwl_window_dispose(struct xwl_window *xwl_window)
xorg_list_del(&xwl_window->link_damage); xorg_list_del(&xwl_window->link_damage);
xorg_list_del(&xwl_window->link_window); xorg_list_del(&xwl_window->link_window);
xwl_window_buffers_dispose(xwl_window, FALSE); /* Special case for the root window in rootful mode */
xwl_window_buffers_dispose(xwl_window,
(!xwl_screen->rootless && window == screen->root));
if (xwl_window->window_buffers_timer) if (xwl_window->window_buffers_timer)
TimerFree(xwl_window->window_buffers_timer); TimerFree(xwl_window->window_buffers_timer);