Skip to content

Application using Boost.Asio crashes when linked with Launch Darkly C++ Client #590

Description

@planetmarshall

Describe the bug

An application using the Boost Asio library crashes when linked with the Launch Darkly C++ client. When run with Address Sanitizer, a heap buffer overflow is reported

To reproduce

Use the Dockerfile in the attached archive to reproduce the issue. In summary -

$ docker build . -t ld-crash
$ docker run --rm ld-crash test-asio

(Expected output)
Error connecting to websocket: connect: Connection refused [system:111 at /usr/local/include/boost/asio/detail/reactive_socket_service.hpp:588:5 in function 'boost::system::error_code boost::asio::detail::reactive_socket_service<Protocol>::connect(implementation_type&, const endpoint_type&, boost::system::error_code&)']

$ docker run --rm ld-crash test-asio-ld

==1==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c71e2fe0108 
...
==1==ABORTING
(see below for full output)

Expected behavior

A program correctly using the Boost ASIO library should function regardless if it is linked with the launchdarkly client library

Logs

Address Sanitizer Output
==130==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7ce954fe0108 at pc 0x0000004901e1 bp 0x7ffd51b32b50 sp 0x7ffd51b32b48
WRITE of size 4 at 0x7ce954fe0108 thread T0
    #0 0x0000004901e0 in boost::asio::detail::conditionally_enabled_mutex<boost::asio::detail::posix_mutex>::conditionally_enabled_mutex(bool, int) /usr/local/include/boost/asio/detail/conditionally_enabled_mutex.hpp:126
    #1 0x00000043dec7 in boost::asio::detail::epoll_reactor::epoll_reactor(boost::asio::execution_context&) /usr/local/include/boost/asio/detail/impl/epoll_reactor.ipp:54
    #2 0x00000042da1e in boost::asio::detail::epoll_reactor* boost::asio::detail::allocate_object<boost::asio::detail::epoll_reactor, boost::asio::execution_context::allocator<void>, boost::asio::execution_context&>(boost::asio::execution_context::allocator<void> const&, boost::asio::execution_context&) /usr/local/include/boost/asio/detail/memory.hpp:71
    #3 0x00000042d51f in boost::asio::execution_context::service* boost::asio::detail::service_registry::create<boost::asio::detail::epoll_reactor, boost::asio::execution_context>(boost::asio::execution_context&, void*) /usr/local/include/boost/asio/detail/impl/service_registry.hpp:100
    #4 0x000000451c6f in boost::asio::detail::service_registry::do_use_service(boost::asio::execution_context::service::key const&, boost::asio::execution_context::service* (*)(boost::asio::execution_context&, void*), void*) /usr/local/include/boost/asio/detail/impl/service_registry.ipp:139
    #5 0x00000042caa0 in boost::asio::detail::epoll_reactor& boost::asio::detail::service_registry::use_service<boost::asio::detail::epoll_reactor>() /usr/local/include/boost/asio/detail/impl/service_registry.hpp:31
    #6 0x00000042b071 in boost::asio::detail::epoll_reactor& boost::asio::use_service<boost::asio::detail::epoll_reactor>(boost::asio::execution_context&) /usr/local/include/boost/asio/impl/execution_context.hpp:105
    #7 0x000000448890 in boost::asio::detail::reactive_socket_service_base::reactive_socket_service_base(boost::asio::execution_context&) /usr/local/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:36
    #8 0x00000042c548 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>::reactive_socket_service(boost::asio::execution_context&) /usr/local/include/boost/asio/detail/reactive_socket_service.hpp:82
    #9 0x00000042ad80 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>* boost::asio::detail::allocate_object<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::execution_context::allocator<void>, boost::asio::execution_context&>(boost::asio::execution_context::allocator<void> const&, boost::asio::execution_context&) /usr/local/include/boost/asio/detail/memory.hpp:71
    #10 0x000000429c31 in boost::asio::execution_context::service* boost::asio::detail::service_registry::create<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::execution_context>(boost::asio::execution_context&, void*) /usr/local/include/boost/asio/detail/impl/service_registry.hpp:100
    #11 0x000000451c6f in boost::asio::detail::service_registry::do_use_service(boost::asio::execution_context::service::key const&, boost::asio::execution_context::service* (*)(boost::asio::execution_context&, void*), void*) /usr/local/include/boost/asio/detail/impl/service_registry.ipp:139
    #12 0x000000429122 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>& boost::asio::detail::service_registry::use_service<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp> >() /usr/local/include/boost/asio/detail/impl/service_registry.hpp:31
    #13 0x0000004272d7 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>& boost::asio::use_service<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp> >(boost::asio::execution_context&) /usr/local/include/boost/asio/impl/execution_context.hpp:105
    #14 0x000000424700 in boost::asio::detail::io_object_impl<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::any_io_executor>::io_object_impl(int, boost::asio::any_io_executor const&) /usr/local/include/boost/asio/detail/io_object_impl.hpp:49
    #15 0x000000421e0b in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>::basic_socket(boost::asio::any_io_executor const&) /usr/local/include/boost/asio/basic_socket.hpp:122
    #16 0x00000041faac in boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>::basic_stream_socket(boost::asio::any_io_executor const&) /usr/local/include/boost/asio/basic_stream_socket.hpp:105
    #17 0x00000041cbaa in boost::empty_::empty_value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, 0u, false>::empty_value<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>>(boost::empty_init_t, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/core/empty_value.hpp:69
    #18 0x0000004197ff in boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type::impl_type<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/beast/websocket/impl/stream_impl.hpp:134
    #19 0x000000416bd5 in boost::detail::sp_if_not_array<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type>::type boost::make_shared<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/smart_ptr/make_shared_object.hpp:230
    #20 0x000000414b00 in boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::stream<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/beast/websocket/impl/stream.hpp:54
    #21 0x0000004129ea in std::__detail::_MakeUniq<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true> >::__single_object std::make_unique<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/c++/16.1.0/bits/unique_ptr.h:1086
    #22 0x00000040a760 in ws_connect /work/main.cpp:19
    #23 0x00000040a9f7 in main /work/main.cpp:25
    #24 0x7ff955dd9ca7  (/lib/x86_64-linux-gnu/libc.so.6+0x29ca7) (BuildId: c495b62edadd6c356265942ec1282d98058a7b41)
    #25 0x7ff955dd9d64 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29d64) (BuildId: c495b62edadd6c356265942ec1282d98058a7b41)
    #26 0x00000040a350 in _start (/work/build/test-asio-ld+0x40a350)

