diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:40:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:40:47 +0000 |
commit | 46db793222dee55d0b846c6ba99a39e2d969c52a (patch) | |
tree | d95f8ea0fb9c9c4eb9ae55c70faa2bc02a7bcea4 /security/sandbox | |
parent | Adding upstream version 115.9.1esr. (diff) | |
download | firefox-esr-46db793222dee55d0b846c6ba99a39e2d969c52a.tar.xz firefox-esr-46db793222dee55d0b846c6ba99a39e2d969c52a.zip |
Adding upstream version 115.10.0esr.upstream/115.10.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/sandbox')
-rw-r--r-- | security/sandbox/linux/SandboxInfo.cpp | 26 | ||||
-rw-r--r-- | security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp | 82 | ||||
-rw-r--r-- | security/sandbox/win/src/sandboxbroker/sandboxBroker.h | 3 |
3 files changed, 59 insertions, 52 deletions
diff --git a/security/sandbox/linux/SandboxInfo.cpp b/security/sandbox/linux/SandboxInfo.cpp index 3d71e55921..aefd9dac2d 100644 --- a/security/sandbox/linux/SandboxInfo.cpp +++ b/security/sandbox/linux/SandboxInfo.cpp @@ -134,11 +134,21 @@ static bool CanCreateUserNamespace() { // the new capabilities (in this case, cloning another namespace) to // detect AppArmor policies that allow CLONE_NEWUSER but don't allow // doing anything useful with it. - pid_t pid = syscall(__NR_clone, SIGCHLD | CLONE_NEWUSER | CLONE_NEWPID, - nullptr, nullptr, nullptr, nullptr); + // + // Bug 1884347: There's a new AppArmor feature which can result in + // unsharing NEWUSER and NEWPID (or NEWNET etc.) in one syscall + // being allowed, but further use of capabilities will be blocked + // afterwards. That may be a bug, but we need to handle it. + pid_t pid = syscall(__NR_clone, SIGCHLD | CLONE_NEWUSER, nullptr, nullptr, + nullptr, nullptr); if (pid == 0) { - // In the child. Do as little as possible. - _exit(0); + // The exact meaning of `unshare(CLONE_NEWPID)` is slightly + // counterintuitive but in this case it doesn't matter. This just + // needs to be some operation that attempts to use capabilities, + // to check if it's blocked by an LSM. + int rv = unshare(CLONE_NEWPID); + // Exit with status 0 on success, 1 on failure. + _exit(rv == 0 ? 0 : 1); } if (pid == -1) { // Failure. @@ -149,11 +159,17 @@ static bool CanCreateUserNamespace() { return false; } // Otherwise, in the parent and successful. - bool waitpid_ok = HANDLE_EINTR(waitpid(pid, nullptr, 0)) == pid; + int wstatus; + bool waitpid_ok = HANDLE_EINTR(waitpid(pid, &wstatus, 0)) == pid; MOZ_ASSERT(waitpid_ok); if (!waitpid_ok) { return false; } + // Check for failures reported by the child process. + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) { + setenv(kCacheEnvName, "0", 1); + return false; + } setenv(kCacheEnvName, "1", 1); return true; } diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp index bd154d3c78..818c160fed 100644 --- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp +++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp @@ -25,11 +25,11 @@ #include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_security.h" #include "mozilla/StaticPrefs_widget.h" +#include "mozilla/StaticPtr.h" #include "mozilla/UniquePtr.h" #include "mozilla/Telemetry.h" #include "mozilla/WinDllServices.h" #include "mozilla/WindowsVersion.h" -#include "mozilla/WinHeaderOnlyUtils.h" #include "mozilla/ipc/LaunchError.h" #include "nsAppDirectoryServiceDefs.h" #include "nsCOMPtr.h" @@ -59,11 +59,11 @@ sandbox::BrokerServices* sBrokerService = nullptr; bool SandboxBroker::sRunningFromNetworkDrive = false; // Cached special directories used for adding policy rules. -static UniquePtr<nsString> sBinDir; -static UniquePtr<nsString> sProfileDir; -static UniquePtr<nsString> sLocalAppDataDir; +static StaticAutoPtr<nsString> sBinDir; +static StaticAutoPtr<nsString> sProfileDir; +static StaticAutoPtr<nsString> sLocalAppDataDir; #ifdef ENABLE_SYSTEM_EXTENSION_DIRS -static UniquePtr<nsString> sUserExtensionsDir; +static StaticAutoPtr<nsString> sUserExtensionsDir; #endif static LazyLogModule sSandboxBrokerLog("SandboxBroker"); @@ -74,7 +74,7 @@ static LazyLogModule sSandboxBrokerLog("SandboxBroker"); // Used to store whether we have accumulated an error combination for this // session. -static UniquePtr<nsTHashtable<nsCStringHashKey>> sLaunchErrors; +static StaticAutoPtr<nsTHashtable<nsCStringHashKey>> sLaunchErrors; // This helper function is our version of SandboxWin::AddWin32kLockdownPolicy // of Chromium, making sure the MITIGATION_WIN32K_DISABLE flag is set before @@ -115,15 +115,31 @@ static sandbox::ResultCode AddWin32kLockdownPolicy( 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 */ -void SandboxBroker::Initialize(sandbox::BrokerServices* aBrokerServices) { +void SandboxBroker::Initialize(sandbox::BrokerServices* aBrokerServices, + const nsAString& aBinDir) { sBrokerService = aBrokerServices; sRunningFromNetworkDrive = widget::WinUtils::RunningFromANetworkDrive(); + + if (!aBinDir.IsEmpty()) { + CacheDirAndAutoClear(aBinDir, &sBinDir); + } } static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey, - UniquePtr<nsString>* cacheVar) { + StaticAutoPtr<nsString>* cacheVar) { nsCOMPtr<nsIFile> dirToCache; nsresult rv = aDirSvc->Get(aDirKey, NS_GET_IID(nsIFile), getter_AddRefs(dirToCache)); @@ -134,14 +150,9 @@ static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey, return; } - *cacheVar = MakeUnique<nsString>(); - ClearOnShutdown(cacheVar); - MOZ_ALWAYS_SUCCEEDS(dirToCache->GetPath(**cacheVar)); - - // Convert network share path to format for sandbox policy. - if (Substring(**cacheVar, 0, 2).Equals(u"\\\\"_ns)) { - (*cacheVar)->InsertLiteral(u"??\\UNC", 1); - } + nsAutoString dirPath; + MOZ_ALWAYS_SUCCEEDS(dirToCache->GetPath(dirPath)); + CacheDirAndAutoClear(dirPath, cacheVar); } /* static */ @@ -165,7 +176,6 @@ void SandboxBroker::GeckoDependentInitialize() { return; } - CacheDirAndAutoClear(dirSvc, NS_GRE_DIR, &sBinDir); CacheDirAndAutoClear(dirSvc, NS_APP_USER_PROFILE_50_DIR, &sProfileDir); CacheDirAndAutoClear(dirSvc, NS_WIN_LOCAL_APPDATA_DIR, &sLocalAppDataDir); #ifdef ENABLE_SYSTEM_EXTENSION_DIRS @@ -176,7 +186,7 @@ void SandboxBroker::GeckoDependentInitialize() { // Create sLaunchErrors up front because ClearOnShutdown must be called on the // main thread. - sLaunchErrors = MakeUnique<nsTHashtable<nsCStringHashKey>>(); + sLaunchErrors = new nsTHashtable<nsCStringHashKey>(); ClearOnShutdown(&sLaunchErrors); } @@ -412,7 +422,7 @@ Result<Ok, mozilla::ipc::LaunchError> SandboxBroker::LaunchApp( static void AddCachedDirRule(sandbox::TargetPolicy* aPolicy, sandbox::TargetPolicy::Semantics aAccess, - const UniquePtr<nsString>& aBaseDir, + const StaticAutoPtr<nsString>& aBaseDir, const nsLiteralString& aRelativePath) { if (!aBaseDir) { // This can only be an NS_WARNING, because it can null for xpcshell tests. @@ -486,35 +496,11 @@ static sandbox::ResultCode AllowProxyLoadFromBinDir( sandbox::TargetPolicy* aPolicy) { // Allow modules in the directory containing the executable such as // mozglue.dll, nss3.dll, etc. - static UniquePtr<nsString> sInstallDir; - if (!sInstallDir) { - // 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( - TaskCategory::Other, - NS_NewRunnableFunction("InitSignedPolicyRulesToBypassCig", - std::move(setClearOnShutdown))); - } - } - - if (!sInstallDir) { - return sandbox::SBOX_ERROR_GENERIC; - } - } + nsAutoString rulePath(*sBinDir); + rulePath.Append(u"\\*"_ns); return aPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_SIGNED_BINARY, sandbox::TargetPolicy::SIGNED_ALLOW_LOAD, - sInstallDir->get()); + rulePath.get()); } static sandbox::ResultCode AddCigToPolicy( @@ -1219,6 +1205,10 @@ void SandboxBroker::SetSecurityLevelForGPUProcess(int32_t aSandboxLevel) { sandbox::SBOX_ALL_OK == result, "With these static arguments AddRule should never fail, what happened?"); + // 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 if (sProfileDir) { AddCachedDirRule(mPolicy, sandbox::TargetPolicy::FILES_ALLOW_DIR_ANY, diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h index 752fbaa9aa..462e4b4b52 100644 --- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h +++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h @@ -76,7 +76,8 @@ class SandboxBroker : public AbstractSandboxBroker { public: SandboxBroker(); - static void Initialize(sandbox::BrokerServices* aBrokerServices); + static void Initialize(sandbox::BrokerServices* aBrokerServices, + const nsAString& aBinDir); void Shutdown() override {} |