Race condition in SessionEstablishmentRateLimiter CIDR exemption list

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Networking & Observability
    • ALL
    • N&O 2026-02-02, N&O 2026-03-02, N&O 2026-03-16
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      During a burn in tests run of a test which enables the session establishment rate limiter with some IP exemptions, a race condition was found by a thread sanitizer. The race condition appears to be between updating and checking the snapshot of the CIDR list.

       WARNING: ThreadSanitizer: data race (pid=43304)
         Read of size 8 at 0x722c0001b370 by thread T148 (mutexes: write M0):
           #0 mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot::version() const src/mongo/util/versioned_value.h:107:20 (libtransport_layer_common.so+0xd9566) (BuildId: 0394e7c84f308a62e6fe857ded4c511cf00cd95b)
           #1 mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::isCurrent(mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot const&) const src/mongo/util/versioned_value.h:138:44 (libtransport_layer_common.so+0xd9566)
           #2 mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::refreshSnapshot(mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot&) const src/mongo/util/versioned_value.h:153:13 (libtransport_layer_common.so+0xd9566)
           #3 mongo::transport::SessionEstablishmentRateLimiter::throttleIfNeeded(mongo::Client*) src/mongo/transport/session_establishment_rate_limiter.cpp:94:34 (libtransport_layer_common.so+0xd9566)
           #4 mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0::operator()(mongo::Status) const src/mongo/transport/session_workflow.cpp:879:21 (libsession_manager.so+0x104e3c) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #5 auto mongo::unique_function<void (mongo::Status)>::makeImpl<mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0>(mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0&&)::SpecificImpl::call(mongo::Status&&) src/mongo/util/functional.h:264:21 (libsession_manager.so+0x104e3c)
           #6 mongo::unique_function<void (mongo::Status)>::operator()(mongo::Status) const src/mongo/util/functional.h:222:22 (libsession_manager.so+0x10defb) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #7 mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()::operator()() const src/mongo/transport/session_workflow.cpp:492:38 (libsession_manager.so+0x10defb)
           #8 void mongo::ClientStrand::run<mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()>(mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()) src/mongo/db/client_strand.h:177:16 (libsession_manager.so+0x10defb)
           #9 mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status) src/mongo/transport/session_workflow.cpp:492:28 (libsession_manager.so+0x10dd5e) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #10 auto mongo::unique_function<void (mongo::Status)>::makeImpl<mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)>(mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)&&)::SpecificImpl::call(mongo::Status&&) src/mongo/util/functional.h:264:21 (libsession_manager.so+0x10dd5e)
           #11 mongo::unique_function<void (mongo::Status)>::operator()(mongo::Status) const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xcb5f3) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #12 mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::WorkerThreadInfo::run() src/mongo/transport/service_executor_synchronous.cpp:116:13 (libservice_executor.so+0xcb5f3)
           #13 mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0::operator()() const src/mongo/transport/service_executor_synchronous.cpp:152:12 (libservice_executor.so+0xc9692) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #14 auto mongo::unique_function<void ()>::makeImpl<mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0>(mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0&&)::SpecificImpl::call() src/mongo/util/functional.h:264:21 (libservice_executor.so+0xca59d) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #15 mongo::unique_function<void ()>::operator()() const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xce0bb) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #16 mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0::operator()() src/mongo/transport/service_executor_utils.cpp:119:13 (libservice_executor.so+0xce0bb)
           #17 auto mongo::unique_function<void ()>::makeImpl<mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0>(mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0&&)::SpecificImpl::call() src/mongo/util/functional.h:264:21 (libservice_executor.so+0xce0bb)
           #18 mongo::unique_function<void ()>::operator()() const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xcdcf6) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #19 mongo::transport::(anonymous namespace)::runFunc(void*) src/mongo/transport/service_executor_utils.cpp:63:5 (libservice_executor.so+0xcdcf6)
      
      Previous write of size 8 at 0x722c0001b370 by thread T147 (mutexes: write M1):
           #0 mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot::operator=(mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot&&) src/mongo/util/versioned_value.h:95:11 (libsession_manager.so+0xfafe2) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #1 mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::refreshSnapshot(mongo::VersionedValue<std::vector<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::variant<mongo::CIDR, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>, std::mutex, mongo::versioned_value_detail::DefaultLockPolicy>::Snapshot&) const src/mongo/util/versioned_value.h:154:22 (libtransport_layer_common.so+0xd969d) (BuildId: 0394e7c84f308a62e6fe857ded4c511cf00cd95b)
           #2 mongo::transport::SessionEstablishmentRateLimiter::throttleIfNeeded(mongo::Client*) src/mongo/transport/session_establishment_rate_limiter.cpp:94:34 (libtransport_layer_common.so+0xd969d)
           #3 mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0::operator()(mongo::Status) const src/mongo/transport/session_workflow.cpp:879:21 (libsession_manager.so+0x104e3c) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #4 auto mongo::unique_function<void (mongo::Status)>::makeImpl<mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0>(mongo::transport::SessionWorkflow::Impl::_scheduleIteration()::$_0&&)::SpecificImpl::call(mongo::Status&&) src/mongo/util/functional.h:264:21 (libsession_manager.so+0x104e3c)
           #5 mongo::unique_function<void (mongo::Status)>::operator()(mongo::Status) const src/mongo/util/functional.h:222:22 (libsession_manager.so+0x10defb) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #6 mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()::operator()() const src/mongo/transport/session_workflow.cpp:492:38 (libsession_manager.so+0x10defb)
           #7 void mongo::ClientStrand::run<mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()>(mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status)::'lambda'()) src/mongo/db/client_strand.h:177:16 (libsession_manager.so+0x10defb)
           #8 mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)::operator()(mongo::Status) src/mongo/transport/session_workflow.cpp:492:28 (libsession_manager.so+0x10dd5e) (BuildId: be595408c66ec7f6e50f35033d322666dda24502)
           #9 auto mongo::unique_function<void (mongo::Status)>::makeImpl<mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)>(mongo::transport::SessionWorkflow::Impl::_captureContext(mongo::unique_function<void (mongo::Status)>)::'lambda'(mongo::Status)&&)::SpecificImpl::call(mongo::Status&&) src/mongo/util/functional.h:264:21 (libsession_manager.so+0x10dd5e)
           #10 mongo::unique_function<void (mongo::Status)>::operator()(mongo::Status) const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xcb5f3) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #11 mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::WorkerThreadInfo::run() src/mongo/transport/service_executor_synchronous.cpp:116:13 (libservice_executor.so+0xcb5f3)
           #12 mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0::operator()() const src/mongo/transport/service_executor_synchronous.cpp:152:12 (libservice_executor.so+0xc9692) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #13 auto mongo::unique_function<void ()>::makeImpl<mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0>(mongo::transport::service_executor_synchronous_detail::ServiceExecutorSyncImpl::SharedState::schedule(mongo::unique_function<void (mongo::Status)>, mongo::StringData)::$_0&&)::SpecificImpl::call() src/mongo/util/functional.h:264:21 (libservice_executor.so+0xca59d) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #14 mongo::unique_function<void ()>::operator()() const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xce0bb) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #15 mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0::operator()() src/mongo/transport/service_executor_utils.cpp:119:13 (libservice_executor.so+0xce0bb)
           #16 auto mongo::unique_function<void ()>::makeImpl<mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0>(mongo::transport::launchServiceWorkerThread(mongo::unique_function<void ()>)::$_0&&)::SpecificImpl::call() src/mongo/util/functional.h:264:21 (libservice_executor.so+0xce0bb)
           #17 mongo::unique_function<void ()>::operator()() const src/mongo/util/functional.h:222:22 (libservice_executor.so+0xcdcf6) (BuildId: 5509cf6fafe71ef91ceb2460aed586b5d3dc7d8a)
           #18 mongo::transport::(anonymous namespace)::runFunc(void*) src/mongo/transport/service_executor_utils.cpp:63:5 (libservice_executor.so+0xcdcf6)

            Assignee:
            Didier Nadeau
            Reporter:
            Allison Easton
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: