From 4468b016ee2d512246051b5b196350a65c203d11 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Wed, 18 Jan 2023 08:03:04 +0000 Subject: [Backport] CVE-2023-0472: Use after free in WebRTC Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/4176412: Delete PeerConnectionHandler in PeerConnection finalizer Also guard against removal of PC during PeerConnectionHandler call that may cause garbage collection. (cherry picked from commit 5066dd66309d884762e5fb9be04b59582893d09a) Bug: chromium:1405256 Change-Id: I9adf7b219e2026e07ccc0868c1a85f3b35cd9d26 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4154578 Commit-Queue: Harald Alvestrand Reviewed-by: Guido Urdaneta Commit-Queue: Guido Urdaneta Cr-Original-Commit-Position: refs/heads/main@{#1091801} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4176412 Auto-Submit: Harald Alvestrand Cr-Commit-Position: refs/branch-heads/5359@{#1347} Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/456883 Reviewed-by: Michal Klocek Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/460492 --- .../modules/peerconnection/rtc_peer_connection.cc | 5 +++-- .../peerconnection/rtc_peer_connection_handler.cc | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index aef2b9f7f8e..636aa342529 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc @@ -893,10 +893,11 @@ RTCPeerConnection::~RTCPeerConnection() { } void RTCPeerConnection::Dispose() { - // Promptly clears the handler's pointer to |this| + // Promptly clears the handler // so that content/ doesn't access it in a lazy sweeping phase. + // Other references to the handler use a weak pointer, preventing access. if (peer_handler_) { - peer_handler_->CloseAndUnregister(); + peer_handler_.reset(); } } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc index 069a56daa38..04b01784d62 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc @@ -837,6 +837,8 @@ class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl if (handler_) { handler_->OnModifySctpTransport(std::move(states.sctp_transport_state)); } + // Since OnSessionDescriptionsUpdated can fire events, it may cause + // garbage collection. Ensure that handler_ is still valid. if (handler_) { handler_->OnModifyTransceivers( states.signaling_state, std::move(states.transceiver_states), @@ -1192,6 +1194,8 @@ bool RTCPeerConnectionHandler::Initialize( CHECK(!initialize_called_); initialize_called_ = true; + // Prevent garbage collection of client_ during processing. + auto* client_on_stack = client_; peer_connection_tracker_ = PeerConnectionTracker::From(*frame); configuration_ = server_configuration; @@ -1229,8 +1233,8 @@ bool RTCPeerConnectionHandler::Initialize( peer_connection_tracker_->RegisterPeerConnection(this, configuration_, options, frame_); } - - return true; + // Gratuitous usage of client_on_stack to prevent compiler errors. + return !!client_on_stack; } bool RTCPeerConnectionHandler::InitializeForTest( @@ -2324,9 +2328,11 @@ void RTCPeerConnectionHandler::OnSessionDescriptionsUpdated( pending_remote_description, std::unique_ptr current_remote_description) { + // Prevent garbage collection of client_ during processing. + auto* client_on_stack = client_; if (!client_ || is_closed_) return; - client_->DidChangeSessionDescriptions( + client_on_stack->DidChangeSessionDescriptions( pending_local_description ? CreateWebKitSessionDescription(pending_local_description.get()) : nullptr, @@ -2644,8 +2650,12 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp, int sdp_mline_index, int component, int address_family) { + // In order to ensure that the RTCPeerConnection is not garbage collected + // from under the function, we keep a pointer to it on the stack. + auto* client_on_stack = client_; DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl"); + // This line can cause garbage collection. auto* platform_candidate = MakeGarbageCollected( sdp, sdp_mid, sdp_mline_index); if (peer_connection_tracker_) { @@ -2665,7 +2675,7 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp, } } if (!is_closed_) - client_->DidGenerateICECandidate(platform_candidate); + client_on_stack->DidGenerateICECandidate(platform_candidate); } void RTCPeerConnectionHandler::OnIceCandidateError( @@ -2677,7 +2687,6 @@ void RTCPeerConnectionHandler::OnIceCandidateError( const String& error_text) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateError"); - if (peer_connection_tracker_) { peer_connection_tracker_->TrackIceCandidateError( this, address, port, host_candidate, url, error_code, error_text); -- cgit v1.2.1