Bug 1859708: Add rule to allow read access to the binary dir for GPU sandbox. r=cmartin

This also changes the way we populate the cached binary dir string, so that when
it is populated, it is done in SandboxBroker::Initialize.

Differential Revision: https://phabricator.services.mozilla.com/D205099
This commit is contained in:
Bob Owen 2024-03-19 22:09:10 +00:00
parent 23a339fc7c
commit 90e0706ca0
5 changed files with 43 additions and 40 deletions

View file

@ -1084,6 +1084,10 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
// stability, we should instantiate COM ASAP so that we can ensure that these // stability, we should instantiate COM ASAP so that we can ensure that these
// global settings are configured before anything can interfere. // global settings are configured before anything can interfere.
mscom::ProcessRuntime mscom; mscom::ProcessRuntime mscom;
# ifdef MOZ_SANDBOX
nsAutoString binDirPath;
# endif
#endif #endif
// The provider needs to outlive the call to shutting down XPCOM. // The provider needs to outlive the call to shutting down XPCOM.
@ -1103,6 +1107,11 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
return 1; return 1;
} }
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
// We need the binary directory to initialize the windows sandbox.
MOZ_ALWAYS_SUCCEEDS(appDir->GetPath(binDirPath));
#endif
dirprovider.SetAppFile(appFile); dirprovider.SetAppFile(appFile);
nsCOMPtr<nsIFile> greDir; nsCOMPtr<nsIFile> greDir;
@ -1301,7 +1310,7 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
# if defined(MOZ_SANDBOX) # if defined(MOZ_SANDBOX)
// Required for sandboxed child processes. // Required for sandboxed child processes.
if (aShellData->sandboxBrokerServices) { if (aShellData->sandboxBrokerServices) {
SandboxBroker::Initialize(aShellData->sandboxBrokerServices); SandboxBroker::Initialize(aShellData->sandboxBrokerServices, binDirPath);
SandboxBroker::GeckoDependentInitialize(); SandboxBroker::GeckoDependentInitialize();
} else { } else {
NS_WARNING( NS_WARNING(

View file

@ -30,7 +30,6 @@
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/WinDllServices.h" #include "mozilla/WinDllServices.h"
#include "mozilla/WindowsVersion.h" #include "mozilla/WindowsVersion.h"
#include "mozilla/WinHeaderOnlyUtils.h"
#include "mozilla/ipc/LaunchError.h" #include "mozilla/ipc/LaunchError.h"
#include "nsAppDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -116,11 +115,27 @@ static sandbox::ResultCode AddWin32kLockdownPolicy(
return result; return result;
} }
static void CacheDirAndAutoClear(const nsAString& aDir,
StaticAutoPtr<nsString>* cacheVar) {
*cacheVar = new nsString(aDir);
ClearOnShutdown(cacheVar);
// Convert network share path to format for sandbox policy.
if (Substring(**cacheVar, 0, 2).Equals(u"\\\\"_ns)) {
(*cacheVar)->InsertLiteral(u"??\\UNC", 1);
}
}
/* static */ /* static */
void SandboxBroker::Initialize(sandbox::BrokerServices* aBrokerServices) { void SandboxBroker::Initialize(sandbox::BrokerServices* aBrokerServices,
const nsAString& aBinDir) {
sBrokerService = aBrokerServices; sBrokerService = aBrokerServices;
sRunningFromNetworkDrive = widget::WinUtils::RunningFromANetworkDrive(); sRunningFromNetworkDrive = widget::WinUtils::RunningFromANetworkDrive();
if (!aBinDir.IsEmpty()) {
CacheDirAndAutoClear(aBinDir, &sBinDir);
}
} }
static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey, static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey,
@ -135,14 +150,9 @@ static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey,
return; return;
} }
*cacheVar = new nsString(); nsAutoString dirPath;
ClearOnShutdown(cacheVar); MOZ_ALWAYS_SUCCEEDS(dirToCache->GetPath(dirPath));
MOZ_ALWAYS_SUCCEEDS(dirToCache->GetPath(**cacheVar)); CacheDirAndAutoClear(dirPath, cacheVar);
// Convert network share path to format for sandbox policy.
if (Substring(**cacheVar, 0, 2).Equals(u"\\\\"_ns)) {
(*cacheVar)->InsertLiteral(u"??\\UNC", 1);
}
} }
/* static */ /* static */
@ -166,7 +176,6 @@ void SandboxBroker::GeckoDependentInitialize() {
return; return;
} }
CacheDirAndAutoClear(dirSvc, NS_GRE_DIR, &sBinDir);
CacheDirAndAutoClear(dirSvc, NS_APP_USER_PROFILE_50_DIR, &sProfileDir); CacheDirAndAutoClear(dirSvc, NS_APP_USER_PROFILE_50_DIR, &sProfileDir);
CacheDirAndAutoClear(dirSvc, NS_WIN_LOCAL_APPDATA_DIR, &sLocalAppDataDir); CacheDirAndAutoClear(dirSvc, NS_WIN_LOCAL_APPDATA_DIR, &sLocalAppDataDir);
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS #ifdef ENABLE_SYSTEM_EXTENSION_DIRS
@ -481,33 +490,11 @@ static sandbox::ResultCode AllowProxyLoadFromBinDir(
sandbox::TargetPolicy* aPolicy) { sandbox::TargetPolicy* aPolicy) {
// Allow modules in the directory containing the executable such as // Allow modules in the directory containing the executable such as
// mozglue.dll, nss3.dll, etc. // mozglue.dll, nss3.dll, etc.
static UniquePtr<nsString> sInstallDir; nsAutoString rulePath(*sBinDir);
if (!sInstallDir) { rulePath.Append(u"\\*"_ns);
// Since this function can be called before sBinDir is initialized,
// we cache the install path by ourselves.
UniquePtr<wchar_t[]> appDirStr;
if (GetInstallDirectory(appDirStr)) {
sInstallDir = MakeUnique<nsString>(appDirStr.get());
sInstallDir->Append(u"\\*");
auto setClearOnShutdown = [ptr = &sInstallDir]() -> void {
ClearOnShutdown(ptr);
};
if (NS_IsMainThread()) {
setClearOnShutdown();
} else {
SchedulerGroup::Dispatch(NS_NewRunnableFunction(
"InitSignedPolicyRulesToBypassCig", std::move(setClearOnShutdown)));
}
}
if (!sInstallDir) {
return sandbox::SBOX_ERROR_GENERIC;
}
}
return aPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_SIGNED_BINARY, return aPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_SIGNED_BINARY,
sandbox::TargetPolicy::SIGNED_ALLOW_LOAD, sandbox::TargetPolicy::SIGNED_ALLOW_LOAD,
sInstallDir->get()); rulePath.get());
} }
static sandbox::ResultCode AddCigToPolicy( static sandbox::ResultCode AddCigToPolicy(
@ -1084,6 +1071,10 @@ void SandboxBroker::SetSecurityLevelForGPUProcess(int32_t aSandboxLevel) {
sandbox::TargetPolicy::FILES_ALLOW_ANY, sandbox::TargetPolicy::FILES_ALLOW_ANY,
L"\\??\\pipe\\gecko-crash-server-pipe.*")); L"\\??\\pipe\\gecko-crash-server-pipe.*"));
// Add rule to allow read access to installation directory.
AddCachedDirRule(mPolicy, sandbox::TargetPolicy::FILES_ALLOW_READONLY,
sBinDir, u"\\*"_ns);
// The GPU process needs to write to a shader cache for performance reasons // The GPU process needs to write to a shader cache for performance reasons
if (sProfileDir) { if (sProfileDir) {
AddCachedDirRule(mPolicy, sandbox::TargetPolicy::FILES_ALLOW_DIR_ANY, AddCachedDirRule(mPolicy, sandbox::TargetPolicy::FILES_ALLOW_DIR_ANY,

View file

@ -75,7 +75,8 @@ class SandboxBroker : public AbstractSandboxBroker {
public: public:
SandboxBroker(); SandboxBroker();
static void Initialize(sandbox::BrokerServices* aBrokerServices); static void Initialize(sandbox::BrokerServices* aBrokerServices,
const nsAString& aBinDir);
static void EnsureLpacPermsissionsOnDir(const nsString& aDir); static void EnsureLpacPermsissionsOnDir(const nsString& aDir);

View file

@ -4224,7 +4224,9 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
#if defined(MOZ_SANDBOX) && defined(XP_WIN) #if defined(MOZ_SANDBOX) && defined(XP_WIN)
if (mAppData->sandboxBrokerServices) { if (mAppData->sandboxBrokerServices) {
SandboxBroker::Initialize(mAppData->sandboxBrokerServices); nsAutoString binDirPath;
MOZ_ALWAYS_SUCCEEDS(xreBinDirectory->GetPath(binDirPath));
SandboxBroker::Initialize(mAppData->sandboxBrokerServices, binDirPath);
} else { } else {
# if defined(MOZ_SANDBOX) # if defined(MOZ_SANDBOX)
// If we're sandboxing content and we fail to initialize, then crashing here // If we're sandboxing content and we fail to initialize, then crashing here

View file

@ -525,7 +525,7 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
#if defined(XP_WIN) #if defined(XP_WIN)
# if defined(MOZ_SANDBOX) # if defined(MOZ_SANDBOX)
if (aChildData->sandboxBrokerServices) { if (aChildData->sandboxBrokerServices) {
SandboxBroker::Initialize(aChildData->sandboxBrokerServices); SandboxBroker::Initialize(aChildData->sandboxBrokerServices, u""_ns);
SandboxBroker::GeckoDependentInitialize(); SandboxBroker::GeckoDependentInitialize();
} }
# endif // defined(MOZ_SANDBOX) # endif // defined(MOZ_SANDBOX)