[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.
This commit is contained in:
aokblast authored and GitHub committed 2026-07-13 02:43:35 +00:00
1 parent 692d89dc02
commit 461f0b699c
1 file changed
+12 -3
+12 -3
View File
@@ -587,9 +587,18 @@ public:
}
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.