Repository navigation
Refuse addTransceiver on a closed Transport - #1143
Merged
Merged
Conversation
libwebrtc accepts addTransceiver on a closed peer connection. Since m150 it builds the transceiver's media channels immediately, reading the Call object that close() already freed, which crashes on the signaling thread when that memory has been reused. The test adds a transceiver (track and media-type variants, audio and video) to a closed publisher Transport and expects LiveKitError(.invalidState). It fails as an assertion on a plain run and crashes the process under Address Sanitizer or Guard Malloc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: omnigent <noreply@omnigent.ai>
Transport.close() now marks the transport closed before anything else, and both addTransceiver variants throw LiveKitError(.invalidState) from then on instead of reaching the closed peer connection. A publish racing a disconnect or reconnect could otherwise add a transceiver after close(), which since WebRTC m150 reads the peer connection's freed Call on the signaling thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: omnigent <noreply@omnigent.ai>
pblazej
marked this pull request as ready for review
September 30, 2026 21:01
pblazej
requested review from
hiroshihorie and
xianshijing-lk
as code owners
September 30, 2026 21:01
xianshijing-lk
approved these changes
Oct 5, 2026
hiroshihorie
approved these changes
Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Publishing a track while a disconnect or full reconnect closes the publisher peer connection can call
addTransceiveron the already-closed connection. Since LiveKitWebRTC m150,PeerConnection::AddTransceiverhas no closed-state check and eagerly builds the new transceiver's media channels from theCallobject thatclose()already freed, so the app crashes intermittently on WebRTC'ssignaling_thread, depending on whether that memory has been reused.This is an SDK-side workaround for the WebRTC bug, which is fixed at the root in webrtc-sdk/webrtc#301:
Transport.close()now sets a closed flag before anything else, and bothaddTransceivervariants throwLiveKitError(.invalidState)once it is set, so the call never reaches the closed peer connection.TransportCloseTestsadds a transceiver (track and media-type variants, audio and video) to a closed publisher transport and expects that error. It fails without the fix (first commit) and, on m150, crashes the process at the same signaling-thread frame under ASan or Guard Malloc; with the fix it passes 20/20, including under both.Crash stack (LiveKitWebRTC 150.7871.02, iOS arm64, re-symbolicated from image offsets)