From 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:47:29 +0200 Subject: Adding upstream version 115.8.0esr. Signed-off-by: Daniel Baumann --- .../xre/dllservices/UntrustedModulesProcessor.h | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 toolkit/xre/dllservices/UntrustedModulesProcessor.h (limited to 'toolkit/xre/dllservices/UntrustedModulesProcessor.h') diff --git a/toolkit/xre/dllservices/UntrustedModulesProcessor.h b/toolkit/xre/dllservices/UntrustedModulesProcessor.h new file mode 100644 index 0000000000..b91d88961a --- /dev/null +++ b/toolkit/xre/dllservices/UntrustedModulesProcessor.h @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_UntrustedModulesProcessor_h +#define mozilla_UntrustedModulesProcessor_h + +#include "mozilla/Atomics.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/glue/WindowsDllServices.h" +#include "mozilla/LazyIdleThread.h" +#include "mozilla/Maybe.h" +#include "mozilla/MozPromise.h" +#include "mozilla/RefPtr.h" +#include "mozilla/UntrustedModulesData.h" +#include "mozilla/Vector.h" +#include "mozilla/WinHeaderOnlyUtils.h" +#include "nsCOMPtr.h" +#include "nsIObserver.h" +#include "nsIRunnable.h" +#include "nsISupportsImpl.h" +#include "nsString.h" + +namespace mozilla { + +class ModuleEvaluator; + +using UntrustedModulesPromise = + MozPromise, nsresult, true>; + +using ModulesTrustPromise = MozPromise; + +using GetModulesTrustIpcPromise = + MozPromise, ipc::ResponseRejectReason, true>; + +struct UnprocessedModuleLoadInfoContainer final + : public LinkedListElement { + glue::EnhancedModuleLoadInfo mInfo; + + template + explicit UnprocessedModuleLoadInfoContainer(T&& aInfo) + : mInfo(std::move(aInfo)) {} + + UnprocessedModuleLoadInfoContainer( + const UnprocessedModuleLoadInfoContainer&) = delete; + UnprocessedModuleLoadInfoContainer& operator=( + const UnprocessedModuleLoadInfoContainer&) = delete; +}; +using UnprocessedModuleLoads = + AutoCleanLinkedList; + +class UntrustedModulesProcessor final : public nsIObserver, + public nsIThreadPoolListener { + public: + static RefPtr Create( + bool aIsReadyForBackgroundProcessing); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + NS_DECL_NSITHREADPOOLLISTENER + + // Called to check if the parent process is ready when a child process + // is spanwed + bool IsReadyForBackgroundProcessing() const; + + // Called by DLL Services to explicitly begin shutting down + void Disable(); + + // Called by DLL Services to submit module load data to the processor + void Enqueue(glue::EnhancedModuleLoadInfo&& aModLoadInfo); + void Enqueue(ModuleLoadInfoVec&& aEvents); + + // Called by telemetry to retrieve the processed data + RefPtr GetProcessedData(); + + // Called by IPC actors in the parent process to evaluate module trust + // on behalf of child processes + RefPtr GetModulesTrust(ModulePaths&& aModPaths, + bool aRunAtNormalPriority); + + UntrustedModulesProcessor(const UntrustedModulesProcessor&) = delete; + UntrustedModulesProcessor(UntrustedModulesProcessor&&) = delete; + UntrustedModulesProcessor& operator=(const UntrustedModulesProcessor&) = + delete; + UntrustedModulesProcessor& operator=(UntrustedModulesProcessor&&) = delete; + + private: + ~UntrustedModulesProcessor() = default; + explicit UntrustedModulesProcessor(bool aIsReadyForBackgroundProcessing); + + static bool IsSupportedProcessType(); + + void AddObservers(); + void RemoveObservers(); + + void ScheduleNonEmptyQueueProcessing(const MutexAutoLock& aProofOfLock) + MOZ_REQUIRES(mUnprocessedMutex); + void CancelScheduledProcessing(const MutexAutoLock& aProofOfLock) + MOZ_REQUIRES(mUnprocessedMutex); + void DispatchBackgroundProcessing(); + + void BackgroundProcessModuleLoadQueue(); + void ProcessModuleLoadQueue(); + + // Extract the loading events from mUnprocessedModuleLoads to process and + // move to mProcessedModuleLoads. It's guaranteed that the total length of + // mProcessedModuleLoads will not exceed |aMaxLength|. + UnprocessedModuleLoads ExtractLoadingEventsToProcess(size_t aMaxLength); + + class ModulesMapResultWithLoads final { + public: + ModulesMapResultWithLoads(Maybe&& aModMapResult, + UnprocessedModuleLoads&& aLoads) + : mModMapResult(std::move(aModMapResult)), mLoads(std::move(aLoads)) {} + Maybe mModMapResult; + UnprocessedModuleLoads mLoads; + }; + + using GetModulesTrustPromise = + MozPromise, nsresult, true>; + + enum class Priority { Default, Background }; + + RefPtr ProcessModuleLoadQueueChildProcess( + Priority aPriority); + void BackgroundProcessModuleLoadQueueChildProcess(); + + void AssertRunningOnLazyIdleThread(); + + RefPtr GetProcessedDataInternal(); + RefPtr GetProcessedDataInternalChildProcess(); + + RefPtr GetModulesTrustInternal( + ModulePaths&& aModPaths, bool aRunAtNormalPriority); + RefPtr GetModulesTrustInternal(ModulePaths&& aModPaths); + + // This function is only called by the parent process + RefPtr GetOrAddModuleRecord(const ModuleEvaluator& aModEval, + const nsAString& aResolvedNtPath); + + // Only called by child processes + RefPtr GetModuleRecord( + const ModulesMap& aModules, + const glue::EnhancedModuleLoadInfo& aModuleLoadInfo); + + RefPtr SendGetModulesTrust(ModulePaths&& aModules, + Priority aPriority); + + void CompleteProcessing(ModulesMapResultWithLoads&& aModulesAndLoads); + RefPtr GetAllProcessedData(const char* aSource); + + private: + RefPtr mThread; + + Mutex mThreadHandleMutex; + Mutex mUnprocessedMutex; + Mutex mModuleCacheMutex; + + // Windows HANDLE for the currently active mThread, if active. + nsAutoHandle mThreadHandle MOZ_GUARDED_BY(mThreadHandleMutex); + + // The members in this group are protected by mUnprocessedMutex + UnprocessedModuleLoads mUnprocessedModuleLoads + MOZ_GUARDED_BY(mUnprocessedMutex); + nsCOMPtr mIdleRunnable MOZ_GUARDED_BY(mUnprocessedMutex); + + // This member must only be touched on mThread + UntrustedModulesData mProcessedModuleLoads; + + enum class Status { StartingUp, Allowed, ShuttingDown }; + + // This member may be touched by any thread + Atomic mStatus; + + // Cache all module records, including ones trusted and ones loaded in + // child processes, in the browser process to avoid evaluating the same + // module multiple times + ModulesMap mGlobalModuleCache MOZ_GUARDED_BY(mModuleCacheMutex); +}; + +} // namespace mozilla + +#endif // mozilla_UntrustedModulesProcessor_h -- cgit v1.2.3