[Xfce4-commits] [xfce/xfconf] 01/02: When multiple calls are made for the same property, it's possible that xfconf_cache_set may be called twice before xfconf_cache_set_property_reply_handler, in which case old_item gets freed and the second handler call might cause undefined behavior or a segfault.

noreply at xfce.org noreply at xfce.org
Tue Aug 29 16:16:56 CEST 2017


This is an automated email from the git hooks/post-receive script.

a   l   i       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository xfce/xfconf.

commit 2131745b35e59fa5c1c0cec7e7ea5eaecd6c6e5f
Author: Stefan Berzl <stefan at localhost.localdomain>
Date:   Sat Aug 26 01:24:40 2017 +0200

    When multiple calls are made for the same property, it's possible that xfconf_cache_set may be called twice before xfconf_cache_set_property_reply_handler, in which case old_item gets freed and the second handler call might cause undefined behavior or a segfault.
    
    Added a counter to prevent that.
    
    Signed-off-by: Ali Abdallah <ali at xfce.org>
---
 xfconf/xfconf-cache.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/xfconf/xfconf-cache.c b/xfconf/xfconf-cache.c
index 48c820d..f3bbe43 100644
--- a/xfconf/xfconf-cache.c
+++ b/xfconf/xfconf-cache.c
@@ -152,6 +152,8 @@ typedef struct
 
     GCancellable *cancellable;
 
+    gint pending_calls_count;
+
     /**
      * Variant to be send on the wire
      * Used in xfconf_cache_old_item_end_call
@@ -177,6 +179,7 @@ xfconf_cache_old_item_new(XfconfCache *cache, const gchar *property)
     old_item->cancellable = g_cancellable_new ();
     old_item->cache = cache;
     old_item->variant = NULL;
+    old_item->pending_calls_count = 0;
 
     return old_item;
 }
@@ -330,7 +333,8 @@ xfconf_cache_class_init(XfconfCacheClass *klass)
 
     signals[SIG_PROPERTY_CHANGED] = g_signal_new(I_("property-changed"),
                                                  XFCONF_TYPE_CACHE,
-                                                 G_SIGNAL_RUN_LAST,
+                                                 G_SIGNAL_RUN_LAST
+                                                 | G_SIGNAL_DETAILED,
                                                  G_STRUCT_OFFSET(XfconfCacheClass,
                                                                  property_changed),
                                                  NULL,
@@ -596,7 +600,9 @@ xfconf_cache_set_property_reply_handler(GDBusProxy *proxy,
     gboolean result;
     old_item = (XfconfCacheOldItem *) user_data;
     cache = old_item->cache;
-    if(!cache->pending_calls)
+
+    old_item->pending_calls_count--;
+    if(old_item->pending_calls_count > 0)
         return;
 
     xfconf_cache_mutex_lock(cache);
@@ -879,6 +885,11 @@ xfconf_cache_set(XfconfCache *cache,
             g_object_unref (old_item->cancellable);
             old_item->cancellable = g_cancellable_new();
         }
+
+        if(old_item->variant){
+            g_variant_unref(old_item->variant);
+            old_item->variant = NULL;
+        }
     } else {
         old_item = xfconf_cache_old_item_new(cache, property);
         if(item)
@@ -898,8 +909,8 @@ xfconf_cache_set(XfconfCache *cache,
                                            (GAsyncReadyCallback) xfconf_cache_set_property_reply_handler,
                                            old_item);
 
-        /* Val will be freed asynchronously */
         old_item->variant = val;
+        old_item->pending_calls_count++;
 
         g_hash_table_insert(cache->pending_calls, old_item->cancellable, old_item);
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list