Bug 1393150 prevent remote extensions when e10s is off, r?kmag draft
authorShane Caraveo <scaraveo@mozilla.com>
Thu, 14 Sep 2017 15:12:45 -0700
changeset 665090 9760fd4d8b29d33af8fd13f5174e9d6a012f83d6
parent 664985 593158cd491002031b4527a95d9bfac79c0cdcef
child 731645 053d4315e016f5f501b6bb433f0421fd8490a45e
push id79918
push usermixedpuppy@gmail.com
push dateThu, 14 Sep 2017 22:13:08 +0000
reviewerskmag
bugs1393150
milestone57.0a1
Bug 1393150 prevent remote extensions when e10s is off, r?kmag MozReview-Commit-ID: HjLLa9vx2UW
browser/modules/E10SUtils.jsm
devtools/server/tests/mochitest/chrome.ini
dom/webidl/WebExtensionPolicy.webidl
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionPolicyService.cpp
toolkit/components/extensions/ExtensionPolicyService.h
toolkit/components/extensions/WebExtensionPolicy.cpp
toolkit/components/extensions/WebExtensionPolicy.h
--- a/browser/modules/E10SUtils.jsm
+++ b/browser/modules/E10SUtils.jsm
@@ -6,18 +6,16 @@
 
 this.EXPORTED_SYMBOLS = ["E10SUtils"];
 
 const {interfaces: Ci, utils: Cu, classes: Cc} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyPreferenceGetter(this, "useRemoteWebExtensions",
-                                      "extensions.webextensions.remote", false);
 XPCOMUtils.defineLazyPreferenceGetter(this, "useSeparateFileUriProcess",
                                       "browser.tabs.remote.separateFileUriProcess", false);
 XPCOMUtils.defineLazyPreferenceGetter(this, "allowLinkedWebInFileUriProcess",
                                       "browser.tabs.remote.allowLinkedWebInFileUriProcess", false);
 XPCOMUtils.defineLazyModuleGetter(this, "Utils",
                                   "resource://gre/modules/sessionstore/Utils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "console",
                                   "resource://gre/modules/Console.jsm");
