[RTDB Desktop] Fix use-after-free in WebSocketListenResponse by removing dangling View* pointer - #1890
Conversation
Fix use-after-free in WebSocketListenResponse by removing dangling View* pointer. Fixes an intermittent desktop/Unity ACCESS_VIOLATION crash occurring when a Realtime Database event listener is detached while a WebSocket listen response is still pending.
✅ Integration test succeeded!Requested by @AustinBenoit on commit 1871444 |
There was a problem hiding this comment.
Code Review
This pull request removes the View pointer parameter from the StartListening interface and its implementations, including InfoListenProvider and WebSocketListenProvider. In WebSocketListenResponse, the QuerySpec is now stored and accessed directly instead of through the View object. This resolves an intermittent use-after-free crash (ACCESS_VIOLATION) that occurred when detaching a listener while a WebSocket listen response was pending, as the View could be destroyed before the response was processed. I have no feedback to provide.
| @@ -79,7 +75,7 @@ void WebSocketListenProvider::StartListening(const QuerySpec& query_spec, | |||
|
|
|||
| std::vector<Event> events; | |||
There was a problem hiding this comment.
Add #include <vector> for vector<>
Description
Fixes an intermittent desktop/Unity ACCESS_VIOLATION crash occurring when a Realtime Database event listener is detached while a WebSocket listen response is still pending.
Root Cause:
WebSocketListenResponse stored a raw, non-owning pointer to the query's local View object (const View* view_). When all listeners for a query are removed (e.g., during UI scene teardown or network reconnect churn),
SyncTree synchronously deallocates the View.
However, any in-flight WebSocketListenResponse in the network queue remains active. When the server response completes later, the callback dereferences the freed pointer (response->view()->query_spec()), causing an
immediate memory access violation (often misattributed in Windows crash dumps to public uS::Socket exports due to symbolication snapping).
WebSocketListenResponse already stores QuerySpec query_spec_ by value and uses it in error handling. Updated the success callback to use response->query_spec() directly. Removed the unused const View* view parameter from ListenProvider::StartListening, WebSocketListenResponse, InfoListenProvider, SyncTree::SetupListener, and related unit test mocks.
Testing
Ran integration tests.
Type of Change
Place an
xthe applicable box:Notes
Release Notessection ofrelease_build_files/readme.md.Bugs:
#1881
From Unity:
1391