[gjs] function: Don't read freed memory if a callback is freed during invocation



commit cbf3227be29d967d916af211665e18a6d17f8f75
Author: Colin Walters <walters verbum org>
Date:   Wed Dec 1 18:18:26 2010 -0500

    function: Don't read freed memory if a callback is freed during invocation
    
    ==11331== Invalid read of size 4
    ==11331==    at 0xC05608D: gjs_invoke_c_function (function.c:664)
    
    This happens when a function calls the GDestroyNotify for SCOPE_ASYNC
    callback while the function is being called.  We'd try to check
    for callback->scope == SCOPE_CALL, but callback is already free()d.
    
    Save the scope value so we don't try to read freed memory.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636263

 gi/function.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
---
diff --git a/gi/function.c b/gi/function.c
index e83aa69..1307d0d 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -398,6 +398,7 @@ gjs_invoke_c_function(JSContext      *context,
     jsval *return_values = NULL;
     guint8 next_rval = 0; /* index into return_values */
     GSList *iter;
+    GIScopeType callback_scope = GI_SCOPE_TYPE_INVALID;
     GjsCallbackTrampoline *callback_trampoline;
     void *destroy_notify;
 
@@ -439,6 +440,8 @@ gjs_invoke_c_function(JSContext      *context,
                                            &callback_trampoline, &destroy_notify)) {
         return JS_FALSE;
     }
+    if (callback_trampoline != NULL)
+        callback_scope = callback_trampoline->scope;
 
     g_callable_info_load_return_type( (GICallableInfo*) function->info, &return_info);
     return_tag = g_type_info_get_tag(&return_info);
@@ -661,8 +664,11 @@ gjs_invoke_c_function(JSContext      *context,
     }
 
 release:
-    if (callback_trampoline &&
-        callback_trampoline->scope == GI_SCOPE_TYPE_CALL) {
+    /* Note we saved a copy of the scope in callback_scope above instead
+     * of inspecting callback_trampoline->scope here, because it's possible the
+     * callback was destroyed during the call.
+     */
+    if (callback_trampoline != NULL && callback_scope == GI_SCOPE_TYPE_CALL) {
         gjs_callback_trampoline_free(callback_trampoline);
     }
 



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