@@ -180,17 +178,17 @@ this.E10SUtils = {
         if (chromeReg.canLoadURLRemotely(aURI) &&
             aPreferredRemoteType != NOT_REMOTE) {
           return DEFAULT_REMOTE_TYPE;
         }
 
         return NOT_REMOTE;
 
       case "moz-extension":
-        return useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE;
+        return WebExtensionPolicy.useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE;
 
       default:
         // For any other nested URIs, we use the innerURI to determine the
         // remote type. In theory we should use the innermost URI, but some URIs
         // have fake inner URIs (e.g. about URIs with inner moz-safe-about) and
         // if such URIs are wrapped in other nested schemes like view-source:,
         // we don't want to "skip" past "about:" by going straight to the
         // innermost URI. Any URIs like this will need to be handled in the
--- a/devtools/server/tests/mochitest/chrome.ini
+++ b/devtools/server/tests/mochitest/chrome.ini
@@ -98,11 +98,13 @@ support-files =
 [test_styles-computed.html]
 [test_styles-layout.html]
 [test_styles-matched.html]
 [test_styles-modify.html]
 [test_styles-svg.html]
 [test_unsafeDereference.html]
 [test_webconsole-node-grip.html]
 [test_webextension-addon-debugging-connect.html]
+skip-if = !e10s # test is designed to work on e10s only
 [test_webextension-addon-debugging-reload.html]
+skip-if = !e10s # test is designed to work on e10s only
 [test_websocket-server.html]
 skip-if = false
--- a/dom/webidl/WebExtensionPolicy.webidl
+++ b/dom/webidl/WebExtensionPolicy.webidl
@@ -77,20 +77,28 @@ interface WebExtensionPolicy {
    *
    * Only one extension policy with a given ID or hostname may be active at a
    * time. Attempting to activate a policy while a conflicting policy is
    * active will raise an error.
    */
   [Affects=Everything, SetterThrows]
   attribute boolean active;
 
+  /**
+   * True if both e10s and webextensions.remote are enabled.  This must be
+   * used instead of checking the remote pref directly since remote extensions
+   * require both to be enabled.
+   */
+  static readonly attribute boolean useRemoteWebExtensions;
 
+  /**
+   * True if the calling process is an extension process.
+   */
   static readonly attribute boolean isExtensionProcess;
 
-
   /**
    * Returns true if the extension has cross-origin access to the given URI.
    */
   boolean canAccessURI(URI uri, optional boolean explicit = false);
 
   /**
    * Returns true if the extension currently has the given permission.
    */
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -77,18 +77,16 @@ Cu.import("resource://gre/modules/Extens
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetters(this, {
   aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"],
   uuidGen: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"],
 });
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "processCount", "dom.ipc.processCount.extension");
-XPCOMUtils.defineLazyPreferenceGetter(this, "useRemoteWebExtensions",
-                                      "extensions.webextensions.remote", false);
 
 var {
   GlobalManager,
   ParentAPIManager,
   StartupCache,
   apiManager: Management,
 } = ExtensionParent;
 
@@ -1021,17 +1019,17 @@ this.Extension = class extends Extension
 
     this.addonData = addonData;
     this.startupReason = startupReason;
 
     if (["ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(startupReason)) {
       StartupCache.clearAddonData(addonData.id);
     }
 
-    this.remote = useRemoteWebExtensions;
+    this.remote = !WebExtensionPolicy.isExtensionProcess;
 
     if (this.remote && processCount !== 1) {
       throw new Error("Out-of-process WebExtensions are not supported with multiple child processes");
     }
 
     // This is filled in the first time an extension child is created.
     this.parentMessageManager = null;
 
--- a/toolkit/components/extensions/ExtensionPolicyService.cpp
+++ b/toolkit/components/extensions/ExtensionPolicyService.cpp
@@ -15,16 +15,17 @@
 #include "mozIExtensionProcessScript.h"
 #include "nsEscape.h"
 #include "nsGkAtoms.h"
 #include "nsIChannel.h"
 #include "nsIContentPolicy.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 #include "nsILoadInfo.h"
+#include "nsIXULRuntime.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 
 using namespace extensions;
 
@@ -76,25 +77,32 @@ ExtensionPolicyService::ExtensionPolicyS
   mObs = services::GetObserverService();
   MOZ_RELEASE_ASSERT(mObs);
 
   Preferences::AddBoolVarCache(&sRemoteExtensions, "extensions.webextensions.remote", false);
 
   RegisterObservers();
 }
 
+bool
+ExtensionPolicyService::UseRemoteExtensions() const
+{
+  return sRemoteExtensions && BrowserTabsRemoteAutostart();
+}
 
 bool
 ExtensionPolicyService::IsExtensionProcess() const
 {
-  if (sRemoteExtensions && XRE_IsContentProcess()) {
+  bool isRemote = UseRemoteExtensions();
+
+  if (isRemote && XRE_IsContentProcess()) {
     auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType();
     return remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE);
   }
-  return XRE_IsParentProcess();
+  return !isRemote && XRE_IsParentProcess();
 }
 
 
 WebExtensionPolicy*
 ExtensionPolicyService::GetByURL(const URLInfo& aURL)
 {
   if (aURL.Scheme() == nsGkAtoms::moz_extension) {
     return GetByHost(aURL.Host());
--- a/toolkit/components/extensions/ExtensionPolicyService.h
+++ b/toolkit/components/extensions/ExtensionPolicyService.h
@@ -70,16 +70,17 @@ public:
   void GetAll(nsTArray<RefPtr<WebExtensionPolicy>>& aResult);
 
   bool RegisterExtension(WebExtensionPolicy& aPolicy);
   bool UnregisterExtension(WebExtensionPolicy& aPolicy);
 
   void BaseCSP(nsAString& aDefaultCSP) const;
   void DefaultCSP(nsAString& aDefaultCSP) const;
 
+  bool UseRemoteExtensions() const;
   bool IsExtensionProcess() const;
 
 protected:
   virtual ~ExtensionPolicyService() = default;
 
 private:
   ExtensionPolicyService();
 
--- a/toolkit/components/extensions/WebExtensionPolicy.cpp
+++ b/toolkit/components/extensions/WebExtensionPolicy.cpp
@@ -208,16 +208,22 @@ WebExtensionPolicy::GetURL(const nsAStri
   MOZ_TRY(NS_NewURI(getter_AddRefs(uri), spec));
 
   MOZ_TRY(uri->Resolve(NS_ConvertUTF16toUTF8(aPath), spec));
 
   return NS_ConvertUTF8toUTF16(spec);
 }
 
 /* static */ bool
+WebExtensionPolicy::UseRemoteWebExtensions(GlobalObject& aGlobal)
+{
+  return EPS().UseRemoteExtensions();
+}
+
+/* static */ bool
 WebExtensionPolicy::IsExtensionProcess(GlobalObject& aGlobal)
 {
   return EPS().IsExtensionProcess();
 }
 
 nsCString
 WebExtensionPolicy::BackgroundPageHTML() const
 {
--- a/toolkit/components/extensions/WebExtensionPolicy.h
+++ b/toolkit/components/extensions/WebExtensionPolicy.h
@@ -135,16 +135,17 @@ public:
 
   static already_AddRefed<WebExtensionPolicy>
   GetByHostname(dom::GlobalObject& aGlobal, const nsACString& aHostname);
 
   static already_AddRefed<WebExtensionPolicy>
   GetByURI(dom::GlobalObject& aGlobal, nsIURI* aURI);
 
 
+  static bool UseRemoteWebExtensions(dom::GlobalObject& aGlobal);
   static bool IsExtensionProcess(dom::GlobalObject& aGlobal);
 
 
   nsISupports* GetParentObject() const { return mParent; }
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
 
 protected: