Bug 1236108 - Modify sandbox initialization code to use directory service to obtain content process temp directory. r=bobowen, r=haik, a=lizzard
☠☠ backed out by 34a219cbd67d ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Tue, 08 Mar 2016 11:02:27 -0800
changeset 325312 26e323cbbfc0fe521895f474a1b468a1e10724f1
parent 325311 1864afbb3bd4405c84978bd9c080931e3ad235d8
child 325313 d59774690fc8154b24ba6ac4a37118350cdc7cfd
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen, haik, lizzard
bugs1236108
milestone47.0a2
Bug 1236108 - Modify sandbox initialization code to use directory service to obtain content process temp directory. r=bobowen, r=haik, a=lizzard The previous patch in this series creates a new directory service entry specifically for obtaining the content process temp directory. This patch converts everything else to reference that entry. It also sets appropriate environment variables in the content processes so that system APIs automatically pick up the directory. This is necessary for the crash reporter to be able to call those APIs in exception handling contexts. MozReview-Commit-ID: DF6aNKrWnWp
dom/ipc/ContentProcess.cpp
toolkit/xre/nsAppRunner.cpp
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -7,18 +7,23 @@
 #include "mozilla/ipc/IOThreadChild.h"
 
 #include "ContentProcess.h"
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
 #include "mozilla/WindowsVersion.h"
 #endif
 
+#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+#include <stdlib.h>
+#endif
+
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 #include "mozilla/Preferences.h"
+#include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #endif
 
 using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace dom {
@@ -28,80 +33,83 @@ static bool
 IsSandboxTempDirRequired()
 {
   // On Windows, a sandbox-writable temp directory is only used
   // for Vista or later with sandbox pref level >= 1.
   return (IsVistaOrLater() &&
     (Preferences::GetInt("security.sandbox.content.level") >= 1));
 }
 
-static const char*
-SandboxTempDirParent()
+static void
+SetTmpEnvironmentVariable(nsIFile* aValue)
 {
-  // On Windows, the sandbox-writable temp directory resides in the
-  // low integrity sandbox base directory.
-  return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
+  // Save the TMP environment variable so that is is picked up by GetTempPath().
+  // Note that we specifically write to the TMP variable, as that is the first
+  // variable that is checked by GetTempPath() to determine its output.
+  nsAutoString fullTmpPath;
+  nsresult rv = aValue->GetPath(fullTmpPath);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+  NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", fullTmpPath.get()));
+  // We also set TEMP in case there is naughty third-party code that is
+  // referencing the environment variable directly.
+  NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", fullTmpPath.get()));
 }
 #endif
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 static bool
 IsSandboxTempDirRequired()
 {
   // On OSX, use the sandbox-writable temp when the pref level >= 1.
   return (Preferences::GetInt("security.sandbox.content.level") >= 1);
 }
 
-static const char*
-SandboxTempDirParent()
+static void
+SetTmpEnvironmentVariable(nsIFile* aValue)
 {
-  return NS_OS_TEMP_DIR;
+  nsAutoCString fullTmpPath;
+  nsresult rv = aValue->GetNativePath(fullTmpPath);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+  NS_WARN_IF(setenv("TMPDIR", fullTmpPath.get(), 1) != 0);
 }
 #endif
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 static void
 SetUpSandboxEnvironment()
 {
   MOZ_ASSERT(nsDirectoryService::gService,
     "SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
 
   if (!IsSandboxTempDirRequired()) {
     return;
   }
 
-  nsAdoptingString tempDirSuffix =
-    Preferences::GetString("security.sandbox.content.tempDirSuffix");
-  if (tempDirSuffix.IsEmpty()) {
-    NS_WARNING("Sandbox-writable temp directory suffix pref not set.");
-    return;
-  }
-
-  // Get the parent of our sandbox writable temp directory.
-  nsCOMPtr<nsIFile> lowIntegrityTemp;
-  nsresult rv = nsDirectoryService::gService->Get(SandboxTempDirParent(),
-                                                  NS_GET_IID(nsIFile),
-                                                  getter_AddRefs(lowIntegrityTemp));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  // Append our profile specific temp name.
-  rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
+  nsCOMPtr<nsIFile> sandboxedContentTemp;
+  nsresult rv =
+    nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
+                                      NS_GET_IID(nsIFile),
+                                      getter_AddRefs(sandboxedContentTemp));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   // Change the gecko defined temp directory to our sandbox-writable one.
   // Undefine returns a failure if the property is not already set.
   Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
-  rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
+  rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, sandboxedContentTemp);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
+
+  SetTmpEnvironmentVariable(sandboxedContentTemp);
 }
 #endif
 
 void
 ContentProcess::SetAppDir(const nsACString& aPath)
 {
   mXREEmbed.SetAppDir(aPath);
 }
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -598,47 +598,25 @@ ProcessDDE(nsINativeAppSupport* aNative,
  * @return true in all environments
 */
 static bool
 CanShowProfileManager()
 {
   return true;
 }
 
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
-static const char*
-SandboxTempDirParent()
-{
-  return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
-}
-#endif
-
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-static const char*
-SandboxTempDirParent()
-{
-  return NS_OS_TEMP_DIR;
-}
-#endif
-
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 static already_AddRefed<nsIFile>
-GetAndCleanTempDir(const nsAString& aTempDirSuffix)
+GetAndCleanTempDir()
 {
   // Get the directory within which we'll place the
   // sandbox-writable temp directory
   nsCOMPtr<nsIFile> tempDir;
-  nsresult rv = NS_GetSpecialDirectory(SandboxTempDirParent(),
-      getter_AddRefs(tempDir));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-
-  // Append our profile specific temp name.
-  rv = tempDir->Append(NS_LITERAL_STRING("Temp-") + aTempDirSuffix);
+  nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
+                                       getter_AddRefs(tempDir));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   rv = tempDir->Remove(/* aRecursive */ true);
   if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) {
     NS_WARNING("Failed to delete temp directory.");
     return nullptr;
@@ -709,17 +687,17 @@ SetUpSandboxEnvironment()
       // 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;
     }
   }
 
   // Get (and clean up if still there) the sandbox-writable temp directory.
-  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir(tempDirSuffix);
+  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
   if (!tempDir) {
     NS_WARNING("Failed to get or clean sandboxed temp directory.");
     return;
   }
 
   rv = tempDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
@@ -731,26 +709,19 @@ CleanUpSandboxEnvironment()
 {
 #if defined(XP_WIN)
   // We can't have created the temp directory before Vista.
   if (!IsVistaOrLater()) {
     return;
   }
 #endif
 
-  // Get temp directory suffix pref.
-  nsAdoptingString tempDirSuffix =
-    Preferences::GetString("security.sandbox.content.tempDirSuffix");
-  if (tempDirSuffix.IsEmpty()) {
-    return;
-  }
-
   // Get and remove the sandbox-writable temp directory.
   // This function already warns if the deletion fails.
-  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir(tempDirSuffix);
+  nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
 }
 #endif
 
 bool gSafeMode = false;
 
 /**
  * The nsXULAppInfo object implements nsIFactory so that it can be its own
  * singleton.