summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer
diff options
context:
space:
mode:
authorDave Tapuska <dtapuska@chromium.org>2022-01-04 22:52:37 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2022-03-03 16:56:34 +0000
commitb0e4ccd60b2b4982989edc919fd31dd289da3942 (patch)
tree1acac6ce9ca791118bf961748fb3ebe2d8d926d2 /chromium/third_party/blink/renderer
parent5610f64967dd3081d8be529be4499e81a323dd12 (diff)
downloadqtwebengine-chromium-b0e4ccd60b2b4982989edc919fd31dd289da3942.tar.gz
[Backport] CVE-2022-0460: Use after free in Window Dialog
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/3247534: Cancel WebPagePopup immediately on WebViewImpl::Close. If we have a WebPagePopup cancel it immediately. Detaching it from the layout was the handled via Detaching the layout nodes but that is slightly complex. Call cancel before we destroy the layout tree. BUG=1250227 Change-Id: I8707e59a3c99a57a16d8b8d8cb35213a33365833 Reviewed-by: Stefan Zager <szager@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Dave Tapuska <dtapuska@chromium.org> Cr-Commit-Position: refs/heads/main@{#955417} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer')
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc56
2 files changed, 57 insertions, 3 deletions
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
index 9c1a8efc351..8f5fe5f0d44 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1410,6 +1410,10 @@ void WebViewImpl::Close() {
DCHECK(AllInstances().Contains(this));
AllInstances().erase(this);
+ // Ensure if we have a page popup we cancel it immediately as we do not
+ // want page popups to re-enter WebViewImpl during our shutdown.
+ CancelPagePopup();
+
// Initiate shutdown for the entire frameset. This will cause a lot of
// notifications to be sent. This will detach all frames in this WebView's
// frame tree.
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
index 46e116800e5..5c14ad4c31a 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -166,7 +166,9 @@ class CompositorAnimationTimeline;
ChromeClientImpl::ChromeClientImpl(WebViewImpl* web_view)
: web_view_(web_view),
cursor_overridden_(false),
- did_request_non_empty_tool_tip_(false) {}
+ did_request_non_empty_tool_tip_(false) {
+ DCHECK(web_view_);
+}
ChromeClientImpl::~ChromeClientImpl() {
DCHECK(file_chooser_queue_.IsEmpty());
@@ -183,10 +185,13 @@ WebViewImpl* ChromeClientImpl::GetWebView() const {
}
void ChromeClientImpl::ChromeDestroyed() {
- // Our lifetime is bound to the WebViewImpl.
+ // Clear |web_view_| since it is refcounted and this class is a GC'd object
+ // and may outlive the WebViewImpl.
+ web_view_ = nullptr;
}
void ChromeClientImpl::SetWindowRect(const IntRect& r, LocalFrame& frame) {
+ DCHECK(web_view_);
DCHECK_EQ(&frame, web_view_->MainFrameImpl()->GetFrame());
web_view_->MainFrameViewWidget()->SetWindowRect(r);
}
@@ -199,10 +204,12 @@ IntRect ChromeClientImpl::RootWindowRect(LocalFrame& frame) {
}
void ChromeClientImpl::FocusPage() {
+ DCHECK(web_view_);
web_view_->Focus();
}
void ChromeClientImpl::DidFocusPage() {
+ DCHECK(web_view_);
if (web_view_->Client())
web_view_->Client()->DidFocus();
}
@@ -214,6 +221,7 @@ bool ChromeClientImpl::CanTakeFocus(mojom::blink::FocusType) {
}
void ChromeClientImpl::TakeFocus(mojom::blink::FocusType type) {
+ DCHECK(web_view_);
if (!web_view_->Client())
return;
if (type == mojom::blink::FocusType::kBackward)
@@ -223,6 +231,7 @@ void ChromeClientImpl::TakeFocus(mojom::blink::FocusType type) {
}
void ChromeClientImpl::SetKeyboardFocusURL(Element* new_focus_element) {
+ DCHECK(web_view_);
KURL focus_url;
if (new_focus_element && new_focus_element->IsLiveLink() &&
new_focus_element->ShouldHaveFocusAppearance())
@@ -241,6 +250,7 @@ void ChromeClientImpl::StartDragging(LocalFrame* frame,
}
bool ChromeClientImpl::AcceptsLoadDrops() const {
+ DCHECK(web_view_);
return !web_view_->Client() || web_view_->Client()->AcceptsLoadDrops();
}
@@ -252,6 +262,7 @@ Page* ChromeClientImpl::CreateWindowDelegate(
network::mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicyFeatureState& opener_feature_state,
const SessionStorageNamespaceId& session_storage_namespace_id) {
+ DCHECK(web_view_);
if (!web_view_->Client())
return nullptr;
@@ -277,6 +288,7 @@ void ChromeClientImpl::DidOverscroll(
const gfx::Vector2dF& accumulated_overscroll,
const gfx::PointF& position_in_viewport,
const gfx::Vector2dF& velocity_in_viewport) {
+ DCHECK(web_view_);
// WebWidgetClient can be null when not compositing, and this behaviour only
// applies when compositing is enabled.
if (!web_view_->does_composite())
@@ -308,6 +320,7 @@ void ChromeClientImpl::SetOverscrollBehavior(
}
void ChromeClientImpl::Show(NavigationPolicy navigation_policy) {
+ DCHECK(web_view_);
// TODO(darin): Change caller to pass LocalFrame.
WebLocalFrameImpl* main_frame = web_view_->MainFrameImpl();
DCHECK(main_frame);
@@ -342,6 +355,7 @@ void ChromeClientImpl::AddMessageToConsole(LocalFrame* local_frame,
}
bool ChromeClientImpl::CanOpenBeforeUnloadConfirmPanel() {
+ DCHECK(web_view_);
return !!web_view_->Client();
}
@@ -366,6 +380,7 @@ void ChromeClientImpl::SetBeforeUnloadConfirmPanelResultForTesting(
}
void ChromeClientImpl::CloseWindowSoon() {
+ DCHECK(web_view_);
web_view_->CloseWindowSoon();
}
@@ -402,12 +417,15 @@ bool ChromeClientImpl::OpenJavaScriptPromptDelegate(LocalFrame* frame,
return success;
}
bool ChromeClientImpl::TabsToLinks() {
+ DCHECK(web_view_);
return web_view_->TabsToLinks();
}
void ChromeClientImpl::InvalidateRect(const IntRect& update_rect) {
- if (!update_rect.IsEmpty())
+ if (!update_rect.IsEmpty()) {
+ DCHECK(web_view_);
web_view_->InvalidateRect(update_rect);
+ }
}
void ChromeClientImpl::ScheduleAnimation(const LocalFrameView* frame_view,
@@ -465,17 +483,20 @@ ScreenInfo ChromeClientImpl::GetScreenInfo(LocalFrame& frame) const {
void ChromeClientImpl::OverrideVisibleRectForMainFrame(
LocalFrame& frame,
IntRect* visible_rect) const {
+ DCHECK(web_view_);
DCHECK(frame.IsMainFrame());
return web_view_->GetDevToolsEmulator()->OverrideVisibleRect(
IntRect(frame.GetWidgetForLocalRoot()->ViewRect()).Size(), visible_rect);
}
float ChromeClientImpl::InputEventsScaleForEmulation() const {
+ DCHECK(web_view_);
return web_view_->GetDevToolsEmulator()->InputEventsScaleForEmulation();
}
void ChromeClientImpl::ContentsSizeChanged(LocalFrame* frame,
const IntSize& size) const {
+ DCHECK(web_view_);
web_view_->DidChangeContentsSize();
WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(frame);
@@ -483,40 +504,49 @@ void ChromeClientImpl::ContentsSizeChanged(LocalFrame* frame,
}
bool ChromeClientImpl::DoubleTapToZoomEnabled() const {
+ DCHECK(web_view_);
return web_view_->SettingsImpl()->DoubleTapToZoomEnabled();
}
void ChromeClientImpl::EnablePreferredSizeChangedMode() {
+ DCHECK(web_view_);
web_view_->EnablePreferredSizeChangedMode();
}
void ChromeClientImpl::ZoomToFindInPageRect(const WebRect& rect_in_root_frame) {
+ DCHECK(web_view_);
web_view_->ZoomToFindInPageRect(rect_in_root_frame);
}
void ChromeClientImpl::PageScaleFactorChanged() const {
+ DCHECK(web_view_);
web_view_->PageScaleFactorChanged();
}
void ChromeClientImpl::MainFrameScrollOffsetChanged(
LocalFrame& main_frame) const {
+ DCHECK(web_view_);
DCHECK(main_frame.IsMainFrame());
web_view_->MainFrameScrollOffsetChanged();
}
float ChromeClientImpl::ClampPageScaleFactorToLimits(float scale) const {
+ DCHECK(web_view_);
return web_view_->ClampPageScaleFactorToLimits(scale);
}
void ChromeClientImpl::ResizeAfterLayout() const {
+ DCHECK(web_view_);
web_view_->ResizeAfterLayout();
}
void ChromeClientImpl::MainFrameLayoutUpdated() const {
+ DCHECK(web_view_);
web_view_->MainFrameLayoutUpdated();
}
void ChromeClientImpl::ShowMouseOverURL(const HitTestResult& result) {
+ DCHECK(web_view_);
if (!web_view_->Client())
return;
@@ -566,6 +596,7 @@ void ChromeClientImpl::SetToolTip(LocalFrame& frame,
void ChromeClientImpl::DispatchViewportPropertiesDidChange(
const ViewportDescription& description) const {
+ DCHECK(web_view_);
web_view_->UpdatePageDefinedViewportConstraints(description);
}
@@ -690,6 +721,7 @@ void ChromeClientImpl::SetCursor(const ui::Cursor& cursor,
void ChromeClientImpl::SetCursorInternal(const ui::Cursor& cursor,
LocalFrame* local_frame) {
+ DCHECK(web_view_);
if (cursor_overridden_)
return;
@@ -738,6 +770,7 @@ void ChromeClientImpl::AutoscrollEnd(LocalFrame* local_frame) {
}
String ChromeClientImpl::AcceptLanguages() {
+ DCHECK(web_view_);
return web_view_->Client()->AcceptLanguages();
}
@@ -777,20 +810,24 @@ void ChromeClientImpl::DetachCompositorAnimationTimeline(
void ChromeClientImpl::EnterFullscreen(LocalFrame& frame,
const FullscreenOptions* options,
FullscreenRequestType request_type) {
+ DCHECK(web_view_);
web_view_->EnterFullscreen(frame, options, request_type);
}
void ChromeClientImpl::ExitFullscreen(LocalFrame& frame) {
+ DCHECK(web_view_);
web_view_->ExitFullscreen(frame);
}
void ChromeClientImpl::FullscreenElementChanged(Element* old_element,
Element* new_element) {
+ DCHECK(web_view_);
web_view_->FullscreenElementChanged(old_element, new_element);
}
void ChromeClientImpl::AnimateDoubleTapZoom(const gfx::Point& point,
const gfx::Rect& rect) {
+ DCHECK(web_view_);
web_view_->AnimateDoubleTapZoom(point, WebRect(rect));
}
@@ -805,6 +842,7 @@ void ChromeClientImpl::UpdateLayerSelection(
}
bool ChromeClientImpl::HasOpenedPopup() const {
+ DCHECK(web_view_);
return web_view_->HasOpenedPopup();
}
@@ -819,20 +857,24 @@ PopupMenu* ChromeClientImpl::OpenPopupMenu(LocalFrame& frame,
}
PagePopup* ChromeClientImpl::OpenPagePopup(PagePopupClient* client) {
+ DCHECK(web_view_);
return web_view_->OpenPagePopup(client);
}
void ChromeClientImpl::ClosePagePopup(PagePopup* popup) {
+ DCHECK(web_view_);
web_view_->ClosePagePopup(popup);
}
DOMWindow* ChromeClientImpl::PagePopupWindowForTesting() const {
+ DCHECK(web_view_);
return web_view_->PagePopupWindow();
}
void ChromeClientImpl::SetBrowserControlsState(float top_height,
float bottom_height,
bool shrinks_layout) {
+ DCHECK(web_view_);
DCHECK(web_view_->MainFrameWidget());
WebSize size = web_view_->MainFrameWidget()->Size();
if (shrinks_layout)
@@ -844,6 +886,7 @@ void ChromeClientImpl::SetBrowserControlsState(float top_height,
void ChromeClientImpl::SetBrowserControlsShownRatio(float top_ratio,
float bottom_ratio) {
+ DCHECK(web_view_);
web_view_->GetBrowserControls().SetShownRatio(top_ratio, bottom_ratio);
}
@@ -911,6 +954,7 @@ void ChromeClientImpl::SetEventListenerProperties(
LocalFrame* frame,
cc::EventListenerClass event_class,
cc::EventListenerProperties properties) {
+ DCHECK(web_view_);
// This method is only useful when compositing is enabled.
if (!web_view_->does_composite())
return;
@@ -953,6 +997,7 @@ cc::EventListenerProperties ChromeClientImpl::EventListenerProperties(
}
void ChromeClientImpl::BeginLifecycleUpdates(LocalFrame& main_frame) {
+ DCHECK(web_view_);
DCHECK(main_frame.IsMainFrame());
web_view_->StopDeferringMainFrameUpdate();
}
@@ -1152,10 +1197,12 @@ void ChromeClientImpl::AjaxSucceeded(LocalFrame* frame) {
}
TransformationMatrix ChromeClientImpl::GetDeviceEmulationTransform() const {
+ DCHECK(web_view_);
return web_view_->GetDeviceEmulationTransform();
}
void ChromeClientImpl::DidUpdateBrowserControls() const {
+ DCHECK(web_view_);
web_view_->DidUpdateBrowserControls();
}
@@ -1179,6 +1226,7 @@ void ChromeClientImpl::NotifyPopupOpeningObservers() const {
}
FloatSize ChromeClientImpl::ElasticOverscroll() const {
+ DCHECK(web_view_);
return web_view_->ElasticOverscroll();
}
@@ -1195,6 +1243,7 @@ WebAutofillClient* ChromeClientImpl::AutofillClientFromFrame(
void ChromeClientImpl::DidUpdateTextAutosizerPageInfo(
const mojom::blink::TextAutosizerPageInfo& page_info) {
+ DCHECK(web_view_);
web_view_->TextAutosizerPageInfoChanged(page_info);
}
@@ -1206,6 +1255,7 @@ void ChromeClientImpl::DocumentDetached(Document& document) {
}
double ChromeClientImpl::UserZoomFactor() const {
+ DCHECK(web_view_);
return PageZoomLevelToZoomFactor(web_view_->ZoomLevel());
}