weston segfaults if client dies during dnd

Pavel Sterin codeatstake at googlemail.com
Tue Feb 14 04:05:15 PST 2012


Hi! I was playing a little bit with wayland/weston after the 0.85
release, and mixed
up the installation paths making the clients/dnd example crash after
the first click.
While this is not a problem (for the compositor), there is a dangling
pointer in
device->grab->focus.
When I tried to drag a flower out of the dbd client it segfaulted and
crashed, but
afterwards with the mouse button still pressed I moved the mouse further in the
wayland window and then the compositor crashed.

I could track this with valgrind back to weston_device_repick() where it calls
 weston_surface_from_global() on device->grab->focus, which is a
dangling pointer,
that was freed in destroy_surface() after clients death.

==26652== Invalid read of size 4
==26652==    at 0x40635D: weston_surface_update_transform (compositor.c:359)
==26652==    by 0x4066AC: weston_surface_from_global (compositor.c:446)
==26652==    by 0x406BBA: weston_device_repick (compositor.c:579)
==26652==    by 0x408C7B: notify_motion (compositor.c:1376)
==26652==    by 0x609D2A8: x11_compositor_handle_event (compositor-x11.c:611)
==26652==    by 0x4C14EF1: wl_event_loop_dispatch (event-loop.c:462)
==26652==    by 0x4C1343C: wl_display_run (wayland-server.c:785)
==26652==    by 0x40AE19: main (compositor.c:2307)
==26652==  Address 0x7dab838 is 232 bytes inside a block of size 576 free'd
==26652==    at 0x4A0662E: free (vg_replace_malloc.c:366)
==26652==    by 0x406D6D: destroy_surface (compositor.c:634)
==26652==    by 0x4C16A08: wl_map_for_each (wayland-util.c:264)
==26652==    by 0x4C12AB1: wl_client_destroy (wayland-server.c:385)
==26652==    by 0x4C12BF0: wl_client_connection_data (wayland-server.c:247)
==26652==    by 0x4C14EF1: wl_event_loop_dispatch (event-loop.c:462)
==26652==    by 0x4C1343C: wl_display_run (wayland-server.c:785)
==26652==    by 0x40AE19: main (compositor.c:2307)
==26652==


I am new to wayland, but as far as I can see, the following patch can
be the right solution,
I am just no sure, if destroy_surface() is the right spot to do it, as
this would mean to traverse
ALL the input devices for every surface deleted...

diff --git a/src/compositor.c b/src/compositor.c
index ab90ded..9dc3fa6 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -602,6 +602,12 @@ destroy_surface(struct wl_resource *resource)
                             struct weston_surface, surface.resource);
        struct weston_compositor *compositor = surface->compositor;

+       wl_list_for_each(device, &compositor->input_device_list, link) {
+               if (device->input_device.grab->focus == (struct
wl_surface *) surface) {
+                       device->input_device.grab->focus = NULL;
+               }
+       }
+
        if (surface->output) {
                weston_surface_damage_below(surface);
                weston_surface_flush_damage(surface);

best Regards
Pavel


More information about the wayland-devel mailing list