From: Daniel Wagner <[email protected]>

__connman_counter_register registers with g_dbus_add_disconnect_watch
only the disconnect function callback and not the connect
function.

When the the owner disconnects service_filter is called
eventually. In service_filter filter_data_remove_callback is called
twice (see backtrace below). This leads to a double free.

Breakpoint 3, filter_data_remove_callback (data=0x68ddf0, cb=0x680130) at 
gdbus/watch.c:355
355             fprintf(stderr, "\nXXX cb %p\n", cb);
(gdb) bt
#0  filter_data_remove_callback (data=0x68ddf0, cb=0x680130) at 
gdbus/watch.c:355
#1  0x000000000040d379 in g_dbus_remove_watch (connection=0x67e5c0, id=20) at 
gdbus/watch.c:732
#2  0x000000000044f53e in remove_counter (user_data=0x67f6b0) at 
src/counter.c:49
#3  0x0000003efde2a4e5 in g_hash_table_remove_node (hash_table=0x6811e0 = 
{...}, node=0x682330, notify=<value optimized out>) at ghash.c:335
#4  0x0000003efde2ba2a in g_hash_table_remove_internal (hash_table=0x6811e0 = 
{...}, key=0x67c010, notify=1) at ghash.c:981
#5  0x000000000044f60f in owner_disconnect (connection=0x67e5c0, 
user_data=0x67f6b0) at src/counter.c:67
#6  0x000000000040cb67 in service_filter (connection=0x67e5c0, 
message=0x680050, user_data=0x68ddf0) at gdbus/watch.c:477
#7  0x000000000040cd5f in message_filter (connection=0x67e5c0, 
message=0x680050, user_data=0x0) at gdbus/watch.c:530
#8  0x0000003f01a109d6 in dbus_connection_dispatch (connection=0x67e5c0) at 
dbus-connection.c:4444
#9  0x000000000040b52a in message_dispatch (data=0x67e5c0) at 
gdbus/mainloop.c:80
#10 0x0000003efde3994b in g_timeout_dispatch (source=0x68dc70, callback=<value 
optimized out>, user_data=<value optimized out>) at gmain.c:3396
#11 0x0000003efde3923e in g_main_dispatch (context=0x67d100) at gmain.c:1960
#12 IA__g_main_context_dispatch (context=0x67d100) at gmain.c:2513
#13 0x0000003efde3cc28 in g_main_context_iterate (context=0x67d100, 
block=<value optimized out>, dispatch=<value optimized out>, self=<value 
optimized out>)
    at gmain.c:2591
#14 0x0000003efde3d075 in IA__g_main_loop_run (loop=0x67d1e0) at gmain.c:2799
#15 0x00000000004265fb in main (argc=1, argv=0x7fffffffe6b8) at src/main.c:258
(gdb) c
Continuing.

XXX cb 0x680130
connmand[8225]: src/service.c:__connman_service_counter_unregister() counter 
/test/counter1

Breakpoint 3, filter_data_remove_callback (data=0x68ddf0, cb=0x680130) at 
gdbus/watch.c:355
355             fprintf(stderr, "\nXXX cb %p\n", cb);
(gdb) bt
#0  filter_data_remove_callback (data=0x68ddf0, cb=0x680130) at 
gdbus/watch.c:355
#1  0x000000000040cbcb in service_filter (connection=0x67e5c0, 
message=0x680050, user_data=0x68ddf0) at gdbus/watch.c:486
#2  0x000000000040cd5f in message_filter (connection=0x67e5c0, 
message=0x680050, user_data=0x0) at gdbus/watch.c:530
#3  0x0000003f01a109d6 in dbus_connection_dispatch (connection=0x67e5c0) at 
dbus-connection.c:4444
#4  0x000000000040b52a in message_dispatch (data=0x67e5c0) at 
gdbus/mainloop.c:80
#5  0x0000003efde3994b in g_timeout_dispatch (source=0x68dc70, callback=<value 
optimized out>, user_data=<value optimized out>) at gmain.c:3396
#6  0x0000003efde3923e in g_main_dispatch (context=0x67d100) at gmain.c:1960
#7  IA__g_main_context_dispatch (context=0x67d100) at gmain.c:2513
#8  0x0000003efde3cc28 in g_main_context_iterate (context=0x67d100, 
block=<value optimized out>, dispatch=<value optimized out>, self=<value 
optimized out>)
    at gmain.c:2591
#9  0x0000003efde3d075 in IA__g_main_loop_run (loop=0x67d1e0) at gmain.c:2799
#10 0x00000000004265fb in main (argc=1, argv=0x7fffffffe6b8) at src/main.c:258
(gdb) c
Continuing.

XXX cb 0x680130

Program received signal SIGSEGV, Segmentation fault.
0x000000000068ddc0 in ?? ()
---
 gdbus/watch.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/gdbus/watch.c b/gdbus/watch.c
index c0dcc93..d420596 100644
--- a/gdbus/watch.c
+++ b/gdbus/watch.c
@@ -479,8 +479,7 @@ static DBusHandlerResult service_filter(DBusConnection 
*connection,
                }
 
                /* Only auto remove if it is a bus name watch */
-               if (data->argument[0] == ':' &&
-                               (!cb->conn_func || !cb->disc_func)) {
+               if (data->argument[0] == ':' && !cb->disc_func) {
                        filter_data_remove_callback(data, cb);
                        continue;
                }
-- 
1.7.2.3

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to