diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2022-03-11 12:03:06 +0100 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2022-03-15 10:25:46 +0100 |
commit | fdbfda85c7c76e6aa60b9907fb7a9887ee07b8b8 (patch) | |
tree | 7abfc6e78344184c108d1d2ee8dfbb157117a302 | |
parent | 00530769f7a968447b75e8375a503a6f6fcc1e7e (diff) | |
download | xserver-fdbfda85c7c76e6aa60b9907fb7a9887ee07b8b8.tar.gz |
xwayland/present: Fix use-after-free in xwl_unrealize_window()
When a window is unrealized, Xwayland would destroy the Wayland surface
prior to unrealizing the present window.
xwl_present_flip() will then do a wl_surface_commit() of that surface,
hence causing a use-after-free:
Invalid read of size 8
at 0x49F7FD4: wl_proxy_marshal_array_flags (wayland-client.c:852)
by 0x49F823A: wl_proxy_marshal_flags (wayland-client.c:784)
by 0x42B877: wl_surface_commit (wayland-client-protocol.h:3914)
by 0x42CAA7: xwl_present_flip (xwayland-present.c:717)
by 0x42CD0E: xwl_present_execute (xwayland-present.c:783)
by 0x42C26D: xwl_present_msc_bump (xwayland-present.c:416)
by 0x42C2D1: xwl_present_timer_callback (xwayland-present.c:433)
by 0x42BAC4: xwl_present_reset_timer (xwayland-present.c:149)
by 0x42D1F8: xwl_present_unrealize_window (xwayland-present.c:945)
by 0x4230E2: xwl_unrealize_window (xwayland-window.c:616)
by 0x4FCDD8: compUnrealizeWindow (compwindow.c:292)
by 0x4F3F5C: UnrealizeTree (window.c:2805)
Address 0x1390b8d8 is 24 bytes inside a block of size 80 free'd
at 0x48470E4: free (vg_replace_malloc.c:872)
by 0x49F8029: wl_proxy_destroy_caller_locks (wayland-client.c:523)
by 0x49F8029: wl_proxy_marshal_array_flags (wayland-client.c:861)
by 0x49F823A: wl_proxy_marshal_flags (wayland-client.c:784)
by 0x421984: wl_surface_destroy (wayland-client-protocol.h:3672)
by 0x423052: xwl_unrealize_window (xwayland-window.c:599)
by 0x4FCDD8: compUnrealizeWindow (compwindow.c:292)
by 0x4F3F5C: UnrealizeTree (window.c:2805)
by 0x4F424B: UnmapWindow (window.c:2863)
by 0x4EF58C: DeleteWindow (window.c:1075)
by 0x4E24B3: doFreeResource (resource.c:885)
by 0x4E2ED7: FreeClientResources (resource.c:1151)
by 0x4ACBA4: CloseDownClient (dispatch.c:3546)
Block was alloc'd at
at 0x4849464: calloc (vg_replace_malloc.c:1328)
by 0x49F7F29: zalloc (wayland-private.h:233)
by 0x49F7F29: proxy_create (wayland-client.c:422)
by 0x49F7F29: create_outgoing_proxy (wayland-client.c:664)
by 0x49F7F29: wl_proxy_marshal_array_flags (wayland-client.c:831)
by 0x49F823A: wl_proxy_marshal_flags (wayland-client.c:784)
by 0x4218CA: wl_compositor_create_surface (wayland-client-protocol.h:1291)
by 0x422A0D: ensure_surface_for_window (xwayland-window.c:445)
by 0x4231E8: xwl_window_set_window_pixmap (xwayland-window.c:647)
by 0x5232D6: damageSetWindowPixmap (damage.c:1565)
by 0x4FC7BC: compSetPixmapVisitWindow (compwindow.c:129)
by 0x4EDB3F: TraverseTree (window.c:441)
by 0x4FC851: compSetPixmap (compwindow.c:151)
by 0x4F8C1A: compAllocPixmap (compalloc.c:616)
by 0x4FC938: compCheckRedirect (compwindow.c:174)
To avoid that, call xwl_present_unrealize_window() before destroying the
Wayland surface.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 42113ab2894251376b2beab7e68f2705f5ce1084)
-rw-r--r-- | hw/xwayland/xwayland-window.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index 152b4d0a6..92bcae326 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -605,16 +605,6 @@ xwl_unrealize_window(WindowPtr window) if (xwl_window_has_viewport_enabled(xwl_window)) xwl_window_disable_viewport(xwl_window); - wl_surface_destroy(xwl_window->surface); - xorg_list_del(&xwl_window->link_damage); - xorg_list_del(&xwl_window->link_window); - unregister_damage(window); - - xwl_window_buffers_dispose(xwl_window); - - if (xwl_window->frame_callback) - wl_callback_destroy(xwl_window->frame_callback); - #ifdef GLAMOR_HAS_GBM if (xwl_screen->present) { struct xwl_present_window *xwl_present_window, *tmp; @@ -627,6 +617,16 @@ xwl_unrealize_window(WindowPtr window) } #endif + wl_surface_destroy(xwl_window->surface); + xorg_list_del(&xwl_window->link_damage); + xorg_list_del(&xwl_window->link_window); + unregister_damage(window); + + xwl_window_buffers_dispose(xwl_window); + + if (xwl_window->frame_callback) + wl_callback_destroy(xwl_window->frame_callback); + free(xwl_window); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); |