0x7ce954fe0108 is located 33 bytes after 167-byte region [0x7ce954fe0040,0x7ce954fe00e7)
allocated by thread T0 here:
    #0 0x7ff9571fb43f in operator new(unsigned long) (/usr/local/lib64/libasan.so.8+0x12543f)
    #1 0x0000004abb95 in std::__new_allocator<unsigned char>::allocate(unsigned long, void const*) /usr/local/include/c++/16.1.0/bits/new_allocator.h:162
    #2 0x0000004aaae0 in std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned long) /usr/local/include/c++/16.1.0/bits/alloc_traits.h:638
    #3 0x0000004aaae0 in boost::asio::execution_context::allocator_impl<std::allocator<void> >::allocate(unsigned long, unsigned long) /usr/local/include/boost/asio/impl/execution_context.hpp:63
    #4 0x00000042e12b in boost::asio::execution_context::allocator<boost::asio::detail::epoll_reactor>::allocate(unsigned long) const /usr/local/include/boost/asio/execution_context.hpp:405
    #5 0x00000042d942 in std::allocator_traits<boost::asio::execution_context::allocator<boost::asio::detail::epoll_reactor> >::allocate(boost::asio::execution_context::allocator<boost::asio::detail::epoll_reactor>&, unsigned long) /usr/local/include/c++/16.1.0/bits/alloc_traits.h:385
    #6 0x00000042d9ed in boost::asio::detail::epoll_reactor* boost::asio::detail::allocate_object<boost::asio::detail::epoll_reactor, boost::asio::execution_context::allocator<void>, boost::asio::execution_context&>(boost::asio::execution_context::allocator<void> const&, boost::asio::execution_context&) /usr/local/include/boost/asio/detail/memory.hpp:66
    #7 0x00000042d51f in boost::asio::execution_context::service* boost::asio::detail::service_registry::create<boost::asio::detail::epoll_reactor, boost::asio::execution_context>(boost::asio::execution_context&, void*) /usr/local/include/boost/asio/detail/impl/service_registry.hpp:100
    #8 0x000000451c6f in boost::asio::detail::service_registry::do_use_service(boost::asio::execution_context::service::key const&, boost::asio::execution_context::service* (*)(boost::asio::execution_context&, void*), void*) /usr/local/include/boost/asio/detail/impl/service_registry.ipp:139
    #9 0x00000042caa0 in boost::asio::detail::epoll_reactor& boost::asio::detail::service_registry::use_service<boost::asio::detail::epoll_reactor>() /usr/local/include/boost/asio/detail/impl/service_registry.hpp:31
    #10 0x00000042b071 in boost::asio::detail::epoll_reactor& boost::asio::use_service<boost::asio::detail::epoll_reactor>(boost::asio::execution_context&) /usr/local/include/boost/asio/impl/execution_context.hpp:105
    #11 0x000000448890 in boost::asio::detail::reactive_socket_service_base::reactive_socket_service_base(boost::asio::execution_context&) /usr/local/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:36
    #12 0x00000042c548 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>::reactive_socket_service(boost::asio::execution_context&) /usr/local/include/boost/asio/detail/reactive_socket_service.hpp:82
    #13 0x00000042ad80 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>* boost::asio::detail::allocate_object<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::execution_context::allocator<void>, boost::asio::execution_context&>(boost::asio::execution_context::allocator<void> const&, boost::asio::execution_context&) /usr/local/include/boost/asio/detail/memory.hpp:71
    #14 0x000000429c31 in boost::asio::execution_context::service* boost::asio::detail::service_registry::create<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::execution_context>(boost::asio::execution_context&, void*) /usr/local/include/boost/asio/detail/impl/service_registry.hpp:100
    #15 0x000000451c6f in boost::asio::detail::service_registry::do_use_service(boost::asio::execution_context::service::key const&, boost::asio::execution_context::service* (*)(boost::asio::execution_context&, void*), void*) /usr/local/include/boost/asio/detail/impl/service_registry.ipp:139
    #16 0x000000429122 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>& boost::asio::detail::service_registry::use_service<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp> >() /usr/local/include/boost/asio/detail/impl/service_registry.hpp:31
    #17 0x0000004272d7 in boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>& boost::asio::use_service<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp> >(boost::asio::execution_context&) /usr/local/include/boost/asio/impl/execution_context.hpp:105
    #18 0x000000424700 in boost::asio::detail::io_object_impl<boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp>, boost::asio::any_io_executor>::io_object_impl(int, boost::asio::any_io_executor const&) /usr/local/include/boost/asio/detail/io_object_impl.hpp:49
    #19 0x000000421e0b in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>::basic_socket(boost::asio::any_io_executor const&) /usr/local/include/boost/asio/basic_socket.hpp:122
    #20 0x00000041faac in boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>::basic_stream_socket(boost::asio::any_io_executor const&) /usr/local/include/boost/asio/basic_stream_socket.hpp:105
    #21 0x00000041cbaa in boost::empty_::empty_value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, 0u, false>::empty_value<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>>(boost::empty_init_t, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/core/empty_value.hpp:69
    #22 0x0000004197ff in boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type::impl_type<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/beast/websocket/impl/stream_impl.hpp:134
    #23 0x000000416bd5 in boost::detail::sp_if_not_array<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type>::type boost::make_shared<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::impl_type, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/smart_ptr/make_shared_object.hpp:230
    #24 0x000000414b00 in boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>::stream<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/boost/beast/websocket/impl/stream.hpp:54
    #25 0x0000004129ea in std::__detail::_MakeUniq<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true> >::__single_object std::make_unique<boost::beast::websocket::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, true>, boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >(boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul>&&) /usr/local/include/c++/16.1.0/bits/unique_ptr.h:1086
    #26 0x00000040a760 in ws_connect /work/main.cpp:19
    #27 0x00000040a9f7 in main /work/main.cpp:25
    #28 0x7ff955dd9ca7  (/lib/x86_64-linux-gnu/libc.so.6+0x29ca7) (BuildId: c495b62edadd6c356265942ec1282d98058a7b41)

SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/local/include/boost/asio/detail/conditionally_enabled_mutex.hpp:126 in boost::asio::detail::conditionally_enabled_mutex<boost::asio::detail::posix_mutex>::conditionally_enabled_mutex(bool, int)
Shadow bytes around the buggy address:
  0x7ce954fdfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ce954fdff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ce954fdff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ce954fe0000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x7ce954fe0080: 00 00 00 00 00 00 00 00 00 00 00 00 07 fa fa fa
=>0x7ce954fe0100: fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7ce954fe0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7ce954fe0200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7ce954fe0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7ce954fe0300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7ce954fe0380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==130==ABORTING

SDK version
3.11.3

Language version, developer tools

Debian trixie
GCC 16
Boost 1.91.0
See attached Dockerfile for full details

OS/platform
Debian Trixie.
See attached Dockerfile for full details

Additional context
The issue appears to have been introduced by the addition of a slim_mutex implementation in Boost ASIO.

The issue does not reproduce on Boost versions <1.91.0 or by compiling both launchdarkly and the client application

with -DBOOST_ASIO_HAS_STD_ATOMIC_WAIT=0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpackage: sdk/clientIssues affecting the C++ Client SDK

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions