[Boost-bugs] [Boost C++ Libraries] #13294: Boost(1.57).Asio crashes after ssl stream is closed and stream is deleted.

Subject: [Boost-bugs] [Boost C++ Libraries] #13294: Boost(1.57).Asio crashes after ssl stream is closed and stream is deleted.
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-11-13 23:17:41


#13294: Boost(1.57).Asio crashes after ssl stream is closed and stream is deleted.
-----------------------------------------------+---------------------------
 Reporter: Andrey Borisov <andrey.borisov@…> | Owner:
                                               | chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost 1.57.0 | Severity: Showstopper
 Keywords: asio ssl close crash |
-----------------------------------------------+---------------------------
 The issue is found in boost asio v1.57 and is presents in 1.65.1.
 Windows, Visual Studio 2015

 Our library uses boost asio ssl stream for secure TCP connection.
 We use dynamically created context and ssl stream:

 {{{#!cpp
 std::shared_ptr<ssl_context> m_context;
 std::shared_ptr<ssl_stream> m_stream;
 ...
 m_context =
 std::make_shared<ssl_context>(TM_NS_ASIO::ssl::context::tlsv12);
 m_stream = std::make_shared<ssl_stream>(*io_service, *m_context);
 }}}

 after handshake we start reading asynchronously:
 {{{#!cpp
 m_stream->async_read_some(buffer, readHandler);
 }}}

 After that we just close the connection and remove objects:
 {{{#!cpp
 m_stream->shutdown(ec);
 m_stream->lowest_layer().close(ec);
 }}}

 Than we destroy the stream and context:
 {{{#!cpp
 m_stream.reset();
 m_context.reset();
 }}}

 Close and destroy operation are performed in a context of io_service
 thread.
 And after the stream deletion the io_service gets the break assertion:

 {{{#!cpp
> msvcp140d.dll!std::_Debug_message(const wchar_t * message, const
 wchar_t * file, unsigned int line) Line 17 C++
 tls_test.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > >::operator*() Line 73 C++
 tls_test.exe!std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > >::operator*() Line 332 C++
 tls_test.exe!boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > >::operator()() Line 532 C++
 tls_test.exe!std::_Invoker_functor::_Call<boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > >
 &>(boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > > & _Obj) Line 1377 C++
 tls_test.exe!std::invoke<boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > >
 &>(boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > > & _Obj) Line 1443 C++
 tls_test.exe!std::_Invoke_ret<void,boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > > &>(std::_Forced<void,1> __formal,
 boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > > & <_Vals_0>) Line 1461 C++
 tls_test.exe!std::_Func_impl<boost::asio::detail::buffer_debug_check<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned
 char> > > >,std::allocator<int>,void>::_Do_call() Line 212 C++
         tls_test.exe!std::_Func_class<void>::operator()() Line 279
 C++
         tls_test.exe!boost::asio::detail::buffer_cast_helper(const
 boost::asio::mutable_buffer & b) Line 146 C++
         tls_test.exe!boost::asio::buffer_cast<void const *>(const
 boost::asio::mutable_buffer & b) Line 427 C++
 tls_test.exe!boost::asio::detail::buffer_sequence_adapter<boost::asio::mutable_buffer,boost::asio::mutable_buffers_1>::validate(const
 boost::asio::mutable_buffers_1 & buffer_sequence) Line 207 C++
 tls_test.exe!boost::asio::detail::win_iocp_socket_recv_op<boost::asio::mutable_buffers_1,boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>
>,boost::asio::ssl::detail::read_op<boost::asio::mutable_buffers_1>,std::function<void
 __cdecl(boost::system::error_code const &,unsigned int)> >
>::do_complete(boost::asio::detail::win_iocp_io_service * owner,
 boost::asio::detail::win_iocp_operation * base, const
 boost::system::error_code & result_ec, unsigned int bytes_transferred)
 Line 72 C++
 tls_test.exe!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service
 & owner, const boost::system::error_code & ec, unsigned int
 bytes_transferred) Line 46 C++
         tls_test.exe!boost::asio::detail::win_iocp_io_service::do_one(bool
 block, boost::system::error_code & ec) Line 409 C++
 tls_test.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code
 & ec) Line 164 C++
 tls_test.exe!boost::asio::io_service::run(boost::system::error_code & ec)
 Line 67 C++
 }}}

 It occurs that completion operation is called after the stream and
 underlined socket was closed and deleted.
 The operation is a dynamically object, created by read_some, but it
 contains link to buffers that application set to it.
 In case of raw socket the buffers are user application buffers without
 checkers. In case of ssl the stream uses its internal buffer for TLS
 operations. And at the moment of the completion operation the stream and
 its buffers are not exist.

-- 
Ticket URL: <https://svn.boost.org/trac10/boost/ticket/13294>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-11-13 23:24:40 UTC