[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