Author: aokblast Date: 2026-07-13T02:43:35Z New Revision: 461f0b699c8dbcafaec0e4b2d171d42ee05f6999
URL: https://github.com/llvm/llvm-project/commit/461f0b699c8dbcafaec0e4b2d171d42ee05f6999 DIFF: https://github.com/llvm/llvm-project/commit/461f0b699c8dbcafaec0e4b2d171d42ee05f6999.diff LOG: [LLDB] Fix use-after-free destroying a Binder from its OnClosed handler (#209019) transport::Binder::OnClosed() holds m_mutex (a recursive_mutex) while invoking m_disconnect_handler. In the MCP server, that handler removes the disconnected client, which owns the transport and therefore the Binder itself. As a result, the Binder -- and its m_mutex -- are destroyed while the scoped_lock in OnClosed still holds the lock. This is a use-after-free everywhere, as the lock guard later unlocks freed memory. Move the disconnect handler out of the critical section and release the lock before invoking it, so the Binder can be safely destroyed without holding or destroying a locked mutex. Added: Modified: lldb/include/lldb/Host/JSONTransport.h Removed: ################################################################################ diff --git a/lldb/include/lldb/Host/JSONTransport.h b/lldb/include/lldb/Host/JSONTransport.h index 87adbbc04eeda..d3c6e8e101ad5 100644 --- a/lldb/include/lldb/Host/JSONTransport.h +++ b/lldb/include/lldb/Host/JSONTransport.h @@ -587,9 +587,18 @@ class Binder : public JSONTransport<Proto>::MessageHandler { } void OnClosed() override { - std::scoped_lock<std::recursive_mutex> guard(m_mutex); - if (m_disconnect_handler) - m_disconnect_handler(); + // The disconnect handler may destroy this Binder -- e.g. the server + // removes the disconnected client, which owns the transport and, with it, + // this handler. Move the handler out and release the lock before invoking + // it, so we neither run the teardown while holding m_mutex nor destroy a + // still-locked mutex. + Callback<void()> disconnect_handler; + { + std::scoped_lock<std::recursive_mutex> guard(m_mutex); + disconnect_handler = std::move(m_disconnect_handler); + } + if (disconnect_handler) + disconnect_handler(); } /// Fails every in-flight outgoing request, invoking its reply with an error. _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
