on_scan_timeout can be called on free'd GClueWifi object
By running valgrind on geoclue, I stumbled onto the following report:
==20762== Invalid read of size 8
==20762== at 0x4B9E416: g_type_check_instance_cast (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x12F770: on_scan_timeout (gclue-wifi.c:416)
==20762== by 0x48BF893: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48BED8D: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48BF13F: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48BF412: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x113907: main (gclue-main.c:194)
==20762== Address 0x9e5c4e0 is 208 bytes inside a block of size 264 free'd
==20762== at 0x48369AB: free (vg_replace_malloc.c:540)
==20762== by 0x4B9D105: g_type_free_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x48BB1C7: g_list_foreach (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48BB1EA: g_list_free_full (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x12A7F6: gclue_locator_finalize (gclue-locator.c:326)
==20762== by 0x4B7EFAD: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x12D689: gclue_service_client_finalize (gclue-service-client.c:663)
==20762== by 0x4B7EFAD: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x12B17D: delete_client (gclue-service-manager.c:129)
==20762== by 0x4B79EB1: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B8D4D3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B9618E: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== Block was alloc'd at
==20762== at 0x483577F: malloc (vg_replace_malloc.c:309)
==20762== by 0x48C49F8: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48DCA01: g_slice_alloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x48DD029: g_slice_alloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6200.0)
==20762== by 0x4B9CD3F: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B7F6E4: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B814F8: g_object_new_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B81848: g_object_new (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x1304C5: gclue_wifi_get_singleton (gclue-wifi.c:795)
==20762== by 0x12A29E: gclue_locator_constructed (gclue-locator.c:358)
==20762== by 0x4B7F8E5: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
==20762== by 0x4B814F8: g_object_new_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6200.0)
I think what happens is that on_scan_done
can schedule a timeout, but the client disconnects, calling delete_client
in the process. Later the timeout function on_scan_timeout
is called and deference the user pointer which has been freed by delete_client
.
It seems to me that on_scan_timeout
should at the very least add a reference to the wifi object and on_scan_done
should unref it. But I don't understand GLib well-enough to be sure that's the solution.