mqttcpp
mqttcpp copied to clipboard
Heap Use After Free bug in function Connection::newMessage
I triggered a heap-use-after-free bug reported by AddressSanitizer when fuzzing mqttcpp. This bug occurs when the program tries to read memory that has already been freed, which leads to undefined behavior and potential crashes. In this case, it appears that a Connection object or related resource is prematurely deleted, but the program later attempts to access it, specifically at 0x60e000001840. The error trace indicates that the problem arises in the newMessage method of the Connection class, which interacts with MqttBroker and MqttServer components.
bug Info as following:
=================================================================
==2009913==ERROR: AddressSanitizer: heap-use-after-free on address 0x60e000001840 at pc 0x0000004e4c44 bp 0x7fffb22e85b0 sp 0x7fffb22e85a8
READ of size 1 at 0x60e000001840 thread T0
#0 0x4e4c43 in Connection::newMessage(gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/boost/connection.cpp:45:9
#1 0x4feba3 in MqttBroker<Connection>::publishNode(MqttBroker<Connection>::Node&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/broker.hpp:130:38
#2 0x4f2a6d in MqttBroker<Connection>::publishImpl(MqttBroker<Connection>::Node&, gsl::span<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, -1l>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/broker.hpp:115:57
#3 0x4f2890 in MqttBroker<Connection>::publishImpl(MqttBroker<Connection>::Node&, gsl::span<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, -1l>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/broker.hpp:122:17
#4 0x4efc15 in MqttBroker<Connection>::publish(gsl::span<char const, -1l>, gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/broker.hpp:69:9
#5 0x4ed72a in MqttServer<Connection>::newMessage(Connection&, gsl::span<unsigned char const, -1l>) /root/protocolFuzz/mqtt/mqttcpp/src/server.hpp:40:25
#6 0x4ecf7c in void MqttStream::handleMessages<Connection>(int, MqttServer<Connection>&, Connection&) /root/protocolFuzz/mqtt/mqttcpp/src/stream.hpp:39:20
#7 0x4ec43b in Connection::doRead()::$_0::operator()(boost::system::error_code, unsigned long) const /root/protocolFuzz/mqtt/mqttcpp/src/boost/connection.cpp:34:25
#8 0x4ec43b in boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>::operator()() /usr/include/boost/asio/detail/bind_handler.hpp:164:5
#9 0x4ea80a in void boost::asio::asio_handler_invoke<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&, ...) /usr/include/boost/asio/handler_invoke_hook.hpp:69:3
#10 0x4ea80a in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>, Connection::doRead()::$_0>(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&, Connection::doRead()::$_0&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37:3
#11 0x4ea80a in void boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>, Connection::doRead()::$_0, boost::system::error_code, unsigned long>(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&, boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>*) /usr/include/boost/asio/detail/bind_handler.hpp:207:3
#12 0x4ea80a in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>, boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&, boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37:3
#13 0x4ea80a in void boost::asio::detail::io_object_executor<boost::asio::executor>::dispatch<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>, std::allocator<void> >(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&&, std::allocator<void> const&) const /usr/include/boost/asio/detail/io_object_executor.hpp:119:9
#14 0x4ea80a in void boost::asio::detail::handler_work<Connection::doRead()::$_0, boost::asio::detail::io_object_executor<boost::asio::executor>, boost::asio::detail::io_object_executor<boost::asio::executor> >::complete<boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>&, Connection::doRead()::$_0&) /usr/include/boost/asio/detail/handler_work.hpp:72:15
#15 0x4ea80a in boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, Connection::doRead()::$_0, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:123:9
#16 0x51dca2 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40:5
#17 0x51dca2 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:447:12
#18 0x51c2bd in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:200:10
#19 0x514c11 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:63:24
#20 0x514c11 in MqttTcpServer::run() /root/protocolFuzz/mqtt/mqttcpp/src/boost/mqtt_tcp_server.cpp:30:16
#21 0x4d9e0f in main /root/protocolFuzz/mqtt/mqttcpp/main.cpp:17:16
#22 0x7fb051633082 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:308:16
#23 0x42ebed in _start (/root/protocolFuzz/mqtt/mqttcpp/build/mqtt+0x42ebed)
0x60e000001840 is located 96 bytes inside of 160-byte region [0x60e0000017e0,0x60e000001880)
freed by thread T0 here:
#0 0x4d72fd in operator delete(void*) (/root/protocolFuzz/mqtt/mqttcpp/build/mqtt+0x4d72fd)
#1 0x4eac1b in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:171:10
#2 0x4eac1b in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:730:11
#3 0x4eac1b in std::__shared_ptr<Connection, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:1169:31
#4 0x4eac1b in Connection::doRead()::$_0::~$_0() /root/protocolFuzz/mqtt/mqttcpp/src/boost/connection.cpp:32:9
#5 0x4eac1b in boost::asio::detail::binder2<Connection::doRead()::$_0, boost::system::error_code, unsigned long>::~binder2() /usr/include/boost/asio/detail/bind_handler.hpp:127:7
#6 0x4eac1b in boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, Connection::doRead()::$_0, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:126:3
#7 0x51dca2 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40:5
#8 0x51dca2 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:447:12
#9 0x51c2bd in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:200:10
#10 0x514c11 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:63:24
#11 0x514c11 in MqttTcpServer::run() /root/protocolFuzz/mqtt/mqttcpp/src/boost/mqtt_tcp_server.cpp:30:16
#12 0x4d9e0f in main /root/protocolFuzz/mqtt/mqttcpp/main.cpp:17:16
#13 0x7fb051633082 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:308:16
previously allocated by thread T0 here:
#0 0x4d6a9d in operator new(unsigned long) (/root/protocolFuzz/mqtt/mqttcpp/build/mqtt+0x4d6a9d)
#1 0x536174 in __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
#2 0x536174 in std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:443:20
#3 0x536174 in std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<Connection, std::allocator<Connection>, (__gnu_cxx::_Lock_policy)2> >&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/allocated_ptr.h:97:21
#4 0x536174 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Connection, std::allocator<Connection>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, ConnectionManager&, MqttServer<Connection>&, int>(Connection*&, std::_Sp_alloc_shared_tag<std::allocator<Connection> >, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>&&, ConnectionManager&, MqttServer<Connection>&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:677:19
#5 0x53578c in std::__shared_ptr<Connection, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Connection>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, ConnectionManager&, MqttServer<Connection>&, int>(std::_Sp_alloc_shared_tag<std::allocator<Connection> >, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>&&, ConnectionManager&, MqttServer<Connection>&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:1344:14
#6 0x53578c in std::shared_ptr<Connection>::shared_ptr<std::allocator<Connection>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, ConnectionManager&, MqttServer<Connection>&, int>(std::_Sp_alloc_shared_tag<std::allocator<Connection> >, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>&&, ConnectionManager&, MqttServer<Connection>&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:359:4
#7 0x53578c in std::shared_ptr<Connection> std::allocate_shared<Connection, std::allocator<Connection>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, ConnectionManager&, MqttServer<Connection>&, int>(std::allocator<Connection> const&, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>&&, ConnectionManager&, MqttServer<Connection>&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:701:14
#8 0x53578c in std::shared_ptr<Connection> std::make_shared<Connection, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, ConnectionManager&, MqttServer<Connection>&, int>(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>&&, ConnectionManager&, MqttServer<Connection>&, int&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr.h:717:14
#9 0x53578c in MqttTcpServer::doAccept()::$_1::operator()(boost::system::error_code) const /root/protocolFuzz/mqtt/mqttcpp/src/boost/mqtt_tcp_server.cpp:47:40
#10 0x53578c in boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>::operator()() /usr/include/boost/asio/detail/bind_handler.hpp:65:5
#11 0x5336ca in void boost::asio::asio_handler_invoke<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code> >(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&, ...) /usr/include/boost/asio/handler_invoke_hook.hpp:69:3
#12 0x5336ca in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>, MqttTcpServer::doAccept()::$_1>(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&, MqttTcpServer::doAccept()::$_1&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37:3
#13 0x5336ca in void boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>, MqttTcpServer::doAccept()::$_1, boost::system::error_code>(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&, boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>*) /usr/include/boost/asio/detail/bind_handler.hpp:106:3
#14 0x5336ca in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>, boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code> >(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&, boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37:3
#15 0x5336ca in void boost::asio::detail::io_object_executor<boost::asio::executor>::dispatch<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>, std::allocator<void> >(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&&, std::allocator<void> const&) const /usr/include/boost/asio/detail/io_object_executor.hpp:119:9
#16 0x5336ca in void boost::asio::detail::handler_work<MqttTcpServer::doAccept()::$_1, boost::asio::detail::io_object_executor<boost::asio::executor>, boost::asio::detail::io_object_executor<boost::asio::executor> >::complete<boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code> >(boost::asio::detail::binder1<MqttTcpServer::doAccept()::$_1, boost::system::error_code>&, MqttTcpServer::doAccept()::$_1&) /usr/include/boost/asio/detail/handler_work.hpp:72:15
#17 0x5336ca in boost::asio::detail::reactive_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::ip::tcp, MqttTcpServer::doAccept()::$_1, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/reactive_socket_accept_op.hpp:140:9
#18 0x51dca2 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40:5
#19 0x51dca2 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:447:12
#20 0x51c2bd in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:200:10
#21 0x514c11 in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:63:24
#22 0x514c11 in MqttTcpServer::run() /root/protocolFuzz/mqtt/mqttcpp/src/boost/mqtt_tcp_server.cpp:30:16
#23 0x4d9e0f in main /root/protocolFuzz/mqtt/mqttcpp/main.cpp:17:16
#24 0x7fb051633082 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: heap-use-after-free /root/protocolFuzz/mqtt/mqttcpp/src/boost/connection.cpp:45:9 in Connection::newMessage(gsl::span<unsigned char const, -1l>)
Shadow bytes around the buggy address:
0x0c1c7fff82b0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c1c7fff82c0: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c1c7fff82d0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c1c7fff82e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c1c7fff82f0: fd fd fd fd fa fa fa fa fa fa fa fa fd fd fd fd
=>0x0c1c7fff8300: fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd
0x0c1c7fff8310: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c1c7fff8320: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c1c7fff8330: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c1c7fff8340: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c1c7fff8350: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2009913==ABORTING