Skip to content
  • Dmitry Guryanov's avatar
    remove listener from wl_data_source destroy_signal listener list · 2e79c487
    Dmitry Guryanov authored
    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.
    2e79c487