GNOME Bugzilla – Bug 305854
accessing already freed memory when cancelling async tcp/inetaddr operation
Last modified: 2006-09-13 12:08:20 UTC
Compile and run the attached test program. Click the button as often and as fast as you can. Valgrind will complain like this: connecting disconnecting ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B1B8: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:124) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00E0 is 8 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B1C5: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:125) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00D8 is 0 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B1CD: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:126) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B1D3: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:128) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B1DE: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:133) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B1EC: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:134) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B1F2: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:134) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B220: gnet_tcp_socket_connect_inetaddr_cb (tcp.c:141) ==1260== by 0x1BD6795B: inetaddr_new_list_async_gthread_dispatch (inetaddr.c:1183) ==1260== by 0x1BDB2582: ??? (gmain.c:3812) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00E4 is 12 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B2FA: gnet_tcp_socket_connect_tcp_cb (tcp.c:174) ==1260== by 0x1BD6BB48: gnet_tcp_socket_new_async_cb (tcp.c:516) ==1260== by 0x1BDD4DBE: ??? (giounix.c:162) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00E4 is 12 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B34F: gnet_tcp_socket_connect_tcp_cb (tcp.c:191) ==1260== by 0x1BD6BB48: gnet_tcp_socket_new_async_cb (tcp.c:516) ==1260== by 0x1BDD4DBE: ??? (giounix.c:162) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00DC is 4 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid write of size 4 ==1260== at 0x1BD6B3AB: gnet_tcp_socket_connect_tcp_cb (tcp.c:210) ==1260== by 0x1BD6BB48: gnet_tcp_socket_new_async_cb (tcp.c:516) ==1260== by 0x1BDD4DBE: ??? (giounix.c:162) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00E8 is 16 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B3B8: gnet_tcp_socket_connect_tcp_cb (tcp.c:211) ==1260== by 0x1BD6BB48: gnet_tcp_socket_new_async_cb (tcp.c:516) ==1260== by 0x1BDD4DBE: ??? (giounix.c:162) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00F0 is 24 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) ==1260== ==1260== Invalid read of size 4 ==1260== at 0x1BD6B3CE: gnet_tcp_socket_connect_tcp_cb (tcp.c:211) ==1260== by 0x1BD6BB48: gnet_tcp_socket_new_async_cb (tcp.c:516) ==1260== by 0x1BDD4DBE: ??? (giounix.c:162) ==1260== by 0x1BDAF581: ??? (gmain.c:1933) ==1260== by 0x1BDB05F7: g_main_context_dispatch (gmain.c:2483) ==1260== by 0x1BDB092F: ??? (gmain.c:2564) ==1260== by 0x1BDB0ED2: g_main_loop_run (gmain.c:2768) ==1260== by 0x1BA3CBB2: gtk_main (gtkmain.c:963) ==1260== by 0x8048D73: main (error.c:71) ==1260== Address 0x1C2C00EC is 20 bytes inside a block of size 28 free'd ==1260== at 0x1B904B04: free (vg_replace_malloc.c:152) ==1260== by 0x1BDB5A83: g_free (gmem.c:187) ==1260== by 0x1BD6B4B5: gnet_tcp_socket_connect_async_cancel (tcp.c:256) ==1260== by 0x8048BF8: on_button_press (error.c:45) ==1260== by 0x1BD3D2A5: g_cclosure_marshal_VOID__VOID (gmarshal.c:77) ==1260== by 0x1BD2B735: g_closure_invoke (gclosure.c:437) ==1260== by 0x1BD3CDCE: ??? (gsignal.c:2488) ==1260== by 0x1BD3BE9B: g_signal_emit_valist (gsignal.c:2247) ==1260== by 0x1BD3C125: g_signal_emit (gsignal.c:2291) ==1260== by 0x1B979654: gtk_button_clicked (gtkbutton.c:782) Cheers -Tim
Created attachment 47009 [details] test case Test case to reproduce the bug (by Tuomas Kokki).
I have one guess that I still must verify. gnet_tcp_socket_connect_async_cancel calls gnet_inetaddr_new_async_cancel. But this one returns when callback is executing. The former goes on anyway and frees some structures that will be used when the inetaddr callback is really executed. Perhaps using references for the objects they refer to would be the solution.
Created attachment 72636 [details] Automated GNet-only test case Another test case, this time using GNet/GLib only and not requiring manual intervention. Seems to produce the same problem (and some more ...).
Should be fixed in CVS now: 2006-09-13 Tim-Philipp Müller <tim at centricular dot net> * src/tcp.c: (gnet_tcp_socket_connect_async_cancel): We used gnet_inetaddr_new_list_async(), so we also need to call gnet_inetaddr_new_list_async_cancel() to cancel it, and not gnet_inetaddr_new_async_cancel(). Would cause invalid memory access, double frees and other weird things when cancelling an asynchronous TCP connect before the dns lookup has finished. Fixes #305854. * src/gnet-private.h: * src/inetaddr.h: * src/tcp.h: The compiler can help us with stuff like this. Let's let it.