From: Pekka Paalanen <pekka.paala...@collabora.co.uk>

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 <pekka.paala...@collabora.co.uk>
---
 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 d9185b85..be02ad69 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -2582,6 +2582,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);
 }
 
@@ -2706,7 +2707,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);
 }
 
@@ -5614,6 +5617,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 af681e51..a9617755 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.13.6

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to