diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc index 5cb09d6fa3188..bandaid 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc @@ -67,7 +67,16 @@ RTCStatsCollectorCallbackImpl::RTCStatsCollectorCallbackImpl( : main_thread_(std::move(main_thread)), callback_(std::move(callback)) {} RTCStatsCollectorCallbackImpl::~RTCStatsCollectorCallbackImpl() { - DCHECK(!callback_); + // SECURITY: callback_ holds a cppgc::Persistent (via WrapPersistent in + // RTCPeerConnection::getStats). Persistent allocates from the UNLOCKED + // single-thread PersistentRegion and MUST be destroyed on the main thread. + // If the frame's kInternalMedia task queue was shut down before + // OnStatsDelivered fired, PostCrossThreadTask returned false, + // OnStatsDeliveredOnMainThread never ran, and callback_ is still set here. + // The last ref drops on the signaling thread (via RTCStatsCollector's + // requests_ going out of scope). Destroying callback_ here would race + // PersistentRegion::free_list_head_ with the main thread. Crash safely. + CHECK(!callback_); } void RTCStatsCollectorCallbackImpl::OnStatsDelivered(