Bug 1018988 - Set up a low integrity temp directory when using the Windows content sandbox. r=mrbkap r=tabraldes r=froydnj

This commit is contained in:
Bob Owen 2014-09-10 12:36:17 +01:00
parent 4826726907
commit 087dd2458b
9 changed files with 151 additions and 5 deletions

View File

@ -43,6 +43,7 @@
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
#include "mozilla/sandboxTarget.h"
#include "nsDirectoryServiceDefs.h"
#elif defined(XP_LINUX)
#include "mozilla/Sandbox.h"
#endif
@ -923,6 +924,69 @@ ContentChild::AllocPBackgroundChild(Transport* aTransport,
return BackgroundChild::Alloc(aTransport, aOtherProcess);
}
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static void
SetUpSandboxEnvironment()
{
// Set up a low integrity temp directory. This only makes sense if the
// delayed integrity level for the content process is INTEGRITY_LEVEL_LOW.
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsIFile> lowIntegrityTemp;
rv = directoryService->Get(NS_WIN_LOW_INTEGRITY_TEMP, NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Undefine returns a failure if the property is not already set.
unused << directoryService->Undefine(NS_OS_TEMP_DIR);
rv = directoryService->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");
}
void
ContentChild::CleanUpSandboxEnvironment()
{
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsIFile> lowIntegrityTemp;
rv = directoryService->Get(NS_WIN_LOW_INTEGRITY_TEMP, NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
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
bool
ContentChild::RecvSetProcessSandbox()
{
@ -947,6 +1011,7 @@ ContentChild::RecvSetProcessSandbox()
if (contentSandboxPref.EqualsLiteral("on")
|| contentSandboxPref.EqualsLiteral("warn")) {
mozilla::SandboxTarget::Instance()->StartSandbox();
SetUpSandboxEnvironment();
}
#endif
#endif

View File

@ -118,6 +118,11 @@ public:
AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
// Cleans up any resources used by the process when sandboxed.
void CleanUpSandboxEnvironment();
#endif
virtual bool RecvSetProcessSandbox() MOZ_OVERRIDE;
PBackgroundChild*

View File

@ -34,6 +34,9 @@ ContentProcess::Init()
void
ContentProcess::CleanUp()
{
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
mContent.CleanUpSandboxEnvironment();
#endif
mXREEmbed.Stop();
}

View File

@ -73,13 +73,16 @@ SandboxBroker::SetSecurityLevelForContentProcess(bool inWarnOnlyMode)
auto result = mPolicy->SetJobLevel(sandbox::JOB_NONE, 0);
bool ret = (sandbox::SBOX_ALL_OK == result);
result =
mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_RESTRICTED_SAME_ACCESS);
result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_RESTRICTED_SAME_ACCESS);
ret = ret && (sandbox::SBOX_ALL_OK == result);
result =
mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
// If the delayed integrity level is changed then SetUpSandboxEnvironment and
// CleanUpSandboxEnvironment in ContentChild should be changed or removed.
result = mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
ret = ret && (sandbox::SBOX_ALL_OK == result);
result = mPolicy->SetAlternateDesktop(true);
ret = ret && (sandbox::SBOX_ALL_OK == result);

View File

@ -751,6 +751,14 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
}
return rv;
}
#if defined(MOZ_CONTENT_SANDBOX)
case Win_LocalAppdataLow: {
// This should only really fail on versions pre-Vista, in which case this
// shouldn't have been used in the first place.
GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
return GetKnownFolder(&localAppDataLowGuid, aFile);
}
#endif
case Win_Documents: {
return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
FOLDERID_DocumentsLibrary,

View File

@ -79,6 +79,9 @@ enum SystemDirectories {
Win_Pictures = 233,
Win_Music = 234,
Win_Videos = 235,
#if defined(MOZ_CONTENT_SANDBOX)
Win_LocalAppdataLow = 236,
#endif
Unix_LocalDirectory = 301,
Unix_LibDirectory = 302,

View File

@ -24,6 +24,10 @@
#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>
@ -499,6 +503,47 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv)
return NS_OK;
}
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN)
static nsresult
GetLowIntegrityTemp(nsIFile** aLowIntegrityTemp)
{
nsCOMPtr<nsIFile> localFile;
nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow,
getter_AddRefs(localFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
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;
}
localFile.forget(aLowIntegrityTemp);
return rv;
}
#endif
// DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com.
// This is meant to be a place of xpcom or system specific file locations, not
// application specific locations. If you need the later, register a callback for
@ -671,6 +716,12 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile));
} else if (inAtom == nsDirectoryService::sLocalAppdata) {
rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile));
#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));
#endif
} else if (inAtom == nsDirectoryService::sPrinthood) {
rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile));
} else if (inAtom == nsDirectoryService::sWinCookiesDirectory) {

View File

@ -71,6 +71,10 @@ DIR_ATOM(sCommon_Desktopdirectory, NS_WIN_COMMON_DESKTOP_DIRECTORY)
DIR_ATOM(sCommon_AppData, NS_WIN_COMMON_APPDATA_DIR)
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)
#endif
DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD)
DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR)
DIR_ATOM(sDefaultDownloadDirectory, NS_WIN_DEFAULT_DOWNLOAD_DIR)

View File

@ -120,6 +120,10 @@
#define NS_WIN_COMMON_APPDATA_DIR "CmAppData"
#define NS_WIN_APPDATA_DIR "AppData"
#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"
#endif
#define NS_WIN_PRINTHOOD "PrntHd"
#define NS_WIN_COOKIES_DIR "CookD"
#define NS_WIN_DEFAULT_DOWNLOAD_DIR "DfltDwnld"