[e10s] Null deref crash when running test_pluginstream_newstream.html; r?bobowen, gcp draft
authorHaik Aftandilian <haftandilian@mozilla.com>
Mon, 08 Feb 2016 10:13:27 -0800
changeset 329586 80afdea2631ee10e6e126266e9223f753bb7ff0a
parent 329566 815d689a6e1e7187b10238f2f840d49201d67c2b
child 513986 63286541c45e755b03c66b2894ff1bcd3ae7e680
push id10554
push userhaftandilian@mozilla.com
push dateMon, 08 Feb 2016 18:20:28 +0000
reviewersbobowen, gcp
milestone47.0a1
[e10s] Null deref crash when running test_pluginstream_newstream.html; r?bobowen, gcp Modify the Mac sandbox to allow temporary files to be created in a parent-specified temporary directory. This replaces the NS_OS_TEMP_DIR directory. MozReview-Commit-ID: I1VXN3WXAdF
browser/app/profile/firefox.js
dom/ipc/ContentProcess.cpp
security/sandbox/mac/Sandbox.h
security/sandbox/mac/Sandbox.mm
toolkit/xre/nsAppRunner.cpp
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1216,16 +1216,20 @@ pref("security.sandbox.windows.log.stack
 // 1 -> "an imperfect sandbox designed to allow firefox to run reasonably well"
 // 2 -> "an ideal sandbox which may break many things"
 // This setting is read when the content process is started. On Mac the content
 // process is killed when all windows are closed, so a change will take effect
 // when the 1st window is opened.
 pref("security.sandbox.content.level", 1);
 #endif
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
+pref("security.sandbox.content.tempDirSuffix", "");
+#endif
+
 // This pref governs whether we attempt to work around problems caused by
 // plugins using OS calls to manipulate the cursor while running out-of-
 // process.  These workarounds all involve intercepting (hooking) certain
 // OS calls in the plugin process, then arranging to make certain OS calls
 // in the browser process.  Eventually plugins will be required to use the
 // NPAPI to manipulate the cursor, and these workarounds will be removed.
 // See bug 621117.
 #ifdef XP_MACOSX
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -10,21 +10,58 @@
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
 #include "mozilla/Preferences.h"
 #include "mozilla/WindowsVersion.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #endif
 
+#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/Preferences.h"
+#include "nsDirectoryService.h"
+#include "nsDirectoryServiceDefs.h"
+#endif
+
 using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace dom {
 
+#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+static void
+SetUpSandboxEnvironment()
+{
+  MOZ_ASSERT(nsDirectoryService::gService,
+    "SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
+
+  nsAdoptingString tempDirPath =
+    Preferences::GetString("security.sandbox.content.tempDir");
+  if (tempDirPath.IsEmpty()) {
+    NS_WARNING("security.sandbox.content.tempDir preference is not set.");
+    return;
+  }
+  printf("ContentProcess: security.sandbox.content.tempDir: %s\n",
+    ToNewCString(tempDirPath));
+
+  nsCOMPtr<nsIFile> tempDir;
+  // XXX initialize tempDir with tempDirPath
+  // XXX how to create an nsIFile from a string path?
+
+  // Change the gecko defined temp directory to the directory specified
+  // by the parent in security.sandbox.content.tempDir. Undefine returns
+  // a failure if the property is not already set.
+  Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
+  nsresult rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, tempDir);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+}
+#endif /* defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) */
+
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
 static void
 SetUpSandboxEnvironment()
 {
   MOZ_ASSERT(nsDirectoryService::gService,
     "SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
 
   // A low integrity temp only currently makes sense for Vista or Later and
@@ -80,16 +117,20 @@ ContentProcess::Init()
                   IOThreadChild::channel());
     mXREEmbed.Start();
     mContent.InitXPCOM();
     mContent.InitGraphicsDeviceData();
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
     SetUpSandboxEnvironment();
 #endif
+
+#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+    SetUpSandboxEnvironment();
+#endif
     
     return true;
 }
 
 // Note: CleanUp() never gets called in non-debug builds because we exit early
 // in ContentChild::ActorDestroy().
 void
 ContentProcess::CleanUp()
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -42,16 +42,17 @@ typedef struct _MacSandboxInfo {
       appPath(other.appPath), appBinaryPath(other.appBinaryPath),
       appDir(other.appDir) {}
   MacSandboxType type;
   int32_t level;
   MacSandboxPluginInfo pluginInfo;
   std::string appPath;
   std::string appBinaryPath;
   std::string appDir;
+  std::string appTempDir;
 } MacSandboxInfo;
 
 namespace mozilla {
 
 bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage);
 
 } // namespace mozilla
 
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -416,16 +416,19 @@ static const char contentSandboxRules[] 
   "\n"
   "; bug 1190032\n"
   "    (allow file*\n"
   "        (home-regex \"/Library/Caches/TemporaryItems/plugtmp.*\"))\n"
   "\n"
   "; bug 1201935\n"
   "    (allow file-read*\n"
   "        (home-subpath \"/Library/Caches/TemporaryItems\"))\n"
+  "; bug 1237847 -- XXX replace with tempDir from preferences\n"
+  "    (allow file-write*\n"
+  "        (home-subpath \"/Library/Caches/TemporaryItems\"))\n"
   "  )\n"
   ")\n";
 
 bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage)
 {
   char *profile = NULL;
   if (aInfo.type == MacSandboxType_Plugin) {
     if (OSXVersion::OnLionOrLater()) {
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -703,16 +703,101 @@ CleanUpSandboxEnvironment()
   }
 
   // Get and remove the low integrity Mozilla temp directory.
   // This function already warns if the deletion fails.
   nsCOMPtr<nsIFile> lowIntegrityTemp = GetAndCleanLowIntegrityTemp(tempDirSuffix);
 }
 #endif
 
+#if defined(XP_MACOSX)
+static void
+SetUpSandboxEnvironment(nsIFile *aProfileDir)
+{
+  // A low integrity temp only currently makes sense for Vista and later, e10s
+  // and sandbox pref level >= 1.
+  if (!BrowserTabsRemoteAutostart() ||
+      Preferences::GetInt("security.sandbox.content.level") < 1) {
+    return;
+  }
+
+  nsresult rv;
+
+  // The profile directory is a directory
+  bool isDirectory;
+  rv = aProfileDir->IsDirectory(&isDirectory);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+
+  // Get (and create if blank) temp directory suffix pref.
+  nsAdoptingString tempDirPath =
+    Preferences::GetString("security.sandbox.content.tempDir");
+  //MOZ_ASSERT(tempDirPath.IsEmpty());
+  if (tempDirPath.IsEmpty()) {
+    nsCOMPtr<nsIUUIDGenerator> uuidgen =
+      do_GetService("@mozilla.org/uuid-generator;1", &rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return;
+    }
+
+    nsCOMPtr<nsIFile> tempDir;
+    rv = aProfileDir->Clone(getter_AddRefs(tempDir));
+    if (NS_FAILED(rv)) {
+      return;
+    }
+
+    // The temp dir path preference is not set so we'll
+    // create a temporary directory in the profile directory
+
+    // The name of the temp directory within the profile
+    nsAutoString tempDirName;
+    tempDirName.AssignWithConversion("temp");
+
+    // Navigate to the temp directory within the profile
+    tempDir->Append(tempDirName);
+
+    // Create it if it doesn't exist
+    bool tempExists = false;
+    rv = tempDir->Exists(&tempExists);
+    if (NS_FAILED(rv)) {
+      return;
+    }
+    if (!tempExists) {
+      rv = tempDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
+      if (NS_FAILED(rv)) {
+        return;
+      }
+    }
+
+    nsAutoString tempDirPath;
+    tempDir->GetPath(tempDirPath);
+
+    // Save the pref to be picked up later.
+    rv = Preferences::SetString("security.sandbox.content.tempDir",
+      tempDirPath);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      // If we fail to save the pref we don't want to create the temp dir,
+      // because we won't be able to clean it up later.
+      return;
+    }
+
+    /*
+    nsCOMPtr<nsIPrefService> prefsvc = Preferences::GetService();
+    if (!prefsvc || NS_FAILED(prefsvc->SavePrefFile(nullptr))) {
+      // Again, if we fail to save the pref file we might not be able to clean
+      // up the temp directory, so don't create one.
+      NS_WARNING("Failed to save pref file, cannot create temp dir.");
+      return;
+    }
+    */
+  }
+}
+#endif /* defined(XP_MACOSX) */
+
 bool gSafeMode = false;
 
 /**
  * The nsXULAppInfo object implements nsIFactory so that it can be its own
  * singleton.
  */
 class nsXULAppInfo : public nsIXULAppInfo,
                      public nsIObserver,
@@ -4268,16 +4353,20 @@ XREMain::XRE_mainRun()
     mozilla::InitEventTracing(logToConsole);
   }
 #endif /* MOZ_INSTRUMENT_EVENT_LOOP */
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
   SetUpSandboxEnvironment();
 #endif
 
+#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+  SetUpSandboxEnvironment(mProfD);
+#endif
+
   {
     rv = appStartup->Run();
     if (NS_FAILED(rv)) {
       NS_ERROR("failed to run appstartup");
       gLogConsoleErrors = true;
     }
   }