Bug 1236108: Modify sandbox initialization code to use directory service to obtain content process temp directory; r?bobowen, haik
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
--- 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
@@ -597,47 +597,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;
@@ -708,17 +686,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;
@@ -730,26 +708,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.