diff options
author | Daniel Cheng <dcheng@chromium.org> | 2016-10-24 13:37:44 -0700 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-03-16 14:47:47 +0000 |
commit | 062a75ed93a9b75f53292c6421b3292f753ea9b5 (patch) | |
tree | 41d5443d5543c3f529c54ee2bc007bf199c1d27c | |
parent | 965db0de3913007ea170150343a37a7277e78f06 (diff) |
[Backport] Disallow frame swap during frame detach.
Otherwise, the swapped-in frame is never detached, resulting in general
confusion and mayhem.
BUG=646610
Review-Url: https://codereview.chromium.org/2429133002
Cr-Commit-Position: refs/heads/master@{#426245}
(cherry picked from commit 29226a0dcd5ff17b04a0a92bb52ea5c88b29decb)
R=japhet@chromium.org
Review URL: https://codereview.chromium.org/2446563003 .
Cr-Commit-Position: refs/branch-heads/2883@{#257}
Cr-Branched-From: 614d31daee2f61b0180df403a8ad43f20b9f6dd7-refs/heads/master@{#423768}
(CVE-2016-5205)
Change-Id: I6153619b7a5cc6a37aa3a17996eeadabbe59d251
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
5 files changed, 14 insertions, 1 deletions
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index 36f1b10d360..dfa128cb154 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -3135,7 +3135,8 @@ void RenderFrameImpl::didCommitProvisionalLoad( if (!proxy) return; - proxy->web_frame()->swap(frame_); + if (!proxy->web_frame()->swap(frame_)) + return; proxy_routing_id_ = MSG_ROUTING_NONE; in_frame_tree_ = true; diff --git a/chromium/third_party/WebKit/Source/core/frame/Frame.h b/chromium/third_party/WebKit/Source/core/frame/Frame.h index c15b0949118..137079c3e5e 100644 --- a/chromium/third_party/WebKit/Source/core/frame/Frame.h +++ b/chromium/third_party/WebKit/Source/core/frame/Frame.h @@ -133,6 +133,8 @@ public: virtual WindowProxyManager* windowProxyManager() const = 0; + bool isDetaching() const { return m_isDetaching; } + protected: Frame(FrameClient*, FrameHost*, FrameOwner*); @@ -141,6 +143,8 @@ protected: RawPtrWillBeMember<FrameHost> m_host; RawPtrWillBeMember<FrameOwner> m_owner; + bool m_isDetaching = false; + private: RawPtrWillBeMember<FrameClient> m_client; // Needed to identify Frame Timing requests. diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp index d972f17789f..7db189a63c8 100644 --- a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp @@ -276,6 +276,10 @@ void LocalFrame::reload(FrameLoadType loadType, ClientRedirectPolicy clientRedir void LocalFrame::detach(FrameDetachType type) { + // Note that detach() can be re-entered, so it's not possible to + // DCHECK(!m_isDetaching) here. + m_isDetaching = true; + PluginScriptForbiddenScope forbidPluginDestructorScripting; // A lot of the following steps can result in the current frame being // detached, so protect a reference to it. diff --git a/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp index 7c2e6635b53..9c303245770 100644 --- a/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp +++ b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp @@ -88,6 +88,8 @@ void RemoteFrame::reload(FrameLoadType frameLoadType, ClientRedirectPolicy clien void RemoteFrame::detach(FrameDetachType type) { + m_isDetaching = true; + PluginScriptForbiddenScope forbidPluginDestructorScripting; // Frame::detach() requires the caller to keep a reference to this, since // otherwise it may clear the last reference to this, causing it to be diff --git a/chromium/third_party/WebKit/Source/web/WebFrame.cpp b/chromium/third_party/WebKit/Source/web/WebFrame.cpp index 5ea8859a994..472f8fb6bb8 100644 --- a/chromium/third_party/WebKit/Source/web/WebFrame.cpp +++ b/chromium/third_party/WebKit/Source/web/WebFrame.cpp @@ -32,6 +32,8 @@ bool WebFrame::swap(WebFrame* frame) #if !ENABLE(OILPAN) RefPtr<WebFrameImplBase> protectThis = toImplBase(); #endif + if (oldFrame->isDetaching()) + return false; // Unload the current Document in this frame: this calls unload handlers, // detaches child frames, etc. Since this runs script, make sure this frame |