diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index cbbd8ef9fbe0..111af7153167 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -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 directoryService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsCOMPtr 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 directoryService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsCOMPtr 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 diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 6f529e7a4a80..c85ff9ab0794 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -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* diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp index bf8e190e63d1..c3037fcd1f53 100644 --- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -34,6 +34,9 @@ ContentProcess::Init() void ContentProcess::CleanUp() { +#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + mContent.CleanUpSandboxEnvironment(); +#endif mXREEmbed.Stop(); } diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp index 39ee19b9e3a6..f1c2d1843fcd 100644 --- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp +++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp @@ -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); diff --git a/xpcom/io/SpecialSystemDirectory.cpp b/xpcom/io/SpecialSystemDirectory.cpp index 939032f310ad..8bad192d9647 100644 --- a/xpcom/io/SpecialSystemDirectory.cpp +++ b/xpcom/io/SpecialSystemDirectory.cpp @@ -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, diff --git a/xpcom/io/SpecialSystemDirectory.h b/xpcom/io/SpecialSystemDirectory.h index 9142f2278ee1..dd3d88379580 100644 --- a/xpcom/io/SpecialSystemDirectory.h +++ b/xpcom/io/SpecialSystemDirectory.h @@ -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, diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index c1e231d51df5..a7c3d3222602 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -24,6 +24,10 @@ #include #include #include + +#if defined(MOZ_CONTENT_SANDBOX) +#include "nsIUUIDGenerator.h" +#endif #elif defined(XP_UNIX) #include #include @@ -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 localFile; + nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, + getter_AddRefs(localFile)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsCOMPtr 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) { diff --git a/xpcom/io/nsDirectoryServiceAtomList.h b/xpcom/io/nsDirectoryServiceAtomList.h index b6bf658631ab..d61446a525c2 100644 --- a/xpcom/io/nsDirectoryServiceAtomList.h +++ b/xpcom/io/nsDirectoryServiceAtomList.h @@ -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) diff --git a/xpcom/io/nsDirectoryServiceDefs.h b/xpcom/io/nsDirectoryServiceDefs.h index 0c4a474f08f3..d0e3df51e344 100644 --- a/xpcom/io/nsDirectoryServiceDefs.h +++ b/xpcom/io/nsDirectoryServiceDefs.h @@ -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"