From dcbcfc7f678d96d9c26514fa47d65d992bb5b48c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 26 Oct 2017 14:33:59 +0300 Subject: [PATCH] libweston: cancel idle_repaint on output destroy If the idle_repaint() callback has been scheduled when a weston_output gets destroyed, the callback will hit use-after-free. I have encountered this when migrating the wayland backend to the head-based API, using --sprawl, and closing/disconnecting one of the parent compositor outputs. Store the idle_repaint callback source, and destroy it in weston_output_release(), ensuring we don't get a stale call to start_repaint_loop later. Signed-off-by: Pekka Paalanen Reviewed-by: Ian Ray Reviewed-by: Daniel Stone Acked-by: Derek Foreman --- libweston/compositor.c | 8 +++++++- libweston/compositor.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 2ec7f8e..4a1d568 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -2592,6 +2592,7 @@ idle_repaint(void *data) assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE); output->repaint_status = REPAINT_AWAITING_COMPLETION; + output->idle_repaint_source = NULL; output->start_repaint_loop(output); } @@ -2716,7 +2717,9 @@ weston_output_schedule_repaint(struct weston_output *output) return; output->repaint_status = REPAINT_BEGIN_FROM_IDLE; - wl_event_loop_add_idle(loop, idle_repaint, output); + assert(!output->idle_repaint_source); + output->idle_repaint_source = wl_event_loop_add_idle(loop, idle_repaint, + output); TL_POINT("core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END); } @@ -5676,6 +5679,9 @@ weston_output_release(struct weston_output *output) output->destroying = 1; + if (output->idle_repaint_source) + wl_event_source_remove(output->idle_repaint_source); + if (output->enabled) weston_compositor_remove_output(output); diff --git a/libweston/compositor.h b/libweston/compositor.h index 5ee7fdf..869740d 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -216,6 +216,9 @@ struct weston_output { * next repaint should be run */ struct timespec next_repaint; + /** For cancelling the idle_repaint callback on output destruction. */ + struct wl_event_source *idle_repaint_source; + struct weston_output_zoom zoom; int dirty; struct wl_signal frame_signal; -- 2.7.4