<div dir="ltr"><div><div><div><div><div>Hi Roman,<br><br></div>(sorry for top posting, that's to keep the patch after the message)<br><br></div>So, with that patch I just sent, there is no more access-after-free in unrealize() but as I said intially, ther eiare still acess-after-free in the pending buffers/events, i.e.:<br><br> Invalid read of size 8<br>    at 0x4348A3: xwl_present_buffer_release (xwayland-present.c:134)<br>    by 0x823203D: ffi_call_unix64 (unix64.S:76)<br>    by 0x82319FE: ffi_call (ffi64.c:525)<br>    by 0x56C32DC: wl_closure_invoke (connection.c:996)<br>    by 0x56BFA38: dispatch_event.isra.6 (wayland-client.c:1434)<br>    by 0x56C0F5B: dispatch_queue (wayland-client.c:1580)<br>    by 0x56C0F5B: wl_display_dispatch_queue_pending (wayland-client.c:1822)<br>    by 0x42A83A: xwl_read_events (xwayland.c:800)<br>    by 0x58B5D0: ospoll_wait (ospoll.c:651)<br>    by 0x584E6B: WaitForSomething (WaitFor.c:208)<br>    by 0x5549AF: Dispatch (dispatch.c:421)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br>  Address 0xfcab338 is 104 bytes inside a block of size 184 free'd<br>    at 0x4C2EDAC: free (vg_replace_malloc.c:530)<br>    by 0x42BB78: xwl_unrealize_window (xwayland.c:626)<br>    by 0x541F69: compUnrealizeWindow (compwindow.c:285)<br>    by 0x57E27A: UnrealizeTree (window.c:2816)<br>    by 0x581209: UnmapWindow (window.c:2874)<br>    by 0x54EBA6: ProcUnmapWindow (dispatch.c:879)<br>    by 0x554BFD: Dispatch (dispatch.c:479)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br>  Block was alloc'd at<br>    at 0x4C2FB06: calloc (vg_replace_malloc.c:711)<br>    by 0x42B389: xwl_realize_window (xwayland.c:486)<br>    by 0x541ED9: compRealizeWindow (compwindow.c:268)<br>    by 0x57DAC0: RealizeTree (window.c:2617)<br>    by 0x580BA8: MapWindow (window.c:2694)<br>    by 0x54EAAA: ProcMapWindow (dispatch.c:845)<br>    by 0x554BFD: Dispatch (dispatch.c:479)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br> <br><br>and:<br><br>    at 0x434882: __xorg_list_del (list.h:183)<br>    by 0x434882: xorg_list_del (list.h:204)<br>    by 0x434882: xwl_present_free_event (xwayland-present.c:112)<br>    by 0x434882: xwl_present_buffer_release (xwayland-present.c:138)<br>    by 0x823203D: ffi_call_unix64 (unix64.S:76)<br>    by 0x82319FE: ffi_call (ffi64.c:525)<br>    by 0x56C32DC: wl_closure_invoke (connection.c:996)<br>    by 0x56BFA38: dispatch_event.isra.6 (wayland-client.c:1434)<br>    by 0x56C0F5B: dispatch_queue (wayland-client.c:1580)<br>    by 0x56C0F5B: wl_display_dispatch_queue_pending (wayland-client.c:1822)<br>    by 0x42A83A: xwl_read_events (xwayland.c:800)<br>    by 0x58B5D0: ospoll_wait (ospoll.c:651)<br>    by 0x584E6B: WaitForSomething (WaitFor.c:208)<br>    by 0x5549AF: Dispatch (dispatch.c:421)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br>  Address 0xfcab380 is 176 bytes inside a block of size 184 free'd<br>    at 0x4C2EDAC: free (vg_replace_malloc.c:530)<br>    by 0x42BB78: xwl_unrealize_window (xwayland.c:626)<br>    by 0x541F69: compUnrealizeWindow (compwindow.c:285)<br>    by 0x57E27A: UnrealizeTree (window.c:2816)<br>    by 0x581209: UnmapWindow (window.c:2874)<br>    by 0x54EBA6: ProcUnmapWindow (dispatch.c:879)<br>    by 0x554BFD: Dispatch (dispatch.c:479)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br>  Block was alloc'd at<br>    at 0x4C2FB06: calloc (vg_replace_malloc.c:711)<br>    by 0x42B389: xwl_realize_window (xwayland.c:486)<br>    by 0x541ED9: compRealizeWindow (compwindow.c:268)<br>    by 0x57DAC0: RealizeTree (window.c:2617)<br>    by 0x580BA8: MapWindow (window.c:2694)<br>    by 0x54EAAA: ProcMapWindow (dispatch.c:845)<br>    by 0x554BFD: Dispatch (dispatch.c:479)<br>    by 0x558C65: dix_main (main.c:276)<br>    by 0x79F81BA: (below main) (libc-start.c:308)<br><br></div>That's what I meant by “elaborate from there” in my previous post :)<br><br></div>Cheers,<br></div>Olivier<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 18, 2018 at 3:29 PM, Olivier Fourdan <span dir="ltr"><<a href="mailto:ofourdan@redhat.com" target="_blank">ofourdan@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">xwl_unrealize_window() would use freed xwl_window which can lead to<br>
various memory corruption and crashes, as reported by valgrind:<br>
<br>
 Invalid read of size 8<br>
    at 0x42C802: xwl_present_cleanup (xwayland-present.c:84)<br>
    by 0x42BA67: xwl_unrealize_window (xwayland.c:601)<br>
    by 0x541EE9: compUnrealizeWindow (compwindow.c:285)<br>
    by 0x57E1FA: UnrealizeTree (window.c:2816)<br>
    by 0x581189: UnmapWindow (window.c:2874)<br>
    by 0x54EB26: ProcUnmapWindow (dispatch.c:879)<br>
    by 0x554B7D: Dispatch (dispatch.c:479)<br>
    by 0x558BE5: dix_main (main.c:276)<br>
    by 0x7C4B1BA: (below main) (libc-start.c:308)<br>
  Address 0xf520f60 is 96 bytes inside a block of size 184 free'd<br>
    at 0x4C2EDAC: free (vg_replace_malloc.c:530)<br>
    by 0x42B9FB: xwl_unrealize_window (xwayland.c:624)<br>
    by 0x541EE9: compUnrealizeWindow (compwindow.c:285)<br>
    by 0x57E1FA: UnrealizeTree (window.c:2816)<br>
    by 0x581189: UnmapWindow (window.c:2874)<br>
    by 0x54EB26: ProcUnmapWindow (dispatch.c:879)<br>
    by 0x554B7D: Dispatch (dispatch.c:479)<br>
    by 0x558BE5: dix_main (main.c:276)<br>
    by 0x7C4B1BA: (below main) (libc-start.c:308)<br>
  Block was alloc'd at<br>
    at 0x4C2FB06: calloc (vg_replace_malloc.c:711)<br>
    by 0x42B307: xwl_realize_window (xwayland.c:488)<br>
    by 0x541E59: compRealizeWindow (compwindow.c:268)<br>
    by 0x57DA40: RealizeTree (window.c:2617)<br>
    by 0x580B28: MapWindow (window.c:2694)<br>
    by 0x54EA2A: ProcMapWindow (dispatch.c:845)<br>
    by 0x554B7D: Dispatch (dispatch.c:479)<br>
    by 0x558BE5: dix_main (main.c:276)<br>
    by 0x7C4B1BA: (below main) (libc-start.c:308)<br>
