Bug 1318532 - Force remote='true' and noisolation='true' to WebExtensions mozbrowser iframes. r=smaug
MozReview-Commit-ID: K6AC918A4Zh
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2278,32 +2278,33 @@ nsFrameLoader::ShouldUseRemoteProcess()
}
if (XRE_IsContentProcess() &&
!(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
return false;
}
+ nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
+
+ bool isRemote = browserFrame->GetRemote();
// If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
// fall back to the default.
- if (OwnerIsMozBrowserFrame() &&
- !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
-
+ if (OwnerIsMozBrowserFrame() && !isRemote) {
return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
}
// Otherwise, we're remote if we have "remote=true" and we're either a
// browser frame or a XUL element.
- return (OwnerIsMozBrowserFrame() ||
- mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
- mOwnerContent->AttrValueIs(kNameSpaceID_None,
- nsGkAtoms::Remote,
- nsGkAtoms::_true,
- eCaseMatters);
+ return (OwnerIsMozBrowserFrame() && isRemote) ||
+ (mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL &&
+ mOwnerContent->AttrValueIs(kNameSpaceID_None,
+ nsGkAtoms::Remote,
+ nsGkAtoms::_true,
+ eCaseMatters));
}
bool
nsFrameLoader::IsRemoteFrame()
{
if (mRemoteFrame) {
MOZ_ASSERT(!mDocShell, "Found a remote frame with a DocShell");
return true;
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -517,25 +517,48 @@ nsGenericHTMLFrameElement::GetReallyIsBr
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
{
*aOut = true;
+ // Never isolate browser frames for WebExtensions
+ nsAutoString addonId;
+ NodePrincipal()->GetAddonId(addonId);
+ if (!addonId.IsEmpty()) {
+ *aOut = false;
+ return NS_OK;
+ }
+
+ // Always isolate for other non-chrome contexts
if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
return NS_OK;
}
// Isolation is only disabled if the attribute is present
*aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
return NS_OK;
}
+/* [infallible] */ nsresult
+nsGenericHTMLFrameElement::GetRemote(bool *aOut)
+{
+ nsString addonId;
+ NodePrincipal()->GetAddonId(addonId);
+ if (!addonId.IsEmpty()) {
+ *aOut = true;
+ return NS_OK;
+ }
+
+ *aOut = HasAttr(kNameSpaceID_None, nsGkAtoms::Remote);
+ return NS_OK;
+}
+
NS_IMETHODIMP
nsGenericHTMLFrameElement::DisallowCreateFrameLoader()
{
MOZ_ASSERT(!mFrameLoader);
MOZ_ASSERT(!mFrameLoaderCreationDisallowed);
mFrameLoaderCreationDisallowed = true;
return NS_OK;
}
--- a/dom/interfaces/html/nsIMozBrowserFrame.idl
+++ b/dom/interfaces/html/nsIMozBrowserFrame.idl
@@ -31,16 +31,24 @@ interface nsIMozBrowserFrame : nsIDOMMoz
*
* Isolation can be disabled by setting the frame's isolated attribute to
* false. Disabling isolation is only allowed if the containing document has
* browser permission (or equivalent access).
*/
[infallible] readonly attribute boolean isolated;
/**
+ * Gets whether this frame runs in a remote process
+ *
+ * A mozbrowser frame is remote when the containing documentation originates
+ * from a WebExtension, or when the frame has the remote attribute set to true.
+ */
+ [infallible] readonly attribute boolean remote;
+
+ /**
* Normally, a frame tries to create its frame loader when its src is
* modified, or its contentWindow is accessed.
*
* disallowCreateFrameLoader prevents the frame element from creating its
* frame loader (in the same way that not being inside a document prevents the
* creation of a frame loader). allowCreateFrameLoader lifts this restriction.
*
* These methods are not re-entrant -- it is an error to call