tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 713f5ece389e5109cb667ea87d07e984119ebf4a
parent 27fe3d48f511e2dd708e687836ece8d357c9dceb
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon,  1 Dec 2025 19:56:56 -0700

Bug 2000941 - Vendor libwebrtc from 794b74e21f

Upstream commit: https://webrtc.googlesource.com/src/+/794b74e21fedd7b288227e1119474303963373d7
    Add field trial WebRTC-SynchronousDestructors for synchronous destructor

    And implemented it for destruction of MediaEngine in ConnectionContext.

    Having it as a PostTask means that it can happen arbitrarely
    later...if worker thread is loaded...which it can be, in some
    apps. The asynchronous destruction of MediaEngine means
    that audio "data" can flow through the system even
    after the destructor of PeerConnectionFactory has been
    run.

    Work in progress doc: https://docs.google.com/document/d/1tZHCWfCjIFtPHtm_tg9hAksHJ-JOurASckv4k-aJInw/edit?usp=sharing

    And related bug: webrtc:14449

    Bug: webrtc:443588673
    Change-Id: I2d0f117ca13fe166d913d71af1ba1e6ff8598b63
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/408745
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Reviewed-by: Peter Hanspers <peterhanspers@webrtc.org>
    Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
    Reviewed-by: Markus Handell <handellm@webrtc.org>
    Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45633}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/experiments/field_trials.py | 3+++
Mthird_party/libwebrtc/pc/connection_context.cc | 17++++++++++++++++-
Mthird_party/libwebrtc/pc/connection_context.h | 3++-
4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T02:53:17.333192+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T02:56:37.611882+00:00. # base of lastest vendoring -5efb280e2b +794b74e21f diff --git a/third_party/libwebrtc/experiments/field_trials.py b/third_party/libwebrtc/experiments/field_trials.py @@ -179,6 +179,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-SwitchEncoderFollowCodecPreferenceOrder', 378566918, date(2025, 5, 1)), + FieldTrial('WebRTC-SynchronousDestructors', + 443588673, + date(2026, 7, 1)), FieldTrial('WebRTC-PayloadTypesInTransport', 360058654, date(2025, 9, 11)), diff --git a/third_party/libwebrtc/pc/connection_context.cc b/third_party/libwebrtc/pc/connection_context.cc @@ -175,12 +175,27 @@ ConnectionContext::ConnectionContext( // this isn't necessary. worker_thread_->BlockingCall([&] { media_engine_->Init(); }); } + + blocking_media_engine_destruction_ = + env.field_trials().IsEnabled("WebRTC-SynchronousDestructors"); } ConnectionContext::~ConnectionContext() { RTC_DCHECK_RUN_ON(signaling_thread_); // `media_engine_` requires destruction to happen on the worker thread. - worker_thread_->PostTask([media_engine = std::move(media_engine_)] {}); + if (blocking_media_engine_destruction_) { + // The media engine shares its Environment with objects that may outlive + // the ConnectionContext if this call is not blocking. If Environment is + // destroyed when ConnectionContext's destruction completes, this may + // cause Use-After-Free. + // + // The plan is to address the problem with a new Terminate(callback) method, + // which is referenced in webrtc:443588673, but pending this one can + // control this with field trial `WebRTC-SynchronousDestructors`. + worker_thread_->BlockingCall([&] { media_engine_ = nullptr; }); + } else { + worker_thread_->PostTask([media_engine = std::move(media_engine_)] {}); + } // Make sure `worker_thread()` and `signaling_thread()` outlive // `default_socket_factory_` and `default_network_manager_`. diff --git a/third_party/libwebrtc/pc/connection_context.h b/third_party/libwebrtc/pc/connection_context.h @@ -100,12 +100,13 @@ class ConnectionContext final : public RefCountedNonVirtual<ConnectionContext> { ~ConnectionContext(); private: - // The following three variables are used to communicate between the + // The following four variables are used to communicate between the // constructor and the destructor, and are never exposed externally. bool wraps_current_thread_; std::unique_ptr<SocketFactory> owned_socket_factory_; std::unique_ptr<Thread> owned_network_thread_ RTC_GUARDED_BY(signaling_thread_); + bool blocking_media_engine_destruction_; Thread* const network_thread_; AlwaysValidPointer<Thread> const worker_thread_; Thread* const signaling_thread_;