heap-use-after-free in turn_sock (TCP)
Describe the bug
No precise scenario, but ASAN crash detected randomly:
=================================================================
==15049==ERROR: AddressSanitizer: heap-use-after-free on address 0x0002b00b5648 at pc 0x0001056f5610 bp 0x00029dd327b0 sp 0x00029dd327a8
#0 0x1056f560c in stun_on_request_complete+0xc8c (Jami:arm64+0x102a8560c)
#1 0x1056ea7f4 in stun_tsx_on_complete+0x2a8 (Jami:arm64+0x102a7a7f4)
#2 0x1056f2498 in retransmit_timer_callback+0x12c (Jami:arm64+0x102a82498)
#3 0x105685fec in pj_timer_heap_poll+0x468 (Jami:arm64+0x102a15fec)
#4 0x104a4acbc in dhtnet::IceTransport::Impl::handleEvents(unsigned int)+0x110 (Jami:arm64+0x101ddacbc)
#5 0x104a65a5c in void* std::__1::__thread_proxy[abi:v160006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, dhtnet::IceTransport::Impl::initIceInstance(dhtnet::IceTransportOptions const&)::$_6>>(void*)+0x154 (Jami:arm64+0x101df5a5c)
#6 0x186caf030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
#7 0x186ca9e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)
0x0002b00b5648 is located 200 bytes inside of 256-byte region [0x0002b00b5580,0x0002b00b5680)
freed by thread T1102 here:
#0 0x111b5ace0 in wrap_free+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x52ce0)
#1 0x1056738d4 in pj_pool_destroy_int+0xbc (Jami:arm64+0x102a038d4)
#2 0x105674788 in cpool_release_pool+0xec (Jami:arm64+0x102a04788)
#3 0x105704130 in dataconn_on_data_read+0x180 (Jami:arm64+0x102a94130)
#4 0x105663b48 in ioqueue_on_read_complete+0x39c (Jami:arm64+0x1029f3b48)
#5 0x1056537a4 in ioqueue_dispatch_read_event+0x700 (Jami:arm64+0x1029e37a4)
#6 0x1056587bc in pj_ioqueue_poll+0x900 (Jami:arm64+0x1029e87bc)
#7 0x104a4ad9c in dhtnet::IceTransport::Impl::handleEvents(unsigned int)+0x1f0 (Jami:arm64+0x101ddad9c)
#8 0x104a65a5c in void* std::__1::__thread_proxy[abi:v160006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, dhtnet::IceTransport::Impl::initIceInstance(dhtnet::IceTransportOptions const&)::$_6>>(void*)+0x154 (Jami:arm64+0x101df5a5c)
#9 0x186caf030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
#10 0x186ca9e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)
previously allocated by thread T1102 here:
#0 0x111b5aba4 in wrap_malloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x52ba4)
#1 0x105660234 in default_block_alloc+0x50 (Jami:arm64+0x1029f0234)
#2 0x105672d68 in pj_pool_allocate_find+0x110 (Jami:arm64+0x102a02d68)
#3 0x105672f94 in pj_pool_calloc+0x7c (Jami:arm64+0x102a02f94)
#4 0x1056633a4 in pj_activesock_create+0x254 (Jami:arm64+0x1029f33a4)
#5 0x105700f6c in turn_on_connection_attempt+0x9d0 (Jami:arm64+0x102a90f6c)
#6 0x1056f59e8 in stun_on_rx_indication+0xe4 (Jami:arm64+0x102a859e8)
#7 0x1056e9914 in pj_stun_session_on_rx_pkt+0x69c (Jami:arm64+0x102a79914)
#8 0x1056fb5e4 in pj_turn_session_on_rx_pkt2+0x1ec (Jami:arm64+0x102a8b5e4)
#9 0x1056fb2f8 in pj_turn_session_on_rx_pkt+0x10c (Jami:arm64+0x102a8b2f8)
#10 0x105703930 in on_data_read_asock+0x468 (Jami:arm64+0x102a93930)
#11 0x105663a5c in ioqueue_on_read_complete+0x2b0 (Jami:arm64+0x1029f3a5c)
#12 0x1056537a4 in ioqueue_dispatch_read_event+0x700 (Jami:arm64+0x1029e37a4)
#13 0x1056587bc in pj_ioqueue_poll+0x900 (Jami:arm64+0x1029e87bc)
#14 0x104a4ad9c in dhtnet::IceTransport::Impl::handleEvents(unsigned int)+0x1f0 (Jami:arm64+0x101ddad9c)
#15 0x104a65a5c in void* std::__1::__thread_proxy[abi:v160006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, dhtnet::IceTransport::Impl::initIceInstance(dhtnet::IceTransportOptions const&)::$_6>>(void*)+0x154 (Jami:arm64+0x101df5a5c)
#16 0x186caf030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030)
#17 0x186ca9e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38)
What I see:
-
turn_sock.c:dataconn_on_data_read
is called with status = 120054 & size = 0 - This causes a dataconn_cleanup on the connection
-
turn_session.c:stun_on_request_complete
is then called with method = PJ_STUN_CONNECTION_BIND_METHOD & status = 370004
I guess dataconn_cleanup is called again in turn_on_connection_bind_status but I'm not sure yet.
Steps to reproduce
None detected yet
PJSIP version
2.13
Context
- macOS, but I guess all platforms should get the same bug
- Custom patched version, but turn_session/turn_sock should be the same.
Log, call stack, etc
cf first part