gresolv: Avoid accessing already freed memory
authorJukka Rissanen <jukka.rissanen@linux.intel.com>
Mon, 15 Oct 2012 10:36:03 +0000 (13:36 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Tue, 16 Oct 2012 09:19:16 +0000 (12:19 +0300)
We must remove the lookup from lookup queue and query from query queue
before calling user callback. The callback might unref the GResolv which in
turn would remove the lookup/query what we are trying to access after
the callback is returned.

So it is enough to remove the lookup or query entry from queue before
cb is called and then manually remove it after the callback has returned.

gweb/gresolv.c

index 77c1afb80fd406be047fb84a619cc999a3d229f2..440f43c1fec0d37f829597fb027a98d8e52f8937 100644 (file)
@@ -497,10 +497,11 @@ static void sort_and_return_results(struct resolv_lookup *lookup)
                        status = lookup->ipv4_status;
        }
 
+       g_queue_remove(lookup->resolv->lookup_queue, lookup);
+
        lookup->result_func(status, results, lookup->result_data);
 
        g_strfreev(results);
-       g_queue_remove(lookup->resolv->lookup_queue, lookup);
        destroy_lookup(lookup);
 }
 
@@ -520,11 +521,12 @@ static gboolean query_timeout(gpointer user_data)
                lookup->ipv6_query = NULL;
        }
 
+       g_queue_remove(resolv->query_queue, query);
+
        if (lookup->ipv4_query == NULL && lookup->ipv6_query == NULL)
                sort_and_return_results(lookup);
 
        destroy_query(query);
-       g_queue_remove(resolv->query_queue, query);
 
        return FALSE;
 }
@@ -709,11 +711,12 @@ static void parse_response(struct resolv_nameserver *nameserver,
                }
        }
 
+       g_queue_remove(resolv->query_queue, query);
+
        if (lookup->ipv4_query == NULL && lookup->ipv6_query == NULL)
                sort_and_return_results(lookup);
 
        destroy_query(query);
-       g_queue_remove(resolv->query_queue, query);
 }
 
 static gboolean received_udp_data(GIOChannel *channel, GIOCondition cond,