summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-03-20 21:11:36 +0000
committerMichal Klocek <michal.klocek@qt.io>2018-06-05 14:19:39 +0000
commit9a660be58f3e46e45351b2edd790b897bf1772a0 (patch)
treeae8517f2389a2da4faa1e3f44b2a45e87f332f0a
parentae56fd7445a474743d9820ddfdf5d50d00ebec3c (diff)
[Backport] CVE-2018-6135
Force a flush of drawing to the widget when a dialog is shown. BUG=823353 TEST=as in bug Reviewed-on: https://chromium-review.googlesource.com/971661 Change-Id: I83fae12fdb6e43cb3ad06f8484d552790f4831c6 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc13
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h7
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.cc20
3 files changed, 40 insertions, 0 deletions
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
index 04f3f40e770..c1a8af784c3 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -686,6 +686,10 @@ void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasShown");
is_hidden_ = false;
+ // If we navigated in background, clear the displayed graphics of the
+ // previous page before going visible.
+ ForceFirstFrameAfterNavigationTimeout();
+
SendScreenRects();
RestartHangMonitorTimeoutIfNecessary();
@@ -2943,6 +2947,15 @@ void RenderWidgetHostImpl::ProgressFling(base::TimeTicks current_time) {
input_router_->ProgressFling(current_time);
}
+void RenderWidgetHostImpl::ForceFirstFrameAfterNavigationTimeout() {
+ if (new_content_rendering_timeout_ &&
+ new_content_rendering_timeout_->IsRunning()) {
+ new_content_rendering_timeout_->Stop();
+ ClearDisplayedGraphics();
+ }
+}
+
+
void RenderWidgetHostImpl::StopFling() {
if (input_router_)
input_router_->StopFling();
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h
index bfaf957de69..e1a44a87568 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -639,6 +639,13 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void ProgressFling(base::TimeTicks current_time);
void StopFling();
+ // The RenderWidgetHostImpl will keep showing the old page (for a while) after
+ // navigation until the first frame of the new page arrives. This reduces
+ // flicker. However, if for some reason it is known that the frames won't be
+ // arriving, this call can be used for force a timeout, to avoid showing the
+ // content of the old page under UI from the new page.
+ void ForceFirstFrameAfterNavigationTimeout();
+
protected:
// ---------------------------------------------------------------------------
// The following method is overridden by RenderViewHost to send upwards to
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
index 0e4799f4441..675a0ab4e00 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -4613,6 +4613,16 @@ void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host,
const GURL& frame_url,
JavaScriptDialogType dialog_type,
IPC::Message* reply_msg) {
+ // Ensure that if showing a dialog is the first thing that a page does, that
+ // the contents of the previous page aren't shown behind it. This is required
+ // because showing a dialog freezes the renderer, so no frames will be coming
+ // from it. https://crbug.com/823353
+ auto* render_widget_host_impl =
+ static_cast<RenderFrameHostImpl*>(render_frame_host)
+ ->GetRenderWidgetHost();
+ if (render_widget_host_impl)
+ render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout();
+
// Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276
if (IsFullscreenForCurrentTab())
@@ -4671,6 +4681,16 @@ void WebContentsImpl::RunBeforeUnloadConfirm(
RenderFrameHost* render_frame_host,
bool is_reload,
IPC::Message* reply_msg) {
+ // Ensure that if showing a dialog is the first thing that a page does, that
+ // the contents of the previous page aren't shown behind it. This is required
+ // because showing a dialog freezes the renderer, so no frames will be coming
+ // from it. https://crbug.com/823353
+ auto* render_widget_host_impl =
+ static_cast<RenderFrameHostImpl*>(render_frame_host)
+ ->GetRenderWidgetHost();
+ if (render_widget_host_impl)
+ render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout();
+
// Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276
if (IsFullscreenForCurrentTab())