[mutter] clutter: Keep a device reference with events



commit ac6039bd2a917992e463ea7a544d12f454344808
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Mon Nov 19 11:25:57 2018 +0100

    clutter: Keep a device reference with events
    
    If a device (virtual or real) is removed while there are remaining
    events queued for that device, the event loop may try to access the
    event freed memory.
    
    To avoid the issue, add a reference to the device when the event is
    created or copied, and remove the reference once the device is freed.
    
    Closes: https://gitlab.gnome.org/GNOME/mutter/issues/393

 clutter/clutter/clutter-event.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c
index c2e91d7a7..8e7782df3 100644
--- a/clutter/clutter/clutter-event.c
+++ b/clutter/clutter/clutter-event.c
@@ -1093,7 +1093,7 @@ clutter_event_set_device (ClutterEvent       *event,
     {
       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
 
-      real_event->device = device;
+      g_set_object (&real_event->device, device);
     }
 
   switch (event->type)
@@ -1362,8 +1362,8 @@ clutter_event_copy (const ClutterEvent *event)
     {
       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
 
-      new_real_event->device = real_event->device;
-      new_real_event->source_device = real_event->source_device;
+      g_set_object (&new_real_event->device, real_event->device);
+      g_set_object (&new_real_event->source_device, real_event->source_device);
       new_real_event->delta_x = real_event->delta_x;
       new_real_event->delta_y = real_event->delta_y;
       new_real_event->is_pointer_emulated = real_event->is_pointer_emulated;
@@ -1433,6 +1433,14 @@ clutter_event_free (ClutterEvent *event)
     {
       _clutter_backend_free_event_data (clutter_get_default_backend (), event);
 
+      if (is_event_allocated (event))
+        {
+          ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
+
+          g_clear_object (&real_event->device);
+          g_clear_object (&real_event->source_device);
+        }
+
       switch (event->type)
         {
         case CLUTTER_BUTTON_PRESS:
@@ -1687,7 +1695,7 @@ clutter_event_set_source_device (ClutterEvent       *event,
     return;
 
   real_event = (ClutterEventPrivate *) event;
-  real_event->source_device = device;
+  g_set_object (&real_event->source_device, device);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]