ASAN显示boost :: asio在套接字上调用pure recv时释放堆后使用

时间:2019-03-07 09:38:47

标签: c++ c++11 boost address-sanitizer

我有大约100个打开的TCP套接字,监视一些远程设备。这是纯主从通信。服务器是主服务器(连接到设备)而设备是从设备。

主设备会定期将请求发送到所有设备,并等待一些时间来响应。仅在发送操作被认为成功(调用处理程序handle_send)之后,套接字才会触发async_read_some,直到消息完成。服务器收到好消息后,它将停止启动async_read_some,因为它不再应该接收任何消息。

随机地,ASAN会在recv阶段抱怨未分配的缓冲区(当调用实际系统调用'recvmsg'时[请参见boost 1.66 /usr/include/boost/asio/detail/impl/socket_ops.ipp:784] )

我们在linux机器上,当我使用boost 1.53时也会发生同样的问题

这是堆栈跟踪:

==7779==ERROR: AddressSanitizer: heap-use-after-free on address 0x611001478a40 at pc 0x503308 bp 0x7ffdea424a70 sp 0x7ffdea424a40
WRITE of size 53 at 0x611001478a40 thread T0
\#0 0x503307 in __interceptor_recvmsg (/usr/tsp/bin/tspinger+0x503307)
\#1 0x8a62c7 in boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:784
\#2 0x8a5457 in boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:877
\#3 0x8a4ac3 in boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:55
\#4 0x681c4e in boost::asio::detail::reactor_op::perform() /usr/include/boost/asio/detail/reactor_op.hpp:44
\#5 0x6f9a98 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:743
\#6 0x6f8a30 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:774
\#7 0x603207 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
\#8 0x5fe649 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:401
\#9 0x5fc7d1 in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:154
\#10 0x5e5e85 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:62
0x611001478a40 is located 0 bytes inside of 209-byte region [0x611001478a40,0x611001478b11)
freed by thread T0 here:
==7779==AddressSanitizer CHECK failed: /builddir/build/BUILD/llvm-3.4.2.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cc:184 "((id & (1u << 31))) == ((0))" (0x80000000, 0x0)
\#0 0x52fe0f in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/tsp/bin/tspinger+0x52fe0f)
\#1 0x535671 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/tsp/bin/tspinger+0x535671)
\#2 0x53bb8d in __sanitizer::StackDepotGet(unsigned int, unsigned long*) (/usr/tsp/bin/tspinger+0x53bb8d)
\#3 0x4f0c54 in __asan::AsanChunkView::GetFreeStack(__sanitizer::StackTrace*) (/usr/tsp/bin/tspinger+0x4f0c54)
\#4 0x52d096 in __asan::DescribeHeapAddress(unsigned long, unsigned long) (/usr/tsp/bin/tspinger+0x52d096)
\#5 0x52e211 in __asan_report_error (/usr/tsp/bin/tspinger+0x52e211)
\#6 0x503323 in __interceptor_recvmsg (/usr/tsp/bin/tspinger+0x503323)
\#7 0x8a62c7 in boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:784
\#8 0x8a5457 in boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) /usr/include/boost/asio/detail/impl/socket_ops.ipp:877
\#9 0x8a4ac3 in boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:55
\#10 0x681c4e in boost::asio::detail::reactor_op::perform() /usr/include/boost/asio/detail/reactor_op.hpp:44
\#11 0x6f9a98 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:743
\#12 0x6f8a30 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:774
\#13 0x603207 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
\#14 0x5fe649 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:401
\#15 0x5fc7d1 in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:154
\#16 0x5e5e85 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:62

现在在async_read中声明的RX缓冲区有些称为

m_invector = vector<byte>(RX_BUFFER_SIZE);
socket_.async_read_some(boost::asio::buffer(m_invector),
                   std::bind(&RemoteObject::handle_read, shared_from_this(),
                      std::placeholders::_1, std::placeholders::_2));

因此,启动async_read_some时,缓冲区总是干净的。 为了完成,我为非Windows系统添加了boost recv例程

signed_size_type recv(socket_type s, buf* bufs, size_t count,
    int flags, boost::system::error_code& ec)
{
  clear_last_error();
  msghdr msg = msghdr();
  msg.msg_iov = bufs;
  msg.msg_iovlen = static_cast<int>(count);
  signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); //LINE 784
  if (result >= 0)
    ec = boost::system::error_code();
  return result;
}

我不明白这一点:ASAN显示了相同的内存使用和空闲点,即boost / asio / detail / impl / socket_ops.ipp:784:这是系统的recvmsg调用。

您有任何线索吗?

谢谢。

0 个答案:

没有答案