0

[DNT] Fix NavigationController raw_ptr during WebContents destruction

GetNavigationEntryScreenshotCache() asserts the frame tree is primary.
However during WebContents destruction, the frame tree is reset before
the animator, so the navigation controller (owned by the FrameTree) back
pointer is a UAF.

This CL adds a shortcut to destroy the animator as the "first" thing
during the WebContents's destruction. Then the animator can still
perform the clean up tasks while the navigation controller is still
valid.

Bug: 373898450
Change-Id: I0d793d536ca99700cf7f8c324f562131f2a480c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5948024
Commit-Queue: William Liu <liuwilliam@chromium.org>
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1372744}
This commit is contained in:
William Liu
2024-10-23 16:05:44 +00:00
committed by Chromium LUCI CQ
parent 78f90eeefd
commit 3aef1d167c
11 changed files with 25 additions and 0 deletions

@ -40,6 +40,8 @@ BackForwardTransitionAnimationManagerAndroid::
BackForwardTransitionAnimationManagerAndroid::
~BackForwardTransitionAnimationManagerAndroid() {
// `this` must be destroyed before the `NavigationController`.
CHECK(navigation_controller_);
if (animator_) {
animator_->AbortAnimation(AnimationAbortReason::kAnimationManagerDestroyed);
DestroyAnimator();

@ -1388,6 +1388,11 @@ WebContentsImpl::~WebContentsImpl() {
#endif
find_request_manager_.reset();
// crbug.com/373898450: The `FrameTree` should outlive the animation manager.
if (view_) {
view_->DestroyBackForwardTransitionAnimationManager();
}
// Shutdown the primary FrameTree.
primary_frame_tree_.Shutdown();

@ -126,6 +126,9 @@ class WebContentsView {
// `features::kBackForwardTransitions` is enabled for the supported platform.
virtual BackForwardTransitionAnimationManager*
GetBackForwardTransitionAnimationManager() = 0;
// Reset the above animation manager.
virtual void DestroyBackForwardTransitionAnimationManager() = 0;
};
// Factory function to create `WebContentsView`s. Implemented in the platform

@ -339,6 +339,10 @@ WebContentsViewAndroid::GetBackForwardTransitionAnimationManager() {
return back_forward_animation_manager_.get();
}
void WebContentsViewAndroid::DestroyBackForwardTransitionAnimationManager() {
back_forward_animation_manager_.reset();
}
void WebContentsViewAndroid::ShowContextMenu(RenderFrameHost& render_frame_host,
const ContextMenuParams& params) {
if (is_active_drag_ && drag_exceeded_movement_threshold_)

@ -87,6 +87,7 @@ class WebContentsViewAndroid : public WebContentsView,
void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect) override;
BackForwardTransitionAnimationManager*
GetBackForwardTransitionAnimationManager() override;
void DestroyBackForwardTransitionAnimationManager() override;
// Backend implementation of RenderViewHostDelegateView.
void ShowContextMenu(RenderFrameHost& render_frame_host,

@ -1085,6 +1085,8 @@ WebContentsViewAura::GetBackForwardTransitionAnimationManager() {
return nullptr;
}
void WebContentsViewAura::DestroyBackForwardTransitionAnimationManager() {}
////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, RenderViewHostDelegateView implementation:

@ -220,6 +220,7 @@ class CONTENT_EXPORT WebContentsViewAura
void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect) override;
BackForwardTransitionAnimationManager*
GetBackForwardTransitionAnimationManager() override;
void DestroyBackForwardTransitionAnimationManager() override;
// Overridden from RenderViewHostDelegateView:
void ShowContextMenu(RenderFrameHost& render_frame_host,

@ -157,6 +157,9 @@ WebContentsViewChildFrame::GetBackForwardTransitionAnimationManager() {
return nullptr;
}
void WebContentsViewChildFrame::DestroyBackForwardTransitionAnimationManager() {
}
void WebContentsViewChildFrame::RestoreFocus() {
NOTREACHED_IN_MIGRATION();
}

@ -62,6 +62,7 @@ class WebContentsViewChildFrame : public WebContentsView,
void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect) override;
BackForwardTransitionAnimationManager*
GetBackForwardTransitionAnimationManager() override;
void DestroyBackForwardTransitionAnimationManager() override;
// Backend implementation of RenderViewHostDelegateView.
void ShowContextMenu(RenderFrameHost& render_frame_host,

@ -92,6 +92,7 @@ class WebContentsViewMac : public WebContentsView,
void UpdateWindowControlsOverlay(const gfx::Rect& bounding_rect) override;
BackForwardTransitionAnimationManager*
GetBackForwardTransitionAnimationManager() override;
void DestroyBackForwardTransitionAnimationManager() override;
// RenderViewHostDelegateView:
void StartDragging(const DropData& drop_data,

@ -160,6 +160,8 @@ WebContentsViewMac::GetBackForwardTransitionAnimationManager() {
return nullptr;
}
void WebContentsViewMac::DestroyBackForwardTransitionAnimationManager() {}
void WebContentsViewMac::StartDragging(
const DropData& drop_data,
const url::Origin& source_origin,