Bug 782456, part 2: Inherit privileges in apps that have permissions that require them. Sigh. r=jlebar
authorChris Jones <jones.chris.g@gmail.com>
Wed, 29 Aug 2012 09:24:48 -0300
changeset 103764 dd12dcbb264b3598f1e3673394e054882b08785b
parent 103763 8f22c4560de7c61a4e72c71cbefcce8c989aa349
child 103765 b0a07b59d5d250c507b1c34e7101b6ed65e39f66
push id23376
push userryanvm@gmail.com
push dateThu, 30 Aug 2012 00:15:25 +0000
treeherdermozilla-central@706174d31a02 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs782456
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 782456, part 2: Inherit privileges in apps that have permissions that require them. Sigh. r=jlebar
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -184,17 +184,18 @@ ContentParent::PreallocateAppProcess()
     if (sPreallocateAppProcessTask) {
         // We were called directly while a delayed task was scheduled.
         sPreallocateAppProcessTask->Cancel();
         sPreallocateAppProcessTask = nullptr;
     }
 
     sPreallocatedAppProcess =
         new ContentParent(MAGIC_PREALLOCATED_APP_MANIFEST_URL,
-                          /*isBrowserElement=*/false);
+                          /*isBrowserElement=*/false,
+                          base::PRIVILEGES_DEFAULT);
     sPreallocatedAppProcess->Init();
 }
 
 /*static*/ void
 ContentParent::DelayedPreallocateAppProcess()
 {
     sPreallocateAppProcessTask = nullptr;
     if (!sPreallocatedAppProcess) {
@@ -270,16 +271,29 @@ ContentParent::GetNewOrUsed(bool aForBro
     nsRefPtr<ContentParent> p =
         new ContentParent(/* appManifestURL = */ EmptyString(),
                           aForBrowserElement);
     p->Init();
     gNonAppContentParents->AppendElement(p);
     return p;
 }
 
+static bool
+AppNeedsInheritedOSPrivileges(mozIApplication* aApp)
+{
+    bool needsInherit = false;
+    // FIXME/bug 785592: implement a CameraBridge so we don't have to
+    // hack around with OS permissions
+    if (NS_FAILED(aApp->HasPermission("camera", &needsInherit))) {
+        NS_WARNING("Unable to check permissions.  Breakage may follow.");
+        return false;
+    }
+    return needsInherit;
+}
+
 /*static*/ TabParent*
 ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
 {
     // We currently don't set the <app> ancestor for <browser> content
     // correctly.  This assertion is to notify the person who fixes
     // this code that they need to reevaluate places here where we may
     // make bad assumptions based on that bug.
     MOZ_ASSERT(!aApp || !aIsBrowserElement);
@@ -321,23 +335,30 @@ ContentParent::CreateBrowser(mozIApplica
     uint32_t appId;
     if (NS_FAILED(appsService->GetAppLocalIdByManifestURL(manifestURL, &appId))) {
         NS_ERROR("Failed to get local app ID");
         return nullptr;
     }
 
     nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
     if (!p) {
-        p = MaybeTakePreallocatedAppProcess();
-        if (p) {
-            p->SetManifestFromPreallocated(manifestURL);
+        if (AppNeedsInheritedOSPrivileges(aApp)) {
+            p = new ContentParent(manifestURL, aIsBrowserElement,
+                                  base::PRIVILEGES_INHERIT);
+            p->Init();
         } else {
-            NS_WARNING("Unable to use pre-allocated app process");
-            p = new ContentParent(manifestURL, aIsBrowserElement);
-            p->Init();
+            p = MaybeTakePreallocatedAppProcess();
+            if (p) {
+                p->SetManifestFromPreallocated(manifestURL);
+            } else {
+                NS_WARNING("Unable to use pre-allocated app process");
+                p = new ContentParent(manifestURL, aIsBrowserElement,
+                                      base::PRIVILEGES_DEFAULT);
+                p->Init();
+            }
         }
         gAppContentParents->Put(manifestURL, p);
     }
 
     nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
     return static_cast<TabParent*>(
         // DeallocPBrowserParent() releases the ref we take here
         p->SendPBrowserConstructor(tp.forget().get(),
@@ -653,30 +674,34 @@ TestShellParent*
 ContentParent::GetTestShellSingleton()
 {
     if (!ManagedPTestShellParent().Length())
         return nullptr;
     return static_cast<TestShellParent*>(ManagedPTestShellParent()[0]);
 }
 
 ContentParent::ContentParent(const nsAString& aAppManifestURL,
-                             bool aIsForBrowser)
-    : mGeolocationWatchID(-1)
+                             bool aIsForBrowser,
+                             ChildOSPrivileges aOSPrivileges)
+    : mSubprocess(nullptr)
+    , mOSPrivileges(aOSPrivileges)
+    , mGeolocationWatchID(-1)
     , mRunToCompletionDepth(0)
     , mShouldCallUnblockChild(false)
     , mIsAlive(true)
     , mSendPermissionUpdates(false)
     , mAppManifestURL(aAppManifestURL)
 {
     // From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
     // PID along with the warning.
     nsDebugImpl::SetMultiprocessMode("Parent");
 
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-    mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
+    mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content,
+                                            aOSPrivileges);
 
     bool useOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
     if (useOffMainThreadCompositing) {
         // We need the subprocess's ProcessHandle to create the
         // PCompositor channel below.  Block just until we have that.
         mSubprocess->LaunchAndWaitForProcessHandle();
     } else {
         mSubprocess->AsyncLaunch();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -112,31 +112,34 @@ public:
 
     BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
 
 protected:
     void OnChannelConnected(int32 pid);
     virtual void ActorDestroy(ActorDestroyReason why);
 
 private:
+    typedef base::ChildPrivileges ChildOSPrivileges;
+
     static nsDataHashtable<nsStringHashKey, ContentParent*> *gAppContentParents;
     static nsTArray<ContentParent*>* gNonAppContentParents;
     static nsTArray<ContentParent*>* gPrivateContent;
 
     static void PreallocateAppProcess();
     static void DelayedPreallocateAppProcess();
     static void ScheduleDelayedPreallocateAppProcess();
     static already_AddRefed<ContentParent> MaybeTakePreallocatedAppProcess();
 
     // Hide the raw constructor methods since we don't want client code
     // using them.
     using PContentParent::SendPBrowserConstructor;
     using PContentParent::SendPTestShellConstructor;
 
-    ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser);
+    ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser,
+                  ChildOSPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT);
     virtual ~ContentParent();
 
     void Init();
 
     // Transform a pre-allocated app process into a "real" app
     // process, for the specified manifest URL.
     void SetManifestFromPreallocated(const nsAString& aAppManifestURL);
 
@@ -277,16 +280,17 @@ private:
                                  const uint32_t& aFlags,
                                  const nsCString& aCategory);
 
     virtual bool RecvPrivateDocShellsExist(const bool& aExist);
 
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     GeckoChildProcessHost* mSubprocess;
+    ChildOSPrivileges mOSPrivileges;
 
     int32_t mGeolocationWatchID;
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
 
     // This is a cache of all of the memory reporters
     // registered in the child process.  To update this, one
     // can broadcast the topic "child-memory-reporter-request" using