[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:
1 parent
692d89dc02
commit
461f0b699c
1 file changed
+12
-3
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user