diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 0e1eaaf47fcc..4b00abe6807c 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -323,6 +323,78 @@ GeckoChildProcessHost::GetUniqueID() return sNextUniqueID++; } +#if defined(XP_WIN) && defined(MOZ_SANDBOX) + +// This is pretty much a duplicate of the function in PluginProcessParent. +// Simply copying for now due to uplift. I will address this duplication and for +// example the similar code in the Constructor in bug 1339105. +static void +AddSandboxAllowedFile(std::vector& aAllowedFiles, + nsIProperties* aDirSvc, const char* aDirKey, + const nsAString& aSuffix = EmptyString()) +{ + nsCOMPtr ruleDir; + nsresult rv = + aDirSvc->Get(aDirKey, NS_GET_IID(nsIFile), getter_AddRefs(ruleDir)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsAutoString rulePath; + rv = ruleDir->GetPath(rulePath); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + // Convert network share path to format for sandbox policy. + if (Substring(rulePath, 0, 2).Equals(L"\\\\")) { + rulePath.InsertLiteral(u"??\\UNC", 1); + } + + if (!aSuffix.IsEmpty()) { + rulePath.Append(aSuffix); + } + + aAllowedFiles.push_back(std::wstring(rulePath.get())); + return; +} + +static void +AddContentSandboxAllowedFiles(int32_t aSandboxLevel, + std::vector& aAllowedFilesRead, + std::vector& aAllowedFilesReadWrite) +{ + if (aSandboxLevel < 1) { + return; + } + + nsresult rv; + nsCOMPtr dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + // Add rule to allow read / write access to content temp dir. If for some + // reason the addition of the content temp failed, this will give write access + // to the normal TEMP dir. However such failures should be pretty rare and + // without this printing will not currently work. + AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, + NS_APP_CONTENT_PROCESS_TEMP_DIR, + NS_LITERAL_STRING("\\*")); + + if (aSandboxLevel < 2) { + return; + } + + // Add rule to allow read access to installation directory. At less than + // level 2 we already add a global read rule. + AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_GRE_DIR, + NS_LITERAL_STRING("\\*")); +} + +#endif + void GeckoChildProcessHost::PrepareLaunch() { @@ -343,6 +415,11 @@ GeckoChildProcessHost::PrepareLaunch() mSandboxLevel = Preferences::GetInt("security.sandbox.content.level"); mEnableSandboxLogging = Preferences::GetBool("security.sandbox.logging.enabled"); + + // This calls the directory service, which can also cause issues if called + // off main thread. + AddContentSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead, + mAllowedFilesReadWrite); } #endif @@ -663,50 +740,6 @@ AddAppDirToCommandLine(std::vector& aCmdLine) } } -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - -static void -AddContentSandboxAllowedFiles(int32_t aSandboxLevel, - std::vector& aAllowedFilesRead) -{ - if (aSandboxLevel < 1) { - return; - } - - nsCOMPtr binDir; - nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(binDir)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - nsAutoString binDirPath; - rv = binDir->GetPath(binDirPath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - // If bin directory is on a remote drive add read access. - wchar_t volPath[MAX_PATH]; - if (!::GetVolumePathNameW(binDirPath.get(), volPath, MAX_PATH)) { - return; - } - - if (::GetDriveTypeW(volPath) != DRIVE_REMOTE) { - return; - } - - // Convert network share path to format for sandbox policy. - if (Substring(binDirPath, 0, 2).Equals(L"\\\\")) { - binDirPath.InsertLiteral(u"??\\UNC", 1); - } - - binDirPath.AppendLiteral(u"\\*"); - - aAllowedFilesRead.push_back(std::wstring(binDirPath.get())); -} - -#endif - bool GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExtraOpts, base::ProcessArchitecture arch) { @@ -1048,7 +1081,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt mSandboxBroker.SetSecurityLevelForContentProcess(mSandboxLevel, mPrivileges); shouldSandboxCurrentProcess = true; - AddContentSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead); } #endif // MOZ_CONTENT_SANDBOX break;