Bug 776850: Kill subprocesses that fail backstop permission checks. r=jlebar
authorChris Jones <jones.chris.g@gmail.com>
Wed, 05 Sep 2012 15:18:48 -0700
changeset 104354 1f990752e27cc68c659eb370c41f6de6e461f524
parent 104353 81b3c65bc17ab3a8c68b16b6b53db9890a0654ee
child 104355 5c580e01ae0c4860856475d7e6f85954debc23c2
push id23417
push userryanvm@gmail.com
push dateThu, 06 Sep 2012 02:27:31 +0000
treeherdermozilla-central@501f4e46a88c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs776850
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 776850: Kill subprocesses that fail backstop permission checks. r=jlebar
dom/ipc/AppProcessPermissions.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
--- a/dom/ipc/AppProcessPermissions.cpp
+++ b/dom/ipc/AppProcessPermissions.cpp
@@ -34,16 +34,18 @@ AppProcessHasPermission(PBrowserParent* 
   if (!app || tab->IsBrowserElement()) {
     return 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);
+    ContentParent* process = static_cast<ContentParent*>(aActor->Manager());
+    process->KillHard();
   }
   return hasPermission;
 }
 
 bool
 AppProcessHasPermission(PContentParent* aActor, const char* aPermission)
 {
   const InfallibleTArray<PBrowserParent*>& browsers =
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -518,27 +518,18 @@ ContentParent::OnChannelConnected(int32 
 
 void
 ContentParent::ProcessingError(Result what)
 {
     if (MsgDropped == what) {
         // Messages sent after crashes etc. are not a big deal.
         return;
     }
-    // Other errors are big deals.  This ensures the process is
-    // eventually killed, but doesn't immediately KILLITWITHFIRE
-    // because we want to get a minidump if possible.  After a timeout
-    // though, the process is forceably killed.
-    if (!KillProcess(OtherProcess(), 1, false)) {
-        NS_WARNING("failed to kill subprocess!");
-    }
-    XRE_GetIOMessageLoop()->PostTask(
-        FROM_HERE,
-        NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
-                            OtherProcess(), /*force=*/true));
+    // Other errors are big deals.
+    KillHard();
 }
 
 namespace {
 
 void
 DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
 {
     XRE_GetIOMessageLoop()
@@ -1226,16 +1217,32 @@ ContentParent::GetOrCreateActorForBlob(n
 
   if (!SendPBlobConstructor(actor, params)) {
     return nullptr;
   }
 
   return actor;
 }
 
+void
+ContentParent::KillHard()
+{
+    // This ensures the process is eventually killed, but doesn't
+    // immediately KILLITWITHFIRE because we want to get a minidump if
+    // possible.  After a timeout though, the process is forceably
+    // killed.
+    if (!KillProcess(OtherProcess(), 1, false)) {
+        NS_WARNING("failed to kill subprocess!");
+    }
+    XRE_GetIOMessageLoop()->PostTask(
+        FROM_HERE,
+        NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
+                            OtherProcess(), /*force=*/true));
+}
+
 PCrashReporterParent*
 ContentParent::AllocPCrashReporter(const NativeThreadId& tid,
                                    const uint32_t& processType)
 {
 #ifdef MOZ_CRASHREPORTER
   return new CrashReporterParent();
 #else
   return nullptr;
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -107,16 +107,23 @@ public:
     }
 
     bool NeedsPermissionsUpdate() {
         return mSendPermissionUpdates;
     }
 
     BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
 
+    /**
+     * Kill our subprocess and make sure it dies.  Should only be used
+     * in emergency situations since it bypasses the normal shutdown
+     * process.
+     */
+    void KillHard();
+
 protected:
     void OnChannelConnected(int32 pid);
     virtual void ActorDestroy(ActorDestroyReason why);
 
 private:
     typedef base::ChildPrivileges ChildOSPrivileges;
 
     static nsDataHashtable<nsStringHashKey, ContentParent*> *gAppContentParents;