<br>
This is because UnrealizeTree() traverses the tree from top to bottom,<br>
which invalidates the assumption that if the Window doesn't feature an<br>
xwl_window on its own, it's the xwl_window of its first ancestor with<br>
one.<br>
<br>
This partially revert commit 82df2ce3<br>
<br>
Signed-off-by: Olivier Fourdan <<a href="mailto:ofourdan@redhat.com">ofourdan@redhat.com</a>><br>
---<br>
 hw/xwayland/xwayland-input.c   |  2 +-<br>
 hw/xwayland/xwayland-present.c | 22 +++++--------<br>
 hw/xwayland/xwayland.c         | 60 ++++++++++++++++--------------<wbr>----<br>
 hw/xwayland/xwayland.h         |  4 +--<br>
 4 files changed, 40 insertions(+), 48 deletions(-)<br>
<br>
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c<br>
index 74a2579f7..0a37f97bd 100644<br>
--- a/hw/xwayland/xwayland-input.c<br>
+++ b/hw/xwayland/xwayland-input.c<br>
@@ -1067,7 +1067,7 @@ xwl_keyboard_activate_grab(<wbr>DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bo<br>
         if (xwl_seat == NULL)<br>
             xwl_seat = find_matching_seat(device);<br>
         if (xwl_seat)<br>
-            set_grab(xwl_seat, xwl_window_of_top(grab-><wbr>window));<br>
+            set_grab(xwl_seat, xwl_window_from_window(grab-><wbr>window));<br>
     }<br>
