Bug 1318532 - Force remote='true' and noisolation='true' to WebExtensions mozbrowser iframes. r=smaug draft
authorTim Nguyen <ntim.bugs@gmail.com>
Thu, 16 Mar 2017 22:41:09 +0000
changeset 610934 be8e734b138496d6e22cc757c08f0fd980b113b7
parent 610933 e1de6bf7e6588a7348beff6bba6830d2f5f5a065
child 638011 d71b898401f650c4ca2fb867c1a3f8f26822e7f2
push id69059
push userbmo:ntim.bugs@gmail.com
push dateWed, 19 Jul 2017 00:19:55 +0000
reviewerssmaug
bugs1318532
milestone56.0a1
Bug 1318532 - Force remote='true' and noisolation='true' to WebExtensions mozbrowser iframes. r=smaug MozReview-Commit-ID: K6AC918A4Zh
dom/base/nsFrameLoader.cpp
dom/html/nsGenericHTMLFrameElement.cpp
dom/interfaces/html/nsIMozBrowserFrame.idl
--- 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