-
Notifications
You must be signed in to change notification settings - Fork 453
Description
i2pd on the server side (STREAM ACCEPT
) would deterministically crash following a basic SAM session:
The server listens for a connection via I2P SAM:
# 127.0.0.1.14746 > 127.0.0.1.7656
HELLO VERSION MIN=3.1 MAX=3.1
# 127.0.0.1.7656 > 127.0.0.1.14746
HELLO REPLY RESULT=OK VERSION=3.1
# 127.0.0.1.14746 > 127.0.0.1.7656
SESSION CREATE STYLE=STREAM ID=ISWOOEQI DESTINATION=MC~oipzmGbxW9QgTOa9H0zNwe1TyghwRQnCkKVonWiZuZpDPE9be-wwsNkFsEO6i096Zeoolm5erw4yUfT0dVo78TUnJObETtkhZgPmRJhZnyL1n~tpEnDAf6q1Gze0SHK3VzkRsV4AVJ1PFarwAlCN8A-B7nHoWOTd0JkH8jW-vkDB~Hh97CdDXDUeA4axPZIJzyAUmeAOPA~BYR~gI0QbH3~zxTqGF9pdjf4U2BAqOebqhliXv0Xw~t1w4WhYDcqtoZ9A0vOV6V5un~kNVlgmvnovz8O-lvK5Q~pHnLkeRS7gaSIYUV~UaB1b93ldVpVpIRuIpVqGCwRPIkAivvaTU3mIIqewK09v2Pkzgze2-JMvdzfNHwt99sVtQCWQkSVtTw2R4fSicnkUqaT9fcz7u~hy2C28QRfcSSgekhUiT44oiwfY-wobKQ-SLSQjSTC0egXUI7Ey1AjYKXUq-dahdihw7meAer~aAP3zKDsQht89WO4bAlAi8T2wtQSyCBQAEAAcAAIugJp7g6rWKQuZFCAN9HdEUgFCesgBKFeJlo983y2p6sr5LL3rydIXqgPU8XELHyOSNjD6E3zUJWNjH8aqACMjeCbXJKsYtM6Ffqx9z1DziJQcg2oajeXP6aksaEbK6QkuGtO-kIpUE-2TCp9F03WjK6ZXJoDVPFwRNKHRUOzj9ZKz9BuHJYUpyDd5PL~bdm5pOeRSMtQZ3AKKC2IeByOf6ku2e6AdnrZrJzPwgzH1mxCNKoSknErMZmOfIYo00PdOPwF~svUHmmgj8fcZjZNR4rG0ds~nEkR0F0KlIllDmcsGafPvprZK88GujBIjZXzh~uzZ6FMJGfDnjqwVO-A2j7UP4~sgkIMRf779FeFuK2vyTxSRQk~0Q5bD5kcuQRg== SIGNATURE_TYPE=EdDSA_SHA512_Ed25519 inbound.nickname=test1
# 127.0.0.1.7656 > 127.0.0.1.14746
SESSION STATUS RESULT=OK DESTINATION=MC~oipzmGbxW9QgTOa9H0zNwe1TyghwRQnCkKVonWiZuZpDPE9be-wwsNkFsEO6i096Zeoolm5erw4yUfT0dVo78TUnJObETtkhZgPmRJhZnyL1n~tpEnDAf6q1Gze0SHK3VzkRsV4AVJ1PFarwAlCN8A-B7nHoWOTd0JkH8jW-vkDB~Hh97CdDXDUeA4axPZIJzyAUmeAOPA~BYR~gI0QbH3~zxTqGF9pdjf4U2BAqOebqhliXv0Xw~t1w4WhYDcqtoZ9A0vOV6V5un~kNVlgmvnovz8O-lvK5Q~pHnLkeRS7gaSIYUV~UaB1b93ldVpVpIRuIpVqGCwRPIkAivvaTU3mIIqewK09v2Pkzgze2-JMvdzfNHwt99sVtQCWQkSVtTw2R4fSicnkUqaT9fcz7u~hy2C28QRfcSSgekhUiT44oiwfY-wobKQ-SLSQjSTC0egXUI7Ey1AjYKXUq-dahdihw7meAer~aAP3zKDsQht89WO4bAlAi8T2wtQSyCBQAEAAcAAIugJp7g6rWKQuZFCAN9HdEUgFCesgBKFeJlo983y2p6sr5LL3rydIXqgPU8XELHyOSNjD6E3zUJWNjH8aqACMjeCbXJKsYtM6Ffqx9z1DziJQcg2oajeXP6aksaEbK6QkuGtO-kIpUE-2TCp9F03WjK6ZXJoDVPFwRNKHRUOzj9ZKz9BuHJYUpyDd5PL~bdm5pOeRSMtQZ3AKKC2IeByOf6ku2e6AdnrZrJzPwgzH1mxCNKoSknErMZmOfIYo00PdOPwF~svUHmmgj8fcZjZNR4rG0ds~nEkR0F0KlIllDmcsGafPvprZK88GujBIjZXzh~uzZ6FMJGfDnjqwVO-A2j7UP4~sgkIMRf779FeFuK2vyTxSRQk~0Q5bD5kcuQRg==
# 127.0.0.1.16339 > 127.0.0.1.7656
HELLO VERSION MIN=3.1 MAX=3.1
# 127.0.0.1.7656 > 127.0.0.1.16339
HELLO REPLY RESULT=OK VERSION=3.1
# 127.0.0.1.16339 > 127.0.0.1.7656
STREAM ACCEPT ID=ISWOOEQI SILENT=false
# 127.0.0.1.7656 > 127.0.0.1.16339
STREAM STATUS RESULT=OK
Client (on another computer) connects to the server and sends the string 55
:
HELLO VERSION MIN=3.1 MAX=3.1
HELLO REPLY RESULT=OK VERSION=3.1
SESSION CREATE STYLE=STREAM ID=FPPQNQO DESTINATION=TRANSIENT SIGNATURE_TYPE=EdDSA_SHA512_Ed25519 inbound.nickname=test1
SESSION STATUS RESULT=OK DESTINATION=mmfmEpeUPqkxa7Qh8mPMI~9sP8HrKMNoPnK4jHvkEe1HgHB6Xu4dWps3q8-7Gs4D~SUSBXutNdBGy0QvdESomTg56J9LXoqLHtKUy7TMURtjsPDHnLOzsSboe8A3Wz6EwTQnE-n32zBPgX682ZiOcP6axtlachCMTchQnItfWyioYvyw87Dch1WyghHqX~IEwV5mW7lR-OuAYilo31aKMp90zUGaBdjrAUm9FIpGhA1~mLZz~KIc-33VM0Kuu4IJhvWRvIewSTheYlRvJS5ej0~hIbU~mpzIJNbv13ey1NI-d-DfjAYKAIPMUsCIw5Pz8svvqgQk2Ht4yZbLjwm27gT4PIIkX~lzX1UA-evoN1ETaFAJ6cN1UnT74ii5MA1GV~ZqCsyeKFNFtPg8PvxN0i7ViNp2IL1tJWOaAR4IIGoPkE7VDmAy0Evk00WUZ~q2GnNckRpcqsrihGa~0PtGovTv35sWKOsXEkIf-DHQNfJrlO5JmHEEBu8c8hcccnnHBQAEAAcAAAFgia6IrUmlOdbDZ53ZMEVYgfK9KmFT~xWWZlagXDuTt7FvkN6eLoo7hjSHN0I2uQaKSiMDORhVZf8l5T0Qeb8GqwV8zHmIZp2aGbdUXOf~fZeYnd68dm6peK9GCVQHc6H-B1eyFIW140NcuNi5ZBaIupnM-Ue59R8jIgHNHrTU3znUtQQb544XHfXrJ8MBwmZu-Uir-WfRjfmEhh--~EDcghKPrQoDx58bGEUz8oVYPbPu1qjEsDIvXZxZs-NnEptgonhoP-V9~FVdKk9gzNCfjf8BUmhh9~kga3sHK8-69EqIZ7ybol-2GO-R1V6kxmGdyqYJbGteYU3LUF1MWMjoAbFT8E3BU2KxkADWHkZQHBRwmVzZTLI2ajMY0VXWyA==
HELLO VERSION MIN=3.1 MAX=3.1
HELLO REPLY RESULT=OK VERSION=3.1
STREAM CONNECT ID=FPPQNQO DESTINATION=MC~oipzmGbxW9QgTOa9H0zNwe1TyghwRQnCkKVonWiZuZpDPE9be-wwsNkFsEO6i096Zeoolm5erw4yUfT0dVo78TUnJObETtkhZgPmRJhZnyL1n~tpEnDAf6q1Gze0SHK3VzkRsV4AVJ1PFarwAlCN8A-B7nHoWOTd0JkH8jW-vkDB~Hh97CdDXDUeA4axPZIJzyAUmeAOPA~BYR~gI0QbH3~zxTqGF9pdjf4U2BAqOebqhliXv0Xw~t1w4WhYDcqtoZ9A0vOV6V5un~kNVlgmvnovz8O-lvK5Q~pHnLkeRS7gaSIYUV~UaB1b93ldVpVpIRuIpVqGCwRPIkAivvaTU3mIIqewK09v2Pkzgze2-JMvdzfNHwt99sVtQCWQkSVtTw2R4fSicnkUqaT9fcz7u~hy2C28QRfcSSgekhUiT44oiwfY-wobKQ-SLSQjSTC0egXUI7Ey1AjYKXUq-dahdihw7meAer~aAP3zKDsQht89WO4bAlAi8T2wtQSyCBQAEAAcAAA== SILENT=false
STREAM STATUS RESULT=OK
55
On the server a random base64 string is received instead of the expected and i2pd crashes. Edit: the received string is the destination of the client.55
A backtrace from the crash:
Program terminated with signal SIGBUS, Bus error.
#0 0x00000000005b7bf3 in i2p::util::MemoryPool<i2p::I2NPMessageBuffer<62708> >::Acquire<>() (
this=0x803d033b8) at build/../libi2pd/util.h:69
69 m_Head = static_cast<T*>(*(void * *)m_Head); // next
(gdb) bt
#0 0x00000000005b7bf3 in i2p::util::MemoryPool<i2p::I2NPMessageBuffer<62708> >::Acquire<>() (
this=0x803d033b8) at build/../libi2pd/util.h:69
#1 0x00000000005b2fdc in i2p::util::MemoryPool<i2p::I2NPMessageBuffer<62708> >::AcquireShared<>() (
this=0x803d033b8) at build/../libi2pd/util.h:92
#2 0x00000000006b757f in i2p::stream::StreamingDestination::CreateDataMessage (this=0x803d032a0,
payload=0x803053010 ")\206CD}\227\260n", len=86, toPort=0, checksum=true)
at libi2pd/Streaming.cpp:1252
#3 0x00000000006b5f00 in i2p::stream::Stream::SendPackets (this=0x803d03518,
packets=std::vector of length 1 = {...}) at libi2pd/Streaming.cpp:790
#4 0x00000000006b809f in i2p::stream::Stream::HandleResendTimer (this=0x803d03518, ecode=...)
at libi2pd/Streaming.cpp:900
#5 0x00000000006c8544 in std::__1::__invoke<void (i2p::stream::Stream::*&)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>&, boost::system::error_code const&, void> (__f=
@0x7fffde3efba0: (void (i2p::stream::Stream::*)(i2p::stream::Stream * const, const boost::system::error_code &)) 0x6b7af0 <i2p::stream::Stream::HandleResendTimer(boost::system::error_code const&)>,
__a0=..., __args=...) at /usr/include/c++/v1/type_traits:3480
#6 0x00000000006c849d in std::__1::__apply_functor<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::tuple<std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> >, 0ul, 1ul, std::__1::tuple<boost::system::error_code const&> > (__f=
@0x7fffde3efba0: (void (i2p::stream::Stream::*)(i2p::stream::Stream * const, const boost::system::error_code &)) 0x6b7af0 <i2p::stream::Stream::HandleResendTimer(boost::system::error_code const&)>,
__bound_args=..., __args=...) at /usr/include/c++/v1/functional:2770
#7 0x00000000006c841a in std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>::operator()<boost::system::error_code const&> (this=0x7fffde3efba0, __args=...)
at /usr/include/c++/v1/functional:2803
#8 0x00000000006c83b5 in boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code>::operator() (this=0x7fffde3efba0)
at /usr/local/include/boost/asio/detail/bind_handler.hpp:65
#9 0x00000000006c8385 in boost::asio::asio_handler_invoke<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code> > (function=...)
at /usr/local/include/boost/asio/handler_invoke_hook.hpp:69
#10 0x00000000006c8362 in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code>, std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&> > (function=..., context=...)
at /usr/local/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#11 0x00000000006c830d in boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code>, std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code> (function=...,
this_handler=0x7fffde3efba0) at /usr/local/include/boost/asio/detail/bind_handler.hpp:106
#12 0x00000000006c81c0 in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code>, boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code> >
(function=..., context=...) at /usr/local/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#13 0x00000000006c8173 in boost::asio::detail::io_object_executor<boost::asio::executor>::dispatch<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code>, std::__1::allocator<void> > (this=0x7fffde3efbf8, f=..., a=...)
at /usr/local/include/boost/asio/detail/io_object_executor.hpp:119
#14 0x00000000006c7f02 in boost::asio::detail::handler_work<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::asio::detail::io_object_executor<boost::asio::executor>, boost::asio::detail::io_object_executor<boost::asio::executor> >::complete<boost::asio::detail::binder1<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::system::error_code> > (this=0x7fffde3efbe8,
function=..., handler=...) at /usr/local/include/boost/asio/detail/handler_work.hpp:72
#15 0x00000000006c7bbd in boost::asio::detail::wait_handler<std::__1::__bind<void (i2p::stream::Stream::*)(boost::system::error_code const&), std::__1::shared_ptr<i2p::stream::Stream>, std::__1::placeholders::__ph<1> const&>, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete (
owner=0x80219ae40, base=0x803e380c0) at /usr/local/include/boost/asio/detail/wait_handler.hpp:73
#16 0x00000000004bbc15 in boost::asio::detail::scheduler_operation::complete (this=0x803e380c0,
owner=0x80219ae40, ec=..., bytes_transferred=0)
at /usr/local/include/boost/asio/detail/scheduler_operation.hpp:40
#17 0x00000000004bb029 in boost::asio::detail::scheduler::do_run_one (this=0x80219ae40, lock=...,
this_thread=..., ec=...) at /usr/local/include/boost/asio/detail/impl/scheduler.ipp:447
#18 0x00000000004babbf in boost::asio::detail::scheduler::run (this=0x80219ae40, ec=...)
at /usr/local/include/boost/asio/detail/impl/scheduler.ipp:200
#19 0x00000000004a9f2c in boost::asio::io_context::run (this=0x8031f3830)
at /usr/local/include/boost/asio/impl/io_context.ipp:63
#20 0x00000000007d4ce2 in i2p::util::RunnableService::Run (this=0x8031f3800) at libi2pd/util.cpp:101
#21 0x00000000007d81d7 in std::__1::__invoke<void (i2p::util::RunnableService::*&)(), i2p::util::RunnableService*&, , void> (
__f=@0x8013e2128: (void (i2p::util::RunnableService::*)(i2p::util::RunnableService * const)) 0x7d4ca0 <i2p::util::RunnableService::Run()>, __a0=@0x8013e2138: 0x8031f3800)
at /usr/include/c++/v1/type_traits:3480
#22 0x00000000007d8150 in std::__1::__apply_functor<void (i2p::util::RunnableService::*)(), std::__1::tuple<i2p::util::RunnableService*>, 0ul, std::__1::tuple<> > (
__f=@0x8013e2128: (void (i2p::util::RunnableService::*)(i2p::util::RunnableService * const)) 0x7d4ca0 <i2p::util::RunnableService::Run()>, __bound_args=..., __args=...)
at /usr/include/c++/v1/functional:2770
#23 0x00000000007d80e7 in std::__1::__bind<void (i2p::util::RunnableService::*)(), i2p::util::RunnableService*>::operator()<> (this=0x8013e2128) at /usr/include/c++/v1/functional:2803
#24 0x00000000007d805d in std::__1::__invoke<std::__1::__bind<void (i2p::util::RunnableService::*)(), i2p::util::RunnableService*>> (__f=...) at /usr/include/c++/v1/type_traits:3539
#25 0x00000000007d8005 in std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, std::__1::__bind<void (i2p::util::RunnableService::*)(), i2p::util::RunnableService*>>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, std::__1::__bind<void (i2p::util::RunnableService::*)(), i2p::util::RunnableService*>>&, std::__1::__tuple_indices<>) (__t=...)
at /usr/include/c++/v1/thread:273
#26 0x00000000007d7d54 in std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, std::__1::__bind<void (i2p::util::RunnableService::*)(), i2p::util::RunnableService*> > > (__vp=0x8013e2120)
at /usr/include/c++/v1/thread:284
#27 0x0000000800f0afac in thread_start (curthread=0x803188000)
at /usr/src/lib/libthr/thread/thr_create.c:292
#28 0x0000000000000000 in ?? ()
The allocator on the system is configured to overwrite all freed memory with 0x5a
.
(gdb) p this
$1 = (i2p::util::MemoryPool<i2p::I2NPMessageBuffer<62708> > *) 0x803d033b8
(gdb) p *this
$2 = {m_Head = 0x5a5a5a5a5a5a5a5a}
Aha! So this MemoryPool
object has been freed.
(gdb) f 2
#2 0x00000000006b757f in i2p::stream::StreamingDestination::CreateDataMessage (this=0x803d032a0,
payload=0x803053010 ")\206CD}\227\260n", len=86, toPort=0, checksum=true)
at libi2pd/Streaming.cpp:1252
1252 auto msg = m_I2NPMsgsPool.AcquireShared ();
(gdb) p this
$3 = (i2p::stream::StreamingDestination *) 0x803d032a0
(gdb) p *this
$4 = {<std::__1::enable_shared_from_this<i2p::stream::StreamingDestination>> = {__weak_this_ = {
__ptr_ = 0x5a5a5a5a5a5a5a5a, __cntrl_ = 0x5a5a5a5a5a5a5a5a}}, m_Owner = {
__ptr_ = 0x5a5a5a5a5a5a5a5a, __cntrl_ = 0x5a5a5a5a5a5a5a5a}, m_LocalPort = 23130, m_Gzip = 90,
...
state = 0x5a5a5a5a5a5a5a5a, zalloc = 0x5a5a5a5a5a5a5a5a, zfree = 0x5a5a5a5a5a5a5a5a,
opaque = 0x5a5a5a5a5a5a5a5a, data_type = 1515870810, adler = 6510615555426900570,
reserved = 6510615555426900570}, m_IsDirty = 90}}
So this StreamingDestination
object has been freed (it contains the MemoryPool
object from above).
(gdb) f 3
#3 0x00000000006b5f00 in i2p::stream::Stream::SendPackets (this=0x803d03518,
packets=std::vector of length 1 = {...}) at libi2pd/Streaming.cpp:790
790 auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage (
(gdb) p m_LocalDestination
... lots of 0x5a ...
So the m_LocalDestination
member has been freed.
(gdb) p this
$5 = (i2p::stream::Stream *) 0x803d03518
(gdb) p *this
The other members of Stream
seem to be ok, just m_LocalDestination
is deleted. It is defined as a reference at Streaming.h:229. So the StreamingDestination
object it references must have had a shorter lifetime than the containing Stream
object.
Version: i2pd 2.34.0