<br>
     ActivateKeyboardGrab(device, grab, time, passive);<br>
diff --git a/hw/xwayland/xwayland-<wbr>present.c b/hw/xwayland/xwayland-<wbr>present.c<br>
index f403ff701..62c70a820 100644<br>
--- a/hw/xwayland/xwayland-<wbr>present.c<br>
+++ b/hw/xwayland/xwayland-<wbr>present.c<br>
@@ -73,13 +73,9 @@ xwl_present_reset_timer(struct xwl_window *xwl_window)<br>
 }<br>
<br>
 void<br>
-xwl_present_cleanup(WindowPtr window)<br>
+xwl_present_cleanup(struct xwl_window *xwl_window, WindowPtr window)<br>
 {<br>
-    struct xwl_window           *xwl_window = xwl_window_of_top(window);<br>
-    struct xwl_present_event    *event, *tmp;<br>
-<br>
-    if (!xwl_window)<br>
-        return;<br>
+    struct xwl_present_event *event, *tmp;<br>
<br>
     if (xwl_window->present_window == window) {<br>
         if (xwl_window->present_frame_<wbr>callback) {<br>
@@ -258,7 +254,7 @@ static const struct wl_callback_listener xwl_present_sync_listener = {<br>
 static RRCrtcPtr<br>
 xwl_present_get_crtc(WindowPtr present_window)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
     if (xwl_window == NULL)<br>
         return NULL;<br>
<br>
@@ -268,7 +264,7 @@ xwl_present_get_crtc(WindowPtr present_window)<br>
 static int<br>
 xwl_present_get_ust_msc(<wbr>WindowPtr present_window, uint64_t *ust, uint64_t *msc)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
     if (!xwl_window)<br>
         return BadAlloc;<br>
     *ust = xwl_window->present_ust;<br>
@@ -297,7 +293,7 @@ xwl_present_queue_vblank(<wbr>WindowPtr present_window,<br>
                          uint64_t event_id,<br>
                          uint64_t msc)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
     struct xwl_present_event *event;<br>
<br>
     if (!xwl_window)<br>
@@ -337,7 +333,7 @@ xwl_present_abort_vblank(<wbr>WindowPtr present_window,<br>
                          uint64_t event_id,<br>
                          uint64_t msc)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
     struct xwl_present_event *event, *tmp;<br>
<br>
     if (!xwl_window)<br>
@@ -374,7 +370,7 @@ xwl_present_check_flip2(<wbr>RRCrtcPtr crtc,<br>
                         Bool sync_flip,<br>
                         PresentFlipReason *reason)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
<br>
     if (!xwl_window)<br>
         return FALSE;<br>
@@ -415,7 +411,7 @@ xwl_present_flip(WindowPtr present_window,<br>
                  Bool sync_flip,<br>
                  RegionPtr damage)<br>
 {<br>
-    struct xwl_window           *xwl_window = xwl_window_of_top(present_<wbr>window);<br>
+    struct xwl_window           *xwl_window = xwl_window_from_window(<wbr>present_window);<br>
     BoxPtr                      present_box, damage_box;<br>
     Bool                        buffer_created;<br>
     struct wl_buffer            *buffer;<br>
@@ -485,7 +481,7 @@ xwl_present_flip(WindowPtr present_window,<br>
 static void<br>
 xwl_present_flips_stop(<wbr>WindowPtr window)<br>
 {<br>
-    struct xwl_window *xwl_window = xwl_window_of_top(window);<br>
+    struct xwl_window *xwl_window = xwl_window_from_window(window)<wbr>;<br>
<br>
     if (!xwl_window)<br>
         return;<br>
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c<br>
index 44bbc3b18..72493285e 100644<br>
--- a/hw/xwayland/xwayland.c<br>
+++ b/hw/xwayland/xwayland.c<br>
@@ -122,21 +122,10 @@ static DevPrivateKeyRec xwl_window_private_key;<br>
 static DevPrivateKeyRec xwl_screen_private_key;<br>
 static DevPrivateKeyRec xwl_pixmap_private_key;<br>
<br>
-struct xwl_window *<br>
-xwl_window_of_top(WindowPtr window)<br>
-{<br>
-    return dixLookupPrivate(&window-><wbr>devPrivates, &xwl_window_private_key);<br>
-}<br>
-<br>
 static struct xwl_window *<br>
-xwl_window_of_self(WindowPtr window)<br>
+xwl_window_get(WindowPtr window)<br>
 {<br>
-    struct xwl_window *xwl_window = dixLookupPrivate(&window-><wbr>devPrivates, &xwl_window_private_key);<br>
-<br>
-    if (xwl_window && xwl_window->window == window)<br>
-        return xwl_window;<br>
-    else<br>
-        return  NULL;<br>
+    return dixLookupPrivate(&window-><wbr>devPrivates, &xwl_window_private_key);<br>
 }<br>
<br>
 struct xwl_screen *<br>
@@ -223,7 +212,7 @@ xwl_property_callback(<wbr>CallbackListPtr *pcbl, void *closure,<br>
     if (rec->win->drawable.pScreen != screen)<br>
         return;<br>
<br>
-    xwl_window = xwl_window_of_self(rec->win);<br>
+    xwl_window = xwl_window_get(rec->win);<br>
     if (!xwl_window)<br>
         return;<br>
<br>
@@ -262,6 +251,22 @@ xwl_close_screen(ScreenPtr screen)<br>
     return screen->CloseScreen(screen);<br>
 }<br>
<br>
+struct xwl_window *<br>
+xwl_window_from_window(<wbr>WindowPtr window)<br>
+{<br>
+    struct xwl_window *xwl_window;<br>
+<br>
+    while (window) {<br>
+        xwl_window = xwl_window_get(window);<br>
+        if (xwl_window)<br>
+            return xwl_window;<br>
+<br>
+        window = window->parent;<br>
+    }<br>
+<br>
+    return NULL;<br>
+}<br>
+<br>
 static struct xwl_seat *<br>
 xwl_screen_get_default_seat(<wbr>struct xwl_screen *xwl_screen)<br>
 {<br>
@@ -292,7 +297,7 @@ xwl_cursor_warped_to(<wbr>DeviceIntPtr device,<br>
     if (!window)<br>
         window = XYToWindow(sprite, x, y);<br>
<br>
-    xwl_window = xwl_window_of_top(window);<br>
+    xwl_window = xwl_window_from_window(window)<wbr>;<br>
     if (!xwl_window && xwl_seat->focus_window) {<br>
         focus = xwl_seat->focus_window-><wbr>window;<br>
<br>
@@ -339,7 +344,7 @@ xwl_cursor_confined_to(<wbr>DeviceIntPtr device,<br>
         return;<br>
     }<br>
<br>
-    xwl_window = xwl_window_of_top(window);<br>
+    xwl_window = xwl_window_from_window(window)<wbr>;<br>
     if (!xwl_window && xwl_seat->focus_window) {<br>
         /* Allow confining on InputOnly windows, but only if the geometry<br>
          * is the same than the focus window.<br>
@@ -455,7 +460,6 @@ xwl_realize_window(WindowPtr window)<br>
     struct xwl_screen *xwl_screen;<br>
     struct xwl_window *xwl_window;<br>
     struct wl_region *region;<br>
-    Bool create_xwl_window = TRUE;<br>
     Bool ret;<br>
<br>
     xwl_screen = xwl_screen_get(screen);<br>
@@ -475,17 +479,11 @@ xwl_realize_window(WindowPtr window)<br>
<br>
     if (xwl_screen->rootless) {<br>
         if (window->redirectDraw != RedirectDrawManual)<br>
-            create_xwl_window = FALSE;<br>
+            return ret;<br>
     }<br>
     else {<br>
         if (window->parent)<br>
-            create_xwl_window = FALSE;<br>
-    }<br>
-<br>
-    if (!create_xwl_window) {<br>
-        if (window->parent)<br>
-            dixSetPrivate(&window-><wbr>devPrivates, &xwl_window_private_key, xwl_window_of_top(window-><wbr>parent));<br>
-        return ret;<br>
+            return ret;<br>
     }<br>
<br>
     xwl_window = calloc(1, sizeof *xwl_window);<br>
@@ -602,9 +600,9 @@ xwl_unrealize_window(WindowPtr window)<br>
     compUnredirectWindow(<wbr>serverClient, window, CompositeRedirectManual);<br>
<br>
 #ifdef GLAMOR_HAS_GBM<br>
-    if (xwl_screen->present)<br>
-        /* Always cleanup Present (Present might have been active on child window) */<br>
-        xwl_present_cleanup(window);<br>
+    xwl_window = xwl_window_from_window(window)<wbr>;<br>
+    if (xwl_window && xwl_screen->present)<br>
+        xwl_present_cleanup(xwl_<wbr>window, window);<br>
 #endif<br>
<br>
     screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;<br>
@@ -612,11 +610,9 @@ xwl_unrealize_window(WindowPtr window)<br>
     xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;<br>
     screen->UnrealizeWindow = xwl_unrealize_window;<br>
<br>
-    xwl_window = xwl_window_of_self(window);<br>
-    if (!xwl_window) {<br>
-        dixSetPrivate(&window-><wbr>devPrivates, &xwl_window_private_key, NULL);<br>
+    xwl_window = xwl_window_get(window);<br>
+    if (!xwl_window)<br>
         return ret;<br>
-    }<br>
<br>
     wl_surface_destroy(xwl_window-<wbr>>surface);<br>
     xorg_list_del(&xwl_window-><wbr>link_damage);<br>
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h<br>
index cf2551b99..11a9f4816 100644<br>
--- a/hw/xwayland/xwayland.h<br>
+++ b/hw/xwayland/xwayland.h<br>
@@ -361,7 +361,7 @@ RRModePtr xwayland_cvt(int HDisplay, int VDisplay,<br>
 void xwl_pixmap_set_private(<wbr>PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);<br>
 struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);<br>
<br>
-struct xwl_window *xwl_window_of_top(WindowPtr window);<br>
+struct xwl_window *xwl_window_from_window(<wbr>WindowPtr window);<br>
<br>
 Bool xwl_shm_create_screen_<wbr>resources(ScreenPtr screen);<br>
 PixmapPtr xwl_shm_create_pixmap(<wbr>ScreenPtr screen, int width, int height,<br>
@@ -383,7 +383,7 @@ struct wl_buffer *xwl_glamor_pixmap_get_wl_<wbr>buffer(PixmapPtr pixmap,<br>
<br>
 #ifdef GLAMOR_HAS_GBM<br>
 Bool xwl_present_init(ScreenPtr screen);<br>
-void xwl_present_cleanup(WindowPtr window);<br>
+void xwl_present_cleanup(struct xwl_window *xwl_window, WindowPtr window);<br>
 #endif<br>
<br>
 void xwl_screen_release_tablet_<wbr>manager(struct xwl_screen *xwl_screen);<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.17.0<br>
<br>
</font></span></blockquote></div><br></div>