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

Issue 606975 link

Starred by 3 users

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug



Sign in to add a comment

Subframe unload handlers run "too late"

Project Member Reported by dcheng@chromium.org, Apr 26 2016

Issue description

We believe that unload handlers in subframes don't run until swap. This is supposed to be problematic because the corresponding RFH in the browser might already be gone.

https://codereview.chromium.org/143783002 was a proposal to fix this, and https://codereview.chromium.org/140553003 is a test that was supposed to demonstrate this problem (I added the subframe swap case as well).

Surprisingly enough, the test currently shows that cookies set in subframe unload handlers *are* persisting, so maybe something unexpected is happening that's worth a closer look.
 

Comment 1 by nick@chromium.org, Apr 26 2016

Cc: nick@chromium.org
cookies aren't really tied to the RFH, though: they're handled on the IO thread, because they're sync IPCs. I wouldn't be surprised to see SetCookie work even after the pending delete host went away.

Comment 2 by nick@chromium.org, Apr 27 2016

The behavior I expect for subframes of a frame that's being navigated is:
 - The FTNs (and thus RFH's and RFPH's) will be deleted early on in CommitPending, by ResetForNewProcess(). This destruction occurs bottom up, and each RenderFrame should receive a FrameMsg_Delete, sent from the dtor ~RenderFrameHostImpl. in bottom-up order within each process (with no ordering guarantees across processes). Any FrameHostMsg_ sent by these he unload handlers will be dropped on the floor, since we've long forgotten the route ID.

For testing, we could look at console.log() or domAutomationController.send(), but I don't know how important these are.

Does sync XHR work properly in this case? That's probably associated with an RFH id, though I don't know that it wouldn't work if the RFH id were invalid. You could have the XHR mutate server state.

navigator.sendBeacon is pretty important to work from unload handlers (it's designed to work there) but I think it doesn't care about RFH, since it's designed to outlive the frame.

cookies and sync XHR from child frame unload handlers might be something that we will we see breakage in, if/when FrameIoData-style checks start being enforced, since the idea is for frame deletion to revoke the privilege.
Project Member

Comment 3 by sheriffbot@chromium.org, Apr 27 2017

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been available for more than 365 days, and should be re-evaluated. Please re-triage this issue.
The Hotlist-Recharge-Cold label is applied for tracking purposes, and should not be removed after re-triaging the issue.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Hotlist-Recharge-Cold
There's some related discussion happening in issue 828529.  As part of that, I poked a bit at what happens in OOPIF unload handlers today for cookies and navigator.sendBeacon, using this setup: A(B(C)), unload handler in C, and B navigates to D.  This is a case where we currently destroy C's RFHI (as part of ResetForNewProcess) prior to telling the renderer to run its unload handler.

If C is not the last active frame in its process (e.g., if C did a window.open() prior to B->D navigation), both setting document.cookie and sendBeacon work fine.  SetCookie goes through RenderFrameMessageFilter, which is process-wide, and ChildProcessSecurityPolicy checks are ok since the process for child_id is still there.  RenderFrameMessageFilter::SetCookie() passes render_frame_id (on the IO thread) into ChromeContentBrowserClient::AllowSetCookie(), but that allows the cookie write without even looking at the routing ID.  AllowSetCookie() does also post a task with render_frame_id to the UI thread to notify TabSpecificContentSettings::CookieChanged(), and that later fails because we can't look up the WebContents via that routing ID.  Not sure whether that's ok or not.  But the cookie does get written. :)  I'm not sure how sendBeacon is implemented, but it's working as well (verified via navigator.sendBeacon("http://127.0.0.1:9000","foo") and listening via "nc -l -p 9000").

However, if frame C *is* the last active frame in its process, I'm seeing a race between process shutdown and the unload handler running -- the cookie/sendBeacon would *sometimes* work, if they beat the process being shut down (in my local build, they tended to not work most of the time).  Nasko's mentioned we should be disabling fast shutdown if there's an unload handler.  Maybe there's something here that doesn't work with OOPIFs?

Sign in to add a comment