xwayland: Free all remaining events in xwl_present_cleanup
These events aren't reachable after xwl_present_cleanup, so they're leaked if we don't free them first. This requires storing the pixmap pointer in struct xwl_present_window. Luckily, the buffer pointer isn't used for anything, so just replace that. v2: * Bump pixmap reference count in xwl_present_flip and drop it in xwl_present_free_event, fixes use-after-free in the latter due to the pixmap already being destroyed. Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
1beffba699
commit
b670527429
|
@ -120,6 +120,16 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
|||
static void
|
||||
xwl_present_free_event(struct xwl_present_event *event)
|
||||
{
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
if (event->pixmap) {
|
||||
if (!event->buffer_released)
|
||||
xwl_pixmap_del_buffer_release_cb(event->pixmap);
|
||||
|
||||
dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
|
||||
}
|
||||
|
||||
xorg_list_del(&event->list);
|
||||
free(event);
|
||||
}
|
||||
|
@ -144,21 +154,10 @@ xwl_present_cleanup(WindowPtr window)
|
|||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list)
|
||||
xwl_present_free_event(event);
|
||||
|
||||
/* Clear remaining buffer releases and inform Present about free ressources */
|
||||
event = xwl_present_window->sync_flip;
|
||||
xwl_present_window->sync_flip = NULL;
|
||||
if (event) {
|
||||
if (event->buffer_released) {
|
||||
xwl_present_free_event(event);
|
||||
} else {
|
||||
event->pending = FALSE;
|
||||
event->abort = TRUE;
|
||||
}
|
||||
}
|
||||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) {
|
||||
xorg_list_del(&event->list);
|
||||
event->abort = TRUE;
|
||||
}
|
||||
xwl_present_free_event(xwl_present_window->sync_flip);
|
||||
|
||||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list)
|
||||
xwl_present_free_event(event);
|
||||
|
||||
/* Clear timer */
|
||||
xwl_present_free_timer(xwl_present_window);
|
||||
|
@ -356,6 +355,7 @@ xwl_present_queue_vblank(WindowPtr present_window,
|
|||
return BadAlloc;
|
||||
|
||||
event->event_id = event_id;
|
||||
event->pixmap = NULL;
|
||||
event->xwl_present_window = xwl_present_window;
|
||||
event->target_msc = msc;
|
||||
|
||||
|
@ -459,11 +459,12 @@ xwl_present_flip(WindowPtr present_window,
|
|||
if (!event)
|
||||
return FALSE;
|
||||
|
||||
pixmap->refcnt++;
|
||||
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, NULL);
|
||||
|
||||
event->event_id = event_id;
|
||||
event->xwl_present_window = xwl_present_window;
|
||||
event->buffer = buffer;
|
||||
event->pixmap = pixmap;
|
||||
event->target_msc = target_msc;
|
||||
event->pending = TRUE;
|
||||
event->abort = FALSE;
|
||||
|
|
|
@ -59,7 +59,7 @@ struct xwl_present_event {
|
|||
Bool buffer_released;
|
||||
|
||||
struct xwl_present_window *xwl_present_window;
|
||||
struct wl_buffer *buffer;
|
||||
PixmapPtr pixmap;
|
||||
|
||||
struct xorg_list list;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user