Bug 795061 - AssertAppProcessPermission: Kill any process that doesn't have the specified permission, not just app processes. r=cjones
authorPhilipp von Weitershausen <philipp@weitershausen.de>
Fri, 28 Sep 2012 10:29:36 -0700
changeset 108632 e81ac71f110718b70c2a881df6d0a84513a17672
parent 108631 96ef3b8bd9ed911a42f1c27cd23604edc846cda1
child 108633 436bbe6d45611a3a15811aeb3008ca1f6dfa23a5
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerscjones
bugs795061
milestone18.0a1
Bug 795061 - AssertAppProcessPermission: Kill any process that doesn't have the specified permission, not just app processes. r=cjones
content/base/test/test_child_process_shutdown_message.html
dom/ipc/AppProcessPermissions.cpp
--- a/content/base/test/test_child_process_shutdown_message.html
+++ b/content/base/test/test_child_process_shutdown_message.html
@@ -21,21 +21,26 @@ const {classes: Cc, interfaces: Ci, util
 const APP_URL = "http://example.org";
 const APP_MANIFEST = "http://example.org/manifest.webapp";
 const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
 
 let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
              .getService(Ci.nsIMessageBroadcaster);
 
 /**
- * Load the example.org app in an <iframe mozbrowser mozapp>
+ * Load the example.org site in an <iframe mozbrowser>
+ *
+ * @param isApp
+ *        If true, the example.org site will be loaded as an app.
  */
-function loadApp(callback) {
+function loadBrowser(isApp, callback) {
   let iframe = document.createElement("iframe");
-  iframe.setAttribute("mozapp", APP_MANIFEST);
+  if (isApp) {
+    iframe.setAttribute("mozapp", APP_MANIFEST);
+  }
   iframe.mozbrowser = true;
   iframe.src = APP_URL;
   document.getElementById("content").appendChild(iframe);
 
   iframe.addEventListener("mozbrowserloadend", function onloadend() {
     iframe.removeEventListener("mozbrowserloadend", onloadend);
     callback(iframe);
   });
@@ -97,40 +102,58 @@ function expectFrameProcessShutdown(ifra
 
   frameMM.addMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, function receiveMessage() {
     frameMM.removeMessageListener(CHILD_PROCESS_SHUTDOWN_MESSAGE, receiveMessage);
     ok(true, "Received 'child-process-shutdown' message from frame message manager.");
     countMessage();
   });
 }
 
-function runTests(callback) {
+function setUp() {
   SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
   SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", true);
   SpecialPowers.addPermission("browser", true, window.document);
+  runNextTest();
+}
 
-  function tearDown() {
-    SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
-    SpecialPowers.clearUserPref("dom.ipc.browser_frames.oop_by_default");
-    SimpleTest.finish();
-  }
-
-  loadApp(function (iframe) {
+function makeKillTest(isApp) function testKill() {
+  loadBrowser(isApp, function (iframe) {
     // We want to make sure we get notified on both the frame and
     // process message managers.
     let frameMM = SpecialPowers.getBrowserFrameMessageManager(iframe);
     prepareProcess(frameMM, function (processMM) {
       // Let's kill the content process by asking for a permission
       // that it doesn't have.
       ok(!processMM.assertPermission("frobnaz"),
          "Content child should not have this permission");
       expectFrameProcessShutdown(iframe, frameMM, processMM, function () {
         iframe.parentNode.removeChild(iframe);
-        tearDown();
+        runNextTest();
       });
     });
   });
 }
 
+function tearDown() {
+  SpecialPowers.clearUserPref("dom.mozBrowserFramesEnabled");
+  SpecialPowers.clearUserPref("dom.ipc.browser_frames.oop_by_default");
+  SimpleTest.finish();
+}
+
+let _tests = [
+  setUp,
+  makeKillTest(false),
+  makeKillTest(true),
+  tearDown
+]
+function runNextTest() {
+  SimpleTest.executeSoon(_tests.shift());
+}
+
+function runTests() {
+  SimpleTest.waitForExplicitFinish();
+  runNextTest();
+}
+
 </script>
 </pre>
 </body>
 </html>
--- a/dom/ipc/AppProcessPermissions.cpp
+++ b/dom/ipc/AppProcessPermissions.cpp
@@ -23,27 +23,29 @@ AssertAppProcessPermission(PBrowserParen
 {
   if (!aActor) {
     NS_WARNING("Testing permissions for null actor");
     return false;
   }
 
   TabParent* tab = static_cast<TabParent*>(aActor);
   nsCOMPtr<mozIApplication> app = tab->GetApp();
+  bool hasPermission = false;
+
   // isBrowser frames inherit their app descriptor to identify their
   // data storage, but they don't inherit the permissions associated
   // with that descriptor.
-  if (!app || tab->IsBrowserElement()) {
-    return false;
+  if (app && !tab->IsBrowserElement()) {
+    if (!NS_SUCCEEDED(app->HasPermission(aPermission, &hasPermission))) {
+      hasPermission = false;
+    }
   }
 
-  bool hasPermission = false;
-  if (!NS_SUCCEEDED(app->HasPermission(aPermission, &hasPermission)) ||
-      !hasPermission) {
-    printf_stderr("Security problem: App process does not have `%s' permission.  It will be killed.", aPermission);
+  if (!hasPermission) {
+    printf_stderr("Security problem: Content process does not have `%s' permission.  It will be killed.\n", aPermission);
     ContentParent* process = static_cast<ContentParent*>(aActor->Manager());
     process->KillHard();
   }
   return hasPermission;
 }
 
 bool
 AssertAppProcessPermission(PContentParent* aActor, const char* aPermission)