Commit 1c63176f authored by Ehsan Karamad's avatar Ehsan Karamad Committed by Commit Bot

[ MimeHandlerView ] Fix cross-origin postMessage

When a.com embeds a PDF in b.com, {embed, object}.postMessages sends the
messages from a.com to the WebRemoteFrame corresponding to the GuestView.

On the browser side, the target RenderFrameHost is determined to be the outer
WebContents's frame that is used to attach MimeHandlerViewGuest. This means
at the end of routing, the IPC ends up going to a dead RenderFrameHost (dropped
on the way since there is no RenderFrame to handle it).

This CL fixes this issue by a) checking if target RenderFrameHost is live, and
b) if not try to find an inner delegate or drop the message.

Note that this CL fixes several tests which currently fail (or timeout) with
--enable-features=MimeHandlerViewInCrossProcessFrame (the list of such tests
is included in the linked bug). This CL fixes some of those tests and together
with https://crrev.com/c/1607425 should make most tests including all of the
PDFExtensionTest* pass (with the flag).

Bug: 961786
Change-Id: I876b971f40d54f3386e23b9750420bbfc1bbbe01
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1606769
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/master@{#659259}
parent da7d41dc
...@@ -143,4 +143,9 @@ ukm::SourceId RenderFrameHostDelegate::GetUkmSourceIdForLastCommittedSource() ...@@ -143,4 +143,9 @@ ukm::SourceId RenderFrameHostDelegate::GetUkmSourceIdForLastCommittedSource()
return ukm::kInvalidSourceId; return ukm::kInvalidSourceId;
} }
RenderFrameHostImpl* RenderFrameHostDelegate::GetMainFrameForInnerDelegate(
FrameTreeNode* frame_tree_node) {
return nullptr;
}
} // namespace content } // namespace content
...@@ -436,6 +436,12 @@ class CONTENT_EXPORT RenderFrameHostDelegate { ...@@ -436,6 +436,12 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
virtual void AudioContextPlaybackStopped(RenderFrameHost* host, virtual void AudioContextPlaybackStopped(RenderFrameHost* host,
int context_id) {} int context_id) {}
// Returns the main frame of the inner delegate that is attached to this
// delegate using |frame_tree_node|. Returns nullptr if no such inner delegate
// exists.
virtual RenderFrameHostImpl* GetMainFrameForInnerDelegate(
FrameTreeNode* frame_tree_node);
protected: protected:
virtual ~RenderFrameHostDelegate() {} virtual ~RenderFrameHostDelegate() {}
}; };
......
...@@ -354,6 +354,15 @@ void RenderFrameProxyHost::OnCheckCompleted() { ...@@ -354,6 +354,15 @@ void RenderFrameProxyHost::OnCheckCompleted() {
void RenderFrameProxyHost::OnRouteMessageEvent( void RenderFrameProxyHost::OnRouteMessageEvent(
const FrameMsg_PostMessage_Params& params) { const FrameMsg_PostMessage_Params& params) {
RenderFrameHostImpl* target_rfh = frame_tree_node()->current_frame_host(); RenderFrameHostImpl* target_rfh = frame_tree_node()->current_frame_host();
if (!target_rfh->IsRenderFrameLive()) {
// Check if there is an inner delegate involved; if so target its main
// frame or otherwise return since there is no point in forwarding the
// message.
target_rfh = target_rfh->delegate()->GetMainFrameForInnerDelegate(
target_rfh->frame_tree_node());
if (!target_rfh || !target_rfh->IsRenderFrameLive())
return;
}
// |targetOrigin| argument of postMessage is already checked by // |targetOrigin| argument of postMessage is already checked by
// blink::LocalDOMWindow::DispatchMessageEventWithOriginCheck (needed for // blink::LocalDOMWindow::DispatchMessageEventWithOriginCheck (needed for
......
...@@ -6868,6 +6868,13 @@ void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHost* host, ...@@ -6868,6 +6868,13 @@ void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHost* host,
observer.AudioContextPlaybackStopped(audio_context_id); observer.AudioContextPlaybackStopped(audio_context_id);
} }
RenderFrameHostImpl* WebContentsImpl::GetMainFrameForInnerDelegate(
FrameTreeNode* frame_tree_node) {
if (auto* web_contents = node_.GetInnerWebContentsInFrame(frame_tree_node))
return web_contents->GetMainFrame();
return nullptr;
}
void WebContentsImpl::UpdateWebContentsVisibility(Visibility visibility) { void WebContentsImpl::UpdateWebContentsVisibility(Visibility visibility) {
// Occlusion is disabled when |features::kWebContentsOcclusion| is disabled // Occlusion is disabled when |features::kWebContentsOcclusion| is disabled
// (for power and speed impact assessment) or when // (for power and speed impact assessment) or when
......
...@@ -604,6 +604,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, ...@@ -604,6 +604,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
int context_id) override; int context_id) override;
void AudioContextPlaybackStopped(RenderFrameHost* host, void AudioContextPlaybackStopped(RenderFrameHost* host,
int context_id) override; int context_id) override;
RenderFrameHostImpl* GetMainFrameForInnerDelegate(
FrameTreeNode* frame_tree_node) override;
// RenderViewHostDelegate ---------------------------------------------------- // RenderViewHostDelegate ----------------------------------------------------
RenderViewHostDelegateView* GetDelegateView() override; RenderViewHostDelegateView* GetDelegateView() override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment