summaryrefslogtreecommitdiffstats
path: root/src/data-device.c
diff options
context:
space:
mode:
authorDmitry Guryanov <dmitry.guryanov@gmail.com>2012-07-17 18:56:03 +0400
committerKristian Høgsberg <krh@bitplanet.net>2012-07-17 16:54:07 -0400
commit2e79c4877fc4f402297e9d685b5eb2c41d7dd814 (patch)
treeb087a70849b132b6bb3346da688d88d42bf1fe80 /src/data-device.c
parentcursor: fix fd leak and a segfault (diff)
downloadwayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar.gz
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar.bz2
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar.lz
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar.xz
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.tar.zst
wayland-2e79c4877fc4f402297e9d685b5eb2c41d7dd814.zip
remove listener from wl_data_source destroy_signal listener list
I've found a bug during wayland exploration - if you make two drag'n'drops in weston client example, dnd - weston crashes with segfault. I've tried to investigate it and found a problem. In function drag_grab_button we first call data_device_end_drag_grab, which sets seat->drag_data_source to NULL. Then we remove listener from list only if drag_data_source is not NULL. So if client will not free wl_data_source and start another drag'n'drop, after the first one. Then two wl_data_source structures will be free'd on client exit (let's name them s1 and s2). next and prev pointer of wl_data_source.resource.destroy_signal.listener_list in both wl_data_source structures will be seat->drag_data_source_listener, but next and prev in seat->drag_data_source_listener.link point to listener_list in s2. So if you try to iterate over listener_list in s1 then you get drag_data_source_listener as first item and (struct wl_listener *)(&s2.resource.destroy_signal.listener_list) Iteration over that list occurs in wl_resource_destroy->destroy_resource->wl_signal_emit->wl_signal_emit and try to call function at address of wl_resource->client, so weston segfaults there.
Diffstat (limited to 'src/data-device.c')
-rw-r--r--src/data-device.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/data-device.c b/src/data-device.c
index 67ae41f..82020af 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -265,9 +265,9 @@ drag_grab_button(struct wl_pointer_grab *grab,
if (seat->pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
- data_device_end_drag_grab(seat);
if (seat->drag_data_source)
wl_list_remove(&seat->drag_data_source_listener.link);
+ data_device_end_drag_grab(seat);
}
}