Bug 1270018: Separate NS_APP_CONTENT_PROCESS_TEMP_DIR into fallible and infallible variants; r?bsmedberg draft
authorAaron Klotz <aklotz@mozilla.com>
Thu, 05 May 2016 18:06:18 -0600
changeset 367951 c42a379854b749a1a02299bbdaf7b1e5cdbf8686
parent 356894 ab0044bfa1df858919797bcd6a9aef76a668cd4a
child 521143 da6a76d338472a7670ac35939b5fac059b94ab83
push id18391
push useraklotz@mozilla.com
push dateTue, 17 May 2016 19:14:14 +0000
reviewersbsmedberg
bugs1270018
milestone49.0a1
Bug 1270018: Separate NS_APP_CONTENT_PROCESS_TEMP_DIR into fallible and infallible variants; r?bsmedberg MozReview-Commit-ID: HX4xNQxAVyL
dom/ipc/ContentProcess.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsXREDirProvider.cpp
toolkit/xre/nsXREDirProvider.h
xpcom/io/nsAppDirectoryServiceDefs.h
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -84,17 +84,17 @@ SetUpSandboxEnvironment()
     "SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
 
   if (!IsSandboxTempDirRequired()) {
     return;
   }
 
   nsCOMPtr<nsIFile> sandboxedContentTemp;
   nsresult rv =
-    nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
+    nsDirectoryService::gService->Get(NS_APP_SANDBOXED_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.
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -612,17 +612,17 @@ CanShowProfileManager()
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 static already_AddRefed<nsIFile>
 GetAndCleanTempDir()
 {
   // Get the directory within which we'll place the
   // sandbox-writable temp directory
   nsCOMPtr<nsIFile> tempDir;
-  nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
+  nsresult rv = NS_GetSpecialDirectory(NS_APP_SANDBOXED_CONTENT_PROCESS_TEMP_DIR,
                                        getter_AddRefs(tempDir));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   // Don't return an error if the directory doesn't exist.
   // Windows Remove() returns NS_ERROR_FILE_NOT_FOUND while
   // OS X returns NS_ERROR_FILE_TARGET_DOES_NOT_EXIST.
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -394,23 +394,47 @@ nsXREDirProvider::GetFile(const char* aP
   else if (!strcmp(aProperty, XRE_ADDON_APP_DIR)) {
     nsCOMPtr<nsIDirectoryServiceProvider> dirsvc(do_GetService("@mozilla.org/file/directory_service;1", &rv));
     if (NS_FAILED(rv))
       return rv;
     bool unused;
     rv = dirsvc->GetFile("XCurProcD", &unused, getter_AddRefs(file));
   }
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+  else if (!strcmp(aProperty, NS_APP_SANDBOXED_CONTENT_PROCESS_TEMP_DIR)) {
+    if (!mSandboxedContentTempDir &&
+        NS_FAILED((rv = LoadSandboxedContentProcessTempDir()))) {
+      return rv;
+    }
+    rv = mSandboxedContentTempDir->Clone(getter_AddRefs(file));
+  }
+#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
   else if (!strcmp(aProperty, NS_APP_CONTENT_PROCESS_TEMP_DIR)) {
-    if (!mContentTempDir && NS_FAILED((rv = LoadContentProcessTempDir()))) {
-      return rv;
+#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+    if (!mContentTempDir) {
+      rv = NS_OK;
+      if (!mSandboxedContentTempDir) {
+        rv = LoadSandboxedContentProcessTempDir();
+      }
+      if (NS_SUCCEEDED(rv)) {
+        mContentTempDir = mSandboxedContentTempDir;
+      }
+    }
+#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+    if (!mContentTempDir) {
+      // Just use the normal temp directory if the sandboxed temp dir is
+      // unavailable (perhaps due to sandboxing being turned off)
+      rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
+                                  getter_AddRefs(mContentTempDir));
+      if (NS_FAILED(rv)) {
+        return rv;
+      }
     }
     rv = mContentTempDir->Clone(getter_AddRefs(file));
   }
-#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
   else if (NS_SUCCEEDED(GetProfileStartupDir(getter_AddRefs(file)))) {
     // We need to allow component, xpt, and chrome registration to
     // occur prior to the profile-after-change notification.
     if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR)) {
       rv = file->AppendNative(NS_LITERAL_CSTRING("chrome"));
     }
   }
 
@@ -627,45 +651,43 @@ LoadExtensionDirectories(nsINIParser &pa
     }
   }
   while (true);
 }
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 
 static const char*
