This patch cleans up remote outer window proxies when we navigate back
into the process.
It adds a flag to mDanglingRemoteOuterProxies that is set in between
BrowsingContext::SetDocShell(), where we can tell that the browsing
context is going from being remote to being local, to
nsGlobalWindowOuter::SetNewDocument(), where the local outer window
proxy is actually created. Once the outer window is created, the
remote window proxies can be cleaned up in
CleanUpDanglingRemoteOuterWindowProxies().
The clean up is done by a process that is similar to object
transplanting, except that instead of looking in the cross-compartment
wrapper table for each compartment to find objects to be turned into
CCWs to the new object, it looks in the remote proxy map for each
compartment. SpiderMonkey doesn't know about the proxy maps, so this
has to be done by a new callback object CompartmentTransplantCallback.
Now that this cleanup is being done, it shouldn't be possible to wrap
a remote outer window proxy when the browsing context is local, so
MaybeWrapWindowProxy() can be simplified. I had to drop the assert
here that the browsing context has a window proxy because during clean
up we call wrap on a local outer window proxy before the BC gets the
window proxy set on it. I had the assert because my original plan was
to implicitly fix remote proxies during wrapping, but that is no
longer necessary.
Differential Revision: https://phabricator.services.mozilla.com/D38343
--HG--
extra : moz-landing-system : lando
Remote outer window proxies can't be the target of a CCW, because if
you attempt to wrap them we just create a new outer window proxy.
Therefore, they can't be the target of an Xray wrapper, so they can't
have Xray waivers that do anything useful. However, if we do a
navigation from a local iframe to a remote iframe, we'll transplant a
remote outer window proxy onto a local outer window proxy, which might
have an Xray. This can cause some issues, particularly if we later
navigate back to a different local window.
To work around this, this patch nukes Xray waivers on navigation to a
remote outer window proxy. This makes Xray waiver behavior
inconsistent with the non-Fission behavior, but it is safer to leave
the non-Fission behavior alone for now, for fear of breaking addons.
Differential Revision: https://phabricator.services.mozilla.com/D40116
--HG--
extra : moz-landing-system : lando
Remote outer window proxies can't be the target of a CCW, because if
you attempt to wrap them we just create a new outer window proxy.
Therefore, they can't be the target of an Xray wrapper, so they can't
have Xray waivers that do anything useful. However, if we do a
navigation from a local iframe to a remote iframe, we'll transplant a
remote outer window proxy onto a local outer window proxy, which might
have an Xray. This can cause some issues, particularly if we later
navigate back to a different local window.
To work around this, this patch nukes Xray waivers on navigation to a
remote outer window proxy. This makes Xray waiver behavior
inconsistent with the non-Fission behavior, but it is safer to leave
the non-Fission behavior alone for now, for fear of breaking addons.
Differential Revision: https://phabricator.services.mozilla.com/D40116
--HG--
extra : moz-landing-system : lando
When a BrowsingContext changes from being local to remote, we have to
change all window proxies from being local to remote, using
transplanting. The actual window proxy becomes a remote window
proxy. Cross compartment wrappers (CCWs) to the window proxy also
become remote window proxies in their respective compartments, rather
than CCWs to a remote proxy in the old compartment of the window
proxy, because the window is no longer actually in that
compartment. This also avoids having to figure out what Xray behavior
for remote window proxies should be.
This patch uses the transplanting support I added to
GetRemoteOuterWindowProxy() in the previous patch to ensure that the
remote proxy map holds the correct value after transplanting finishes.
It drops the requirement that both arguments to JS_TransplantObject
have the same class, because we need to transplant a window proxy with
a remote window proxy. It also deals with this by not adding origobj
to the wrapper map unless it is a CCW, to handle transplanting to a
remote proxy.
The core design here, with the remote window proxies in every
compartment, is taken from a patch by peterv.
Differential Revision: https://phabricator.services.mozilla.com/D35730
--HG--
extra : moz-landing-system : lando
In a later patch, the prewrap hook will need to know the address of
the object we are eventually going to transplant into. In the
non-transplant case, the value will be null.
Differential Revision: https://phabricator.services.mozilla.com/D37597
--HG--
extra : moz-landing-system : lando
When a BrowsingContext changes from being local to remote, we have to
change all window proxies from being local to remote, using
transplanting. The actual window proxy becomes a remote window
proxy. Cross compartment wrappers (CCWs) to the window proxy also
become remote window proxies in their respective compartments, rather
than CCWs to a remote proxy in the old compartment of the window
proxy, because the window is no longer actually in that
compartment. This also avoids having to figure out what Xray behavior
for remote window proxies should be.
This patch uses the transplanting support I added to
GetRemoteOuterWindowProxy() in the previous patch to ensure that the
remote proxy map holds the correct value after transplanting finishes.
It drops the requirement that both arguments to JS_TransplantObject
have the same class, because we need to transplant a window proxy with
a remote window proxy. It also deals with this by not adding origobj
to the wrapper map unless it is a CCW, to handle transplanting to a
remote proxy.
The core design here, with the remote window proxies in every
compartment, is taken from a patch by peterv.
Differential Revision: https://phabricator.services.mozilla.com/D35730
--HG--
extra : moz-landing-system : lando
In a later patch, the prewrap hook will need to know the address of
the object we are eventually going to transplant into. In the
non-transplant case, the value will be null.
Differential Revision: https://phabricator.services.mozilla.com/D37597
--HG--
extra : moz-landing-system : lando
Marking GetGlobalJSObject and GetGlobalJSObjectPreserveColor final and inline
on inner/outer windows allows compilers to de-virtualize and inline them, which
makes them just as fast as calling FastGetGlobalJSObject is now (in the case of
GetGlobalJSObjectPreserveColor; GetGlobalJSObject has to do the gray-unmarking,
which is a bit more work).
In WindowDestroyedEvent::Run we want to switch to GetGlobalJSObject(), because
we want to root the object and hence should unmark gray.
In nsGlobalWindowInner::RunTimeoutHandler we likewise want to unmark gray. The
AutoEntryScript constructor likely did that already, but it's not that
expensive when it doesn't need to do any work.
Differential Revision: https://phabricator.services.mozilla.com/D29711
--HG--
extra : moz-landing-system : lando
This ensures the JS shell and browser behave the same way and it's nice for fuzzing.
Differential Revision: https://phabricator.services.mozilla.com/D25204
--HG--
extra : moz-landing-system : lando
Consequently, this removes:
- MOZ_LIBPRIO, which is now always enabled.
- non_msvc_compiler, which is now always true.
- The cl.py wrapper, since it's not used anymore.
- CL_INCLUDES_PREFIX, which was only used for the cl.py wrapper.
- NONASCII, which was only there to ensure CL_INCLUDES_PREFIX still
worked in non-ASCII cases.
This however keeps a large part of detecting and configuring for MSVC,
because we still do need it for at least headers, libraries, and midl.
Depends on D19614
Differential Revision: https://phabricator.services.mozilla.com/D19615
--HG--
extra : moz-landing-system : lando
In the new setup, they are still same-compartment with their target, but may
not be same-realm (due to transplants).
We could make them be same-realm by adjusting FixWaiverAfterTransplant, but
this is conceptually simpler.
Differential Revision: https://phabricator.services.mozilla.com/D19261
--HG--
extra : moz-landing-system : lando
In vm/Iteration.cpp this inlines some functions because there's a single
caller now. Follow-up patches will do additional cleanup/optimization.
Differential Revision: https://phabricator.services.mozilla.com/D18926
--HG--
extra : moz-landing-system : lando
This is supposed to be per-global state, and we're planning to have multiple
globals per compartment.
Differential Revision: https://phabricator.services.mozilla.com/D18850
--HG--
extra : moz-landing-system : lando
We want to use a transparent CCW if there is any pair of globals, one from each
compartment, which are, or have ever been, same origin-domain in the HTML spec
sense. This is obviously required in the "are now same origin-domain" case, and in
the "were same origin-domain" case it's required because there may be existing
transparent CCWs between the compartments and we don't want them to become
opaque due to a roundtrip through the compartment boundary.
In practice, we need to consider two cases:
1) The two compartments started out same-origin. In this case the two
CompartmentOriginInfos will have matching (in the Equals() sense)
GetPrincipalIgnoringDocumentDomain(). They will also have matching SiteRef(),
of course.
2) The two compartments started out different-origin but then at some point two
globals in the compartments ended up same origin-domain. That requires that
the two globals be same TLD+1 and have both set document.domain. So in this
case the two CompartmentOriginInfos have matching SiteRef() and both test true
for HasChangedDocumentDomain().
We only need to worry about this for web compartments, which means that we only
need to worry about cases when security checks are symmetric
(i.e. originSubsumesTarget == targetSubsumesOrigin) and neither compartment is
forcing Xrays.
Differential Revision: https://phabricator.services.mozilla.com/D18031
--HG--
extra : moz-landing-system : lando
The end result we want is that on the web cross-compartment wrappers for
WindowProxy and Location are always CrossOriginObjectWrapper. That needs to be true
for both cases that are different-origin (as now) and cases that are
same-origin, since they might become different-origin due to document.domain
changes but we don't want that to affect the wrappers involved.
On the web, all security checks are symmetric, so in WrapperFactory::Rewrap we
would have originSubsumesTarget == targetSubsumesOrigin in all web cases.
I claim that
originSubsumesTarget == targetSubsumesOrigin &&
(!targetSubsumesOrigin ||
(!originCompartmentPrivate->wantXrays &&
!targetCompartmentPrivate->wantXrays)) &&
"object is a WindowProxy or Location"
is a necessary and sufficient condition for using CrossOriginObjectWrapper.
Comparing to our current code, if originSubsumesTarget and targetSubsumesOrigin
are both false, then for the WindowProxy and Location cases we currently end up
with the following arguments to SelectWrapper:
securityWrapper: true
xrayType: XrayForDOMObject
waiveXrays: false
So SelectWrapper ends up returning CrossOriginObjectWrapper, which the new
condition keeps doing.
If originSubsumesTarget and targetSubsumesOrigin are both true, then there are
two cases. If both compartments have wantXrays false (which is always the case
on the web), then we end up with the following arguments to SelectWrapper:
securityWrapper: false
xrayType: NotXray
waiveXrays: false
and SelectWrapper returns CrossCompartmentWrapper. We want to do
CrossOriginObjectWrapper instead, as explained above.
Finally, if originSubsumesTarget and targetSubsumesOrigin are both true but one
of the compartments has wantXrays set, then we get:
securityWrapper: false
xrayType: XrayForDOMObject
waiveXrays: might be true or false
and then SelectWrapper might return a WaiveXrayWrapper or a PermissiveXrayDOM.
In this case we do _not_ want to start returning CrossOriginObjectWrapper, and
this is a non-web case anyway, since web compartments can't set wantXrays.
Differential Revision: https://phabricator.services.mozilla.com/D18030
--HG--
extra : moz-landing-system : lando
The end result we want is that on the web cross-compartment wrappers for
WindowProxy and Location are always CrossOriginObjectWrapper. That needs to be true
for both cases that are different-origin (as now) and cases that are
same-origin, since they might become different-origin due to document.domain
changes but we don't want that to affect the wrappers involved.
On the web, all security checks are symmetric, so in WrapperFactory::Rewrap we
would have originSubsumesTarget == targetSubsumesOrigin in all web cases.
I claim that
originSubsumesTarget == targetSubsumesOrigin &&
(!targetSubsumesOrigin ||
(!originCompartmentPrivate->wantXrays &&
!targetCompartmentPrivate->wantXrays)) &&
"object is a WindowProxy or Location"
is a necessary and sufficient condition for using CrossOriginObjectWrapper.
Comparing to our current code, if originSubsumesTarget and targetSubsumesOrigin
are both false, then for the WindowProxy and Location cases we currently end up
with the following arguments to SelectWrapper:
securityWrapper: true
xrayType: XrayForDOMObject
waiveXrays: false
So SelectWrapper ends up returning CrossOriginObjectWrapper, which the new
condition keeps doing.
If originSubsumesTarget and targetSubsumesOrigin are both true, then there are
two cases. If both compartments have wantXrays false (which is always the case
on the web), then we end up with the following arguments to SelectWrapper:
securityWrapper: false
xrayType: NotXray
waiveXrays: false
and SelectWrapper returns CrossCompartmentWrapper. We want to do
CrossOriginObjectWrapper instead, as explained above.
Finally, if originSubsumesTarget and targetSubsumesOrigin are both true but one
of the compartments has wantXrays set, then we get:
securityWrapper: false
xrayType: XrayForDOMObject
waiveXrays: might be true or false
and then SelectWrapper might return a WaiveXrayWrapper or a PermissiveXrayDOM.
In this case we do _not_ want to start returning CrossOriginObjectWrapper, and
this is a non-web case anyway, since web compartments can't set wantXrays.
Differential Revision: https://phabricator.services.mozilla.com/D18030
--HG--
extra : moz-landing-system : lando
The end result we want is that on the web cross-compartment wrappers for
WindowProxy and Location are always CrossOriginObjectWrapper. That needs to be true
for both cases that are different-origin (as now) and cases that are
same-origin, since they might become different-origin due to document.domain
changes but we don't want that to affect the wrappers involved.
On the web, all security checks are symmetric, so in WrapperFactory::Rewrap we
would have originSubsumesTarget == targetSubsumesOrigin in all web cases.
I claim that
originSubsumesTarget == targetSubsumesOrigin &&
(!targetSubsumesOrigin ||
(!originCompartmentPrivate->wantXrays &&
!targetCompartmentPrivate->wantXrays)) &&
"object is a WindowProxy or Location"
is a necessary and sufficient condition for using CrossOriginObjectWrapper.
Comparing to our current code, if originSubsumesTarget and targetSubsumesOrigin
are both false, then for the WindowProxy and Location cases we currently end up
with the following arguments to SelectWrapper:
securityWrapper: true
xrayType: XrayForDOMObject
waiveXrays: false
So SelectWrapper ends up returning CrossOriginObjectWrapper, which the new
condition keeps doing.
If originSubsumesTarget and targetSubsumesOrigin are both true, then there are
two cases. If both compartments have wantXrays false (which is always the case
on the web), then we end up with the following arguments to SelectWrapper:
securityWrapper: false
xrayType: NotXray
waiveXrays: false
and SelectWrapper returns CrossCompartmentWrapper. We want to do
CrossOriginObjectWrapper instead, as explained above.
Finally, if originSubsumesTarget and targetSubsumesOrigin are both true but one
of the compartments has wantXrays set, then we get:
securityWrapper: false
xrayType: XrayForDOMObject
waiveXrays: might be true or false
and then SelectWrapper might return a WaiveXrayWrapper or a PermissiveXrayDOM.
In this case we do _not_ want to start returning CrossOriginObjectWrapper, and
this is a non-web case anyway, since web compartments can't set wantXrays.
Differential Revision: https://phabricator.services.mozilla.com/D18030
--HG--
extra : moz-landing-system : lando
I am not a huge fan of the UnwrapReflectorToISupports setup here. Maybe we
should introduce two differently-named methods that make it somewhat clear what
the limitations of not taking a JSContext are? I couldn't think of sane
naming...
Differential Revision: https://phabricator.services.mozilla.com/D17885
--HG--
extra : moz-landing-system : lando
This will allow us to correctly handle CheckedUnwrapDynamic on wrappers around
WindowProxy and Location.
Differential Revision: https://phabricator.services.mozilla.com/D17882
--HG--
extra : moz-landing-system : lando
I am not a huge fan of the UnwrapReflectorToISupports setup here. Maybe we
should introduce two differently-named methods that make it somewhat clear what
the limitations of not taking a JSContext are? I couldn't think of sane
naming...
Differential Revision: https://phabricator.services.mozilla.com/D17885
--HG--
extra : moz-landing-system : lando
This will allow us to correctly handle CheckedUnwrapDynamic on wrappers around
WindowProxy and Location.
Differential Revision: https://phabricator.services.mozilla.com/D17882
--HG--
extra : moz-landing-system : lando
I am not a huge fan of the UnwrapReflectorToISupports setup here. Maybe we
should introduce two differently-named methods that make it somewhat clear what
the limitations of not taking a JSContext are? I couldn't think of sane
naming...
Differential Revision: https://phabricator.services.mozilla.com/D17885
--HG--
extra : moz-landing-system : lando
This will allow us to correctly handle CheckedUnwrapDynamic on wrappers around
WindowProxy and Location.
Differential Revision: https://phabricator.services.mozilla.com/D17882
--HG--
extra : moz-landing-system : lando
I am bit surprised myself, but just removing the getPropertyDescriptor trap seems to mostly work.
The only real special case here is the XPC Sandbox, which I changed to keep using its getPropertyDescriptorImpl.
testSetPropertyIgnoringNamedGetter.cpp didn't even really need its getPropertyDescriptor implementation.
Differential Revision: https://phabricator.services.mozilla.com/D17386
--HG--
extra : moz-landing-system : lando