forked from mirrors/gecko-dev
		
	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:
		
							parent
							
								
									23a339fc7c
								
							
						
					
					
						commit
						90e0706ca0
					
				
					 5 changed files with 43 additions and 40 deletions
				
			
		|  | @ -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( | ||||||
|  |  | ||||||
|  | @ -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, | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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
 | ||||||
|  |  | ||||||
|  | @ -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)
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Bob Owen
						Bob Owen