-GetContentProcessTempBaseDirKey()
+GetSandboxedContentProcessTempBaseDirKey()
 {
 #if defined(XP_WIN)
   return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
 #else
   return NS_OS_TEMP_DIR;
 #endif
 }
 
 nsresult
-nsXREDirProvider::LoadContentProcessTempDir()
+nsXREDirProvider::LoadSandboxedContentProcessTempDir()
 {
 #if defined(XP_WIN)
   const bool isSandboxDisabled = !mozilla::IsVistaOrLater() ||
     (Preferences::GetInt("security.sandbox.content.level") < 1);
 #elif defined(XP_MACOSX)
   const bool isSandboxDisabled =
     Preferences::GetInt("security.sandbox.content.level") < 1;
 #endif
 
   if (isSandboxDisabled) {
-    // Just use the normal temp directory if sandboxing is turned off
-    return NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
-                                  getter_AddRefs(mContentTempDir));
+    return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIFile> localFile;
 
-  nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),
+  nsresult rv = NS_GetSpecialDirectory(GetSandboxedContentProcessTempBaseDirKey(),
                                        getter_AddRefs(localFile));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsAutoString tempDirSuffix;
   rv = Preferences::GetString("security.sandbox.content.tempDirSuffix",
                               &tempDirSuffix);
@@ -676,17 +698,17 @@ nsXREDirProvider::LoadContentProcessTemp
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   rv = localFile->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  localFile.swap(mContentTempDir);
+  localFile.swap(mSandboxedContentTempDir);
   return NS_OK;
 }
 
 #endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
 
 void
 nsXREDirProvider::LoadExtensionBundleDirectories()
 {
--- a/toolkit/xre/nsXREDirProvider.h
+++ b/toolkit/xre/nsXREDirProvider.h
@@ -118,17 +118,17 @@ protected:
   static nsresult AppendSysUserExtensionPath(nsIFile* aFile);
 
   // Internal helper that splits a path into components using the '/' and '\\'
   // delimiters.
   static inline nsresult AppendProfileString(nsIFile* aFile, const char* aPath);
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
   // Load the temp directory for sandboxed content processes
-  nsresult LoadContentProcessTempDir();
+  nsresult LoadSandboxedContentProcessTempDir();
 #endif
 
   // Calculate and register extension and theme bundle directories.
   void LoadExtensionBundleDirectories();
 
 #ifdef MOZ_B2G
   // Calculate and register app-bundled extension directories.
   void LoadAppBundleDirs();
@@ -142,16 +142,17 @@ protected:
   // On OSX, mGREBinDir points to .app/Contents/MacOS
   nsCOMPtr<nsIFile>      mGREBinDir;
   // On OSX, mXULAppDir points to .app/Contents/Resources/browser
   nsCOMPtr<nsIFile>      mXULAppDir;
   nsCOMPtr<nsIFile>      mProfileDir;
   nsCOMPtr<nsIFile>      mProfileLocalDir;
   bool                   mProfileNotified;
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
+  nsCOMPtr<nsIFile>      mSandboxedContentTempDir;
+#endif
   nsCOMPtr<nsIFile>      mContentTempDir;
-#endif
   nsCOMArray<nsIFile>    mAppBundleDirectories;
   nsCOMArray<nsIFile>    mExtensionDirectories;
   nsCOMArray<nsIFile>    mThemeDirectories;
 };
 
 #endif
--- a/xpcom/io/nsAppDirectoryServiceDefs.h
+++ b/xpcom/io/nsAppDirectoryServiceDefs.h
@@ -80,12 +80,21 @@
 
 #define NS_APP_INSTALL_CLEANUP_DIR              "XPIClnupD"  //location of xpicleanup.dat xpicleanup.exe 
 
 #define NS_APP_INDEXEDDB_PARENT_DIR             "indexedDBPDir"
 
 #define NS_APP_PERMISSION_PARENT_DIR            "permissionDBPDir"
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
-#define NS_APP_CONTENT_PROCESS_TEMP_DIR         "ContentTmpD"
+
+// This is the property that should be used for resolving the content process
+// TEMP path 99% of the time when sandboxing is on. It will fail if
+// sandboxing is disabled.
+#define NS_APP_SANDBOXED_CONTENT_PROCESS_TEMP_DIR "SandboxedContentTmpD"
+
 #endif // (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 
+// This property is similar to NS_APP_SANDBOXED_CONTENT_PROCESS_TEMP_DIR but
+// will always succeed, regardless of sandbox state.
+#define NS_APP_CONTENT_PROCESS_TEMP_DIR         "ContentTmpD"
+
 #endif // nsAppDirectoryServiceDefs_h___