New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 653746 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Proxy created incorrectly when canceling a pending/speculative RFH

Project Member Reported by alex...@chromium.org, Oct 7 2016

Issue description

When we cancel a pending/speculative RFH, we call RenderFrameHostManager::DiscardUnusedFrame, which contains a check of whether the RFH being canceled is in a SiteInstance that has other active frames.  If so, it tries to leave a proxy in place of the RFH.  However, the logic for doing so seems broken:

  // If the SiteInstance for the pending RFH is being used by others don't
  // delete the RFH. Just swap it out and it can be reused at a later point.
  // In --site-per-process, RenderFrameHosts are not kept around and are
  // deleted when not used, replaced by RenderFrameProxyHosts.
  SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
  if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
    // Any currently suspended navigations are no longer needed.
    render_frame_host->CancelSuspendedNavigations();

    // If a proxy already exists for the |site_instance|, just reuse it instead
    // of creating a new one. There is no need to call SwapOut on the
    // |render_frame_host|, as this method is only called to discard a pending
    // or speculative RenderFrameHost, i.e. one that has never hosted an actual
    // document.
    RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance);
    if (!proxy) {
      proxy = CreateRenderFrameProxyHost(site_instance,
                                         render_frame_host->render_view_host());
    }

If there is no existing proxy, CreateRenderFrameProxyHost creates it only on the browser side; there is no call to InitRenderFrameProxy to actually create it in the renderer.

Repro steps to show that not having a proxy breaks script connections when it shouldn't:
1) Navigate to http://csreis.github.io
2) In devtools, execute window.open("http://tests.netsekure.org/empty.html")
3) Go back to first tab, and in devtools, execute window.open("","foo")
4) In the new tab from step 3, navigate to http://tests.netsekure.org/redirect.php via omnibox
5) This will redirect to http://tests.netsekure.com/.  Open DevTools, and execute:
   window.addEventListener("message",(e) => console.log(e.data))
6) Go back to first tab (csreis.github.io), and navigate to http://tests.netsekure.org/empty.html.
7) From devtools, execute
   window.open("","foo").postMessage("asdf","*")

Step (7) should look up the middle tab "foo" (currently showing "http://tests.netsekure.com/") and send it a postMessage, which should be printed on the console of that tab (thanks to handler from step 5).

Without --site-per-process, this works.

With --site-per-process, this doesn't work.  The postMessage isn't delivered, presumably because there's no actual proxy created for the "foo" tab in the tests.netsekure.org renderer.

Additionally, the RenderView that is left around in this case is in an inconsistent state, thinking that it's still swapped in and that it has a main frame/widget; this is causing the CreateRenderView crash in https://crbug.com/627400#c21 and probably other issues.

 
Project Member

Comment 1 by bugdroid1@chromium.org, Oct 14 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/78c9c0d7d8e45837bc93efababf7fe517b2b36ad

commit 78c9c0d7d8e45837bc93efababf7fe517b2b36ad
Author: alexmos <alexmos@chromium.org>
Date: Fri Oct 14 18:57:03 2016

Fix RenderView reuse issues when canceling a pending RenderFrameHost.

This CL fixes three issues that happen when a pending RenderFrameHost
is canceled and discarded, but its SiteInstance has other active
frames.  In that case, the pending RenderFrameHost is replaced with a
proxy, so that other frames in the SiteInstance can still communicate
with it.

1) When a main frame pending RFH is canceled, we never update its
RVH's main_frame_routing_id() or is_active() status.  If the RVH is
later reused by another main frame navigation, these parameters would
be stale, leading to a crash in CreateRenderView trying to resolve
the main frame via the stale routing ID.  (Issue 627400)

2) The discarded RFH was deleted on the browser side, but the
corresponding RenderFrame wasn't deleted on the renderer side.  That
led to a renderer-side crash of trying to reuse the leaked
RenderFrame's widget if we ever re-navigated to the same SiteInstance
in the same frame.  The fix is to send a FrameMsg_Delete in the cases
where the discarded main frame isn't going to be cleaned up by its RVH
going away (in the case where the proxy is going to keep it
alive).  ( Issue 651980 )

3) The replacement proxy's RenderFrameProxyHost was created, but the
RenderFrameProxy wasn't actually initialized on the renderer side, so
other frames couldn't actually communicate with this frame.  (Issue
653746)

These changes are also likely to help with crashes we've been chasing
in issues 626802 and  575245 .

BUG=627400, 651980 , 653746 ,626802, 575245 
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_site_isolation

Review-Url: https://codereview.chromium.org/2410153005
Cr-Commit-Position: refs/heads/master@{#425409}

[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/browser/frame_host/render_frame_host_impl.cc
[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/browser/frame_host/render_frame_host_manager.cc
[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/browser/site_per_process_browsertest.cc
[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/renderer/render_frame_proxy.cc
[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/renderer/render_widget.cc
[modify] https://crrev.com/78c9c0d7d8e45837bc93efababf7fe517b2b36ad/content/renderer/render_widget.h

Status: Fixed (was: Assigned)

Sign in to add a comment