[PATCH weston] xwm: fix use after free
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Jan 29 09:17:31 PST 2015
2015-01-28 5:29 GMT+02:00 Bryce Harrington <bryce at osg.samsung.com>:
> On Fri, Dec 26, 2014 at 06:10:35PM +0200, Giulio Camuffo wrote:
>> Calling wl_event_source_remove() will free the event source later, so
>> reset the pointer to avoid calling it two times on the same pointer.
>> Fix a compositor crash when copying some text from weston terminal,
>> pasting it in the same terminal and hitting ctrl-u, while a X client
>> is running.
>> ---
>> xwayland/selection.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>
> Looking at wl_event_source_remove(), I definitely see what you mean
> about it delaying the free's.
>
> Verifying the pointer does eventually get freed is a bit tricky but I
> think I understand it: wl_event_source_remove() adds source->link to the
> loop->destroy_list, then later on this list is processed by a C macro:
>
> wl_list_for_each_safe(source, next, &loop->destroy_list, link)
> free(source);
>
> This uses wl_container_of() on the link stored in destroy_list to find
> its parent container, source, and then frees it.
>
> So, presuming my understanding of the logic is correct:
That is my understanding as well.
>
> Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
>
>> diff --git a/xwayland/selection.c b/xwayland/selection.c
>> index b694477..24bd56d 100644
>> --- a/xwayland/selection.c
>> +++ b/xwayland/selection.c
>> @@ -46,6 +46,7 @@ writable_callback(int fd, uint32_t mask, void *data)
>> wm->property_reply = NULL;
>> if (wm->property_source)
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> close(fd);
>> weston_log("write error to target fd: %m\n");
>> return 1;
>> @@ -61,6 +62,7 @@ writable_callback(int fd, uint32_t mask, void *data)
>> wm->property_reply = NULL;
>> if (wm->property_source)
>> wl_event_source_remove(wm->property_source);
>
> If we need to check wm->property_source before calling
> wl_event_source_remove(), shouldn't this also be done for the subsequent
> calls as well?
No, because the calls below are all inside
weston_wm_read_data_source(), which is the handler of
wm->property_source. So inside there we know that the source is valid
and we can freely destroy it without checking. But in the function
above we cannot do that assumption.
--
Giulio
>
>> + wm->property_source = NULL;
>>
>> if (wm->incr) {
>> xcb_delete_property(wm->conn,
>> @@ -352,6 +354,7 @@ weston_wm_read_data_source(int fd, uint32_t mask, void *data)
>> weston_log("read error from data source: %m\n");
>> weston_wm_send_selection_notify(wm, XCB_ATOM_NONE);
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> close(fd);
>> wl_array_release(&wm->source_data);
>> }
>> @@ -375,6 +378,7 @@ weston_wm_read_data_source(int fd, uint32_t mask, void *data)
>> wm->selection_property_set = 1;
>> wm->flush_property_on_delete = 1;
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> weston_wm_send_selection_notify(wm, wm->selection_request.property);
>> } else if (wm->selection_property_set) {
>> weston_log("got %zu bytes, waiting for "
>> @@ -382,6 +386,7 @@ weston_wm_read_data_source(int fd, uint32_t mask, void *data)
>>
>> wm->flush_property_on_delete = 1;
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> } else {
>> weston_log("got %zu bytes, "
>> "property deleted, seting new property\n",
>> @@ -395,6 +400,7 @@ weston_wm_read_data_source(int fd, uint32_t mask, void *data)
>> weston_wm_send_selection_notify(wm, wm->selection_request.property);
>> xcb_flush(wm->conn);
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> close(fd);
>> wl_array_release(&wm->source_data);
>> wm->selection_request.requestor = XCB_NONE;
>> @@ -413,6 +419,7 @@ weston_wm_read_data_source(int fd, uint32_t mask, void *data)
>> }
>> xcb_flush(wm->conn);
>> wl_event_source_remove(wm->property_source);
>> + wm->property_source = NULL;
>> close(wm->data_source_fd);
>> wm->data_source_fd = -1;
>> close(fd);
>> --
>> 2.2.1
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list