chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.85k stars 1.21k forks source link

AddrSan - heap-use-after-free due to double-free of Object*, possibly in epoll_reactor #268

Open Olipro opened 6 years ago

Olipro commented 6 years ago

Somewhere after commit hash 524288, I've had addrsan complaining on a particular test about a heap-use-after-free.

It appears to be caused by a double-free since if I edit object_pool.hpp so that the free() function checks if o == free_list_ and returns immediately the problem goes away. Without the change, we end up with the object in the free list having next-> pointing to itself. Obviously the underlying problem needs to be fixed but I've submitted a pull request just in case. (see #269 )

Here's the AddrSan output:


==40103==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f000007ee8 at pc 0x0000006484ad bp 0x7ffe75219ba0 sp 0x7ffe75219b98
    READ of size 8 at 0x60f000007ee8 thread T0
        #0 0x6484ac in asio::detail::object_pool<asio::detail::epoll_reactor::descriptor_state>::destroy_list(asio::detail::epoll_reactor::descriptor_state*) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:154:14
        #1 0x6461bd in asio::detail::object_pool<asio::detail::epoll_reactor::descriptor_state>::~object_pool() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:78:5
        #2 0x646465 in asio::detail::epoll_reactor::~epoll_reactor() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:70:1
        #3 0x6464d8 in asio::detail::epoll_reactor::~epoll_reactor() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:65:1
        #4 0x56ea28 in asio::detail::service_registry::destroy(asio::execution_context::service*) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/service_registry.ipp:109:3
        #5 0x56e95f in asio::detail::service_registry::destroy_services() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/service_registry.ipp:53:5
        #6 0x56e73c in asio::execution_context::destroy() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/execution_context.ipp:45:22
        #7 0x56da36 in asio::execution_context::~execution_context() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/execution_context.ipp:34:3
        #8 0x5b8044 in asio::io_context::~io_context() **/home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/io_context.ipp:56:1

    0x60f000007ee8 is located 24 bytes inside of 168-byte region [0x60f000007ed0,0x60f000007f78)
    freed by thread T0 here:
        #0 0x561440 in operator delete(void*) /home/oliver/llvm-5.0.0.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:137
        #1 0x64851f in void asio::detail::object_pool_access::destroy<asio::detail::epoll_reactor::descriptor_state>(asio::detail::epoll_reactor::descriptor_state*) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:46:5
        #2 0x6484c0 in asio::detail::object_pool<asio::detail::epoll_reactor::descriptor_state>::destroy_list(asio::detail::epoll_reactor::descriptor_state*) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:155:7
        #3 0x6461bd in asio::detail::object_pool<asio::detail::epoll_reactor::descriptor_state>::~object_pool() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:78:5
        #4 0x646465 in asio::detail::epoll_reactor::~epoll_reactor() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:70:1
        #5 0x6464d8 in asio::detail::epoll_reactor::~epoll_reactor() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:65:1
        #6 0x56ea28 in asio::detail::service_registry::destroy(asio::execution_context::service*) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/service_registry.ipp:109:3
        #7 0x56e95f in asio::detail::service_registry::destroy_services() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/service_registry.ipp:53:5
        #8 0x56e73c in asio::execution_context::destroy() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/execution_context.ipp:45:22
        #9 0x56da36 in asio::execution_context::~execution_context() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/execution_context.ipp:34:3
        #10 0x5b8044 in asio::io_context::~io_context() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/io_context.ipp:56:1

    previously allocated by thread T83 here:
        #0 0x5606c8 in operator new(unsigned long) /home/oliver/llvm-5.0.0.src/projects/compiler-rt/lib/asan/asan_new_delete.cc:92
        #1 0x64cc09 in asio::detail::epoll_reactor::descriptor_state* asio::detail::object_pool_access::create<asio::detail::epoll_reactor::descriptor_state, bool>(bool) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:40:12
        #2 0x64ca83 in asio::detail::epoll_reactor::descriptor_state* asio::detail::object_pool<asio::detail::epoll_reactor::descriptor_state>::alloc<bool>(bool) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/object_pool.hpp:113:11
        #3 0x64c88e in asio::detail::epoll_reactor::allocate_descriptor_state() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:609:34
        #4 0x64b9b9 in asio::detail::epoll_reactor::register_descriptor(int, asio::detail::epoll_reactor::descriptor_state*&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:153:21
        #5 0x6b31de in asio::detail::reactive_socket_service_base::do_assign(asio::detail::reactive_socket_service_base::base_implementation_type&, int, int const&, std::error_code&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp:214:26
        #6 0x6b2da0 in asio::detail::reactive_socket_service<asio::ip::tcp>::assign(asio::detail::reactive_socket_service<asio::ip::tcp>::implementation_type&, asio::ip::tcp const&, int const&, std::error_code&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/reactive_socket_service.hpp:137:10
        #7 0x6b2aab in asio::basic_socket<asio::ip::tcp>::assign(asio::ip::tcp const&, int const&, std::error_code&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/basic_socket.hpp:391:25
        #8 0x6b27b8 in asio::detail::reactive_socket_accept_op_base<asio::basic_socket<asio::ip::tcp>, asio::ip::tcp>::do_assign() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp:72:13
        #9 0x687b67 in asio::detail::reactive_socket_accept_op<asio::basic_socket<asio::ip::tcp>, asio::ip::tcp, Mimecast::MCDNSProxy::ReceiveTCPRequest(asio::basic_socket_acceptor<asio::ip::tcp>&)::$_5>::do_complete(void*, asio::detail::scheduler_operation*, std::error_code const&, unsigned long) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp:116:10
        #10 0x64d597 in asio::detail::scheduler_operation::complete(void*, std::error_code const&, unsigned long) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/scheduler_operation.hpp:39:5
        #11 0x64cdd3 in asio::detail::epoll_reactor::descriptor_state::do_complete(void*, asio::detail::scheduler_operation*, std::error_code const&, unsigned long) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/epoll_reactor.ipp:757:11
        #12 0x64d597 in asio::detail::scheduler_operation::complete(void*, std::error_code const&, unsigned long) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/scheduler_operation.hpp:39:5
        #13 0x6a418b in asio::detail::scheduler::do_run_one(asio::detail::conditionally_enabled_mutex::scoped_lock&, asio::detail::scheduler_thread_info&, std::error_code const&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/scheduler.ipp:400:12
        #14 0x6a35d6 in asio::detail::scheduler::run(std::error_code&) /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/detail/impl/scheduler.ipp:153:10
        #15 0x6a32e0 in asio::io_context::run() /home/oliver/Projects/asioproj/build/debug/asio/asio/include/asio/impl/io_context.ipp:61:24`
vinniefalco commented 6 years ago

Seems related to https://github.com/boostorg/asio/commit/aa0bf0a8b34815cbf4ecac9e36c2a809385bd458