Bug 1162327 Part 1: Change low integrity temp to a fixed dir per profile and improve clean-up. r=jimm, r=froydnj

This commit is contained in:
Bob Owen 2015-05-18 11:51:07 +01:00
Родитель 37f134ce21
Коммит f1a00623b7
6 изменённых файлов: 161 добавлений и 91 удалений

Просмотреть файл

@ -1210,6 +1210,9 @@ pref("security.sandbox.content.level", 1);
pref("security.sandbox.content.level", 0);
#endif
// ID (a UUID when set by gecko) that is used as a per profile suffix to a low
// integrity temp directory.
pref("security.sandbox.content.tempDirSuffix", "");
#if defined(MOZ_STACKWALKING)
// This controls the depth of stack trace that is logged when Windows sandbox

Просмотреть файл

@ -10,6 +10,7 @@
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/Preferences.h"
#include "mozilla/WindowsVersion.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#endif
@ -20,72 +21,48 @@ namespace mozilla {
namespace dom {
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static already_AddRefed<nsIFile>
GetLowIntegrityTemp()
{
MOZ_ASSERT(nsDirectoryService::gService,
"GetLowIntegrityTemp relies on nsDirectoryService being initialized");
// A low integrity temp only currently makes sense for sandbox pref level 1.
if (Preferences::GetInt("security.sandbox.content.level") != 1) {
return nullptr;
}
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP,
NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return lowIntegrityTemp.forget();
}
static void
SetUpSandboxEnvironment()
{
MOZ_ASSERT(nsDirectoryService::gService,
"SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
// Setup to use a low integrity temp if available.
nsCOMPtr<nsIFile> lowIntegrityTemp = GetLowIntegrityTemp();
if (!lowIntegrityTemp) {
// A low integrity temp only currently makes sense for Vista or Later and
// sandbox pref level 1.
if (!IsVistaOrLater() ||
Preferences::GetInt("security.sandbox.content.level") != 1) {
return;
}
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
NS_WARNING("Low integrity temp suffix pref not set.");
return;
}
// Get the base low integrity Mozilla temp directory.
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP_BASE,
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);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Change the gecko defined temp directory to our low integrity one.
// 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, lowIntegrityTemp);
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Set TEMP and TMP environment variables.
nsAutoString lowIntegrityTempPath;
rv = lowIntegrityTemp->GetPath(lowIntegrityTempPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool setOK = SetEnvironmentVariableW(L"TEMP", lowIntegrityTempPath.get());
NS_WARN_IF_FALSE(setOK, "Failed to set TEMP to low integrity temp path");
setOK = SetEnvironmentVariableW(L"TMP", lowIntegrityTempPath.get());
NS_WARN_IF_FALSE(setOK, "Failed to set TMP to low integrity temp path");
}
static void
CleanUpSandboxEnvironment()
{
// Remove low integrity temp if it exists.
nsCOMPtr<nsIFile> lowIntegrityTemp = GetLowIntegrityTemp();
if (!lowIntegrityTemp) {
return;
}
// Don't check the return value as the directory will only have been created
// if it has been used.
unused << lowIntegrityTemp->Remove(/* aRecursive */ true);
}
#endif
@ -114,9 +91,6 @@ ContentProcess::Init()
void
ContentProcess::CleanUp()
{
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
CleanUpSandboxEnvironment();
#endif
mXREEmbed.Stop();
}

Просмотреть файл

@ -103,6 +103,10 @@
#ifndef PROCESS_DEP_ENABLE
#define PROCESS_DEP_ENABLE 0x1
#endif
#if defined(MOZ_CONTENT_SANDBOX)
#include "nsIUUIDGenerator.h"
#endif
#endif
#ifdef ACCESSIBILITY
@ -583,6 +587,116 @@ CanShowProfileManager()
return true;
}
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static already_AddRefed<nsIFile>
GetAndCleanLowIntegrityTemp(const nsAString& aTempDirSuffix)
{
// Get the base low integrity Mozilla temp directory.
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOW_INTEGRITY_TEMP_BASE,
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
// Append our profile specific temp name.
rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + aTempDirSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
rv = lowIntegrityTemp->Remove(/* aRecursive */ true);
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) {
NS_WARNING("Failed to delete low integrity temp directory.");
return nullptr;
}
return lowIntegrityTemp.forget();
}
static void
SetUpSandboxEnvironment()
{
// A low integrity temp only currently makes sense for Vista and later, e10s
// and sandbox pref level 1.
if (!IsVistaOrLater() || !BrowserTabsRemoteAutostart() ||
Preferences::GetInt("security.sandbox.content.level") != 1) {
return;
}
// Get (and create if blank) temp directory suffix pref.
nsresult rv;
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsID uuid;
rv = uuidgen->GenerateUUIDInPlace(&uuid);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
char uuidChars[NSID_LENGTH];
uuid.ToProvidedString(uuidChars);
tempDirSuffix.AssignASCII(uuidChars);
// Save the pref to be picked up later.
rv = Preferences::SetCString("security.sandbox.content.tempDirSuffix",
uuidChars);
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;
}
}
// Get (and clean up if still there) the low integrity Mozilla temp directory.
nsCOMPtr<nsIFile> lowIntegrityTemp = GetAndCleanLowIntegrityTemp(tempDirSuffix);
if (!lowIntegrityTemp) {
NS_WARNING("Failed to get or clean low integrity Mozilla temp directory.");
return;
}
rv = lowIntegrityTemp->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
}
static void
CleanUpSandboxEnvironment()
{
// We can't have created a low integrity temp before Vista.
if (!IsVistaOrLater()) {
return;
}
// Get temp directory suffix pref.
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
return;
}
// Get and remove the low integrity Mozilla temp directory.
// This function already warns if the deletion fails.
unused << GetAndCleanLowIntegrityTemp(tempDirSuffix);
}
#endif
bool gSafeMode = false;
/**
@ -4081,6 +4195,10 @@ XREMain::XRE_mainRun()
}
#endif /* MOZ_INSTRUMENT_EVENT_LOOP */
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
SetUpSandboxEnvironment();
#endif
{
rv = appStartup->Run();
if (NS_FAILED(rv)) {
@ -4089,6 +4207,10 @@ XREMain::XRE_mainRun()
}
}
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
CleanUpSandboxEnvironment();
#endif
return rv;
}

Просмотреть файл

@ -24,10 +24,6 @@
#include <shlobj.h>
#include <stdlib.h>
#include <stdio.h>
#if defined(MOZ_CONTENT_SANDBOX)
#include "nsIUUIDGenerator.h"
#endif
#elif defined(XP_UNIX)
#include <unistd.h>
#include <stdlib.h>
@ -502,7 +498,7 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv)
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN)
static nsresult
GetLowIntegrityTemp(nsIFile** aLowIntegrityTemp)
GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase)
{
nsCOMPtr<nsIFile> localFile;
nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow,
@ -511,37 +507,12 @@ GetLowIntegrityTemp(nsIFile** aLowIntegrityTemp)
return rv;
}
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsID uuid;
rv = uuidgen->GenerateUUIDInPlace(&uuid);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
char uuidChars[NSID_LENGTH];
uuid.ToProvidedString(uuidChars);
rv = localFile->AppendNative(NS_LITERAL_CSTRING(MOZ_USER_DIR));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = localFile->AppendNative(NS_LITERAL_CSTRING("MozTemp-")
+ nsDependentCString(uuidChars));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
localFile.forget(aLowIntegrityTemp);
localFile.forget(aLowIntegrityTempBase);
return rv;
}
#endif
@ -722,8 +693,8 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
#if defined(MOZ_CONTENT_SANDBOX)
} else if (inAtom == nsDirectoryService::sLocalAppdataLow) {
rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, getter_AddRefs(localFile));
} else if (inAtom == nsDirectoryService::sLowIntegrityTemp) {
rv = GetLowIntegrityTemp(getter_AddRefs(localFile));
} else if (inAtom == nsDirectoryService::sLowIntegrityTempBase) {
rv = GetLowIntegrityTempBase(getter_AddRefs(localFile));
#endif
} else if (inAtom == nsDirectoryService::sPrinthood) {
rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile));

Просмотреть файл

@ -74,7 +74,7 @@ DIR_ATOM(sAppdata, NS_WIN_APPDATA_DIR)
DIR_ATOM(sLocalAppdata, NS_WIN_LOCAL_APPDATA_DIR)
#if defined(MOZ_CONTENT_SANDBOX)
DIR_ATOM(sLocalAppdataLow, NS_WIN_LOCAL_APPDATA_LOW_DIR)
DIR_ATOM(sLowIntegrityTemp, NS_WIN_LOW_INTEGRITY_TEMP)
DIR_ATOM(sLowIntegrityTempBase, NS_WIN_LOW_INTEGRITY_TEMP_BASE)
#endif
DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD)
DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR)

Просмотреть файл

@ -131,7 +131,7 @@
#define NS_WIN_LOCAL_APPDATA_DIR "LocalAppData"
#if defined(MOZ_CONTENT_SANDBOX)
#define NS_WIN_LOCAL_APPDATA_LOW_DIR "LocalAppDataLow"
#define NS_WIN_LOW_INTEGRITY_TEMP "LowTmpD"
#define NS_WIN_LOW_INTEGRITY_TEMP_BASE "LowTmpDBase"
#endif
#define NS_WIN_PRINTHOOD "PrntHd"
#define NS_WIN_COOKIES_DIR "CookD"