1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_UntrustedModulesProcessor_h
8 #define mozilla_UntrustedModulesProcessor_h
10 #include "mozilla/Atomics.h"
11 #include "mozilla/DebugOnly.h"
12 #include "mozilla/glue/WindowsDllServices.h"
13 #include "mozilla/LazyIdleThread.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/MozPromise.h"
16 #include "mozilla/RefPtr.h"
17 #include "mozilla/UntrustedModulesData.h"
18 #include "mozilla/Vector.h"
19 #include "mozilla/WinHeaderOnlyUtils.h"
21 #include "nsIObserver.h"
22 #include "nsIRunnable.h"
23 #include "nsISupportsImpl.h"
28 class ModuleEvaluator
;
30 using UntrustedModulesPromise
=
31 MozPromise
<Maybe
<UntrustedModulesData
>, nsresult
, true>;
33 using ModulesTrustPromise
= MozPromise
<ModulesMapResult
, nsresult
, true>;
35 using GetModulesTrustIpcPromise
=
36 MozPromise
<Maybe
<ModulesMapResult
>, ipc::ResponseRejectReason
, true>;
38 struct UnprocessedModuleLoadInfoContainer final
39 : public LinkedListElement
<UnprocessedModuleLoadInfoContainer
> {
40 glue::EnhancedModuleLoadInfo mInfo
;
43 explicit UnprocessedModuleLoadInfoContainer(T
&& aInfo
)
44 : mInfo(std::move(aInfo
)) {}
46 UnprocessedModuleLoadInfoContainer(
47 const UnprocessedModuleLoadInfoContainer
&) = delete;
48 UnprocessedModuleLoadInfoContainer
& operator=(
49 const UnprocessedModuleLoadInfoContainer
&) = delete;
51 using UnprocessedModuleLoads
=
52 AutoCleanLinkedList
<UnprocessedModuleLoadInfoContainer
>;
54 class UntrustedModulesProcessor final
: public nsIObserver
,
55 public nsIThreadPoolListener
{
57 static RefPtr
<UntrustedModulesProcessor
> Create(
58 bool aIsReadyForBackgroundProcessing
);
60 NS_DECL_THREADSAFE_ISUPPORTS
62 NS_DECL_NSITHREADPOOLLISTENER
64 // Called to check if the parent process is ready when a child process
66 bool IsReadyForBackgroundProcessing() const;
68 // Called by DLL Services to explicitly begin shutting down
71 // Called by DLL Services to submit module load data to the processor
72 void Enqueue(glue::EnhancedModuleLoadInfo
&& aModLoadInfo
);
73 void Enqueue(ModuleLoadInfoVec
&& aEvents
);
75 // Called by telemetry to retrieve the processed data
76 RefPtr
<UntrustedModulesPromise
> GetProcessedData();
78 // Called by IPC actors in the parent process to evaluate module trust
79 // on behalf of child processes
80 RefPtr
<ModulesTrustPromise
> GetModulesTrust(ModulePaths
&& aModPaths
,
81 bool aRunAtNormalPriority
);
83 UntrustedModulesProcessor(const UntrustedModulesProcessor
&) = delete;
84 UntrustedModulesProcessor(UntrustedModulesProcessor
&&) = delete;
85 UntrustedModulesProcessor
& operator=(const UntrustedModulesProcessor
&) =
87 UntrustedModulesProcessor
& operator=(UntrustedModulesProcessor
&&) = delete;
90 ~UntrustedModulesProcessor() = default;
91 explicit UntrustedModulesProcessor(bool aIsReadyForBackgroundProcessing
);
93 static bool IsSupportedProcessType();
96 void RemoveObservers();
98 void ScheduleNonEmptyQueueProcessing(const MutexAutoLock
& aProofOfLock
)
99 MOZ_REQUIRES(mUnprocessedMutex
);
100 void CancelScheduledProcessing(const MutexAutoLock
& aProofOfLock
)
101 MOZ_REQUIRES(mUnprocessedMutex
);
102 void DispatchBackgroundProcessing();
104 void BackgroundProcessModuleLoadQueue();
105 void ProcessModuleLoadQueue();
107 // Extract the loading events from mUnprocessedModuleLoads to process and
108 // move to mProcessedModuleLoads. It's guaranteed that the total length of
109 // mProcessedModuleLoads will not exceed |aMaxLength|.
110 UnprocessedModuleLoads
ExtractLoadingEventsToProcess(size_t aMaxLength
);
112 class ModulesMapResultWithLoads final
{
114 ModulesMapResultWithLoads(Maybe
<ModulesMapResult
>&& aModMapResult
,
115 UnprocessedModuleLoads
&& aLoads
)
116 : mModMapResult(std::move(aModMapResult
)), mLoads(std::move(aLoads
)) {}
117 Maybe
<ModulesMapResult
> mModMapResult
;
118 UnprocessedModuleLoads mLoads
;
121 using GetModulesTrustPromise
=
122 MozPromise
<Maybe
<ModulesMapResultWithLoads
>, nsresult
, true>;
124 enum class Priority
{ Default
, Background
};
126 RefPtr
<GetModulesTrustPromise
> ProcessModuleLoadQueueChildProcess(
128 void BackgroundProcessModuleLoadQueueChildProcess();
130 void AssertRunningOnLazyIdleThread();
132 RefPtr
<UntrustedModulesPromise
> GetProcessedDataInternal();
133 RefPtr
<UntrustedModulesPromise
> GetProcessedDataInternalChildProcess();
135 RefPtr
<ModulesTrustPromise
> GetModulesTrustInternal(
136 ModulePaths
&& aModPaths
, bool aRunAtNormalPriority
);
137 RefPtr
<ModulesTrustPromise
> GetModulesTrustInternal(ModulePaths
&& aModPaths
);
139 // This function is only called by the parent process
140 RefPtr
<ModuleRecord
> GetOrAddModuleRecord(const ModuleEvaluator
& aModEval
,
141 const nsAString
& aResolvedNtPath
);
143 // Only called by child processes
144 RefPtr
<ModuleRecord
> GetModuleRecord(
145 const ModulesMap
& aModules
,
146 const glue::EnhancedModuleLoadInfo
& aModuleLoadInfo
);
148 RefPtr
<GetModulesTrustIpcPromise
> SendGetModulesTrust(ModulePaths
&& aModules
,
151 void CompleteProcessing(ModulesMapResultWithLoads
&& aModulesAndLoads
);
152 RefPtr
<UntrustedModulesPromise
> GetAllProcessedData(const char* aSource
);
155 RefPtr
<LazyIdleThread
> mThread
;
157 Mutex mThreadHandleMutex
;
158 Mutex mUnprocessedMutex
;
159 Mutex mModuleCacheMutex
;
161 // Windows HANDLE for the currently active mThread, if active.
162 nsAutoHandle mThreadHandle
MOZ_GUARDED_BY(mThreadHandleMutex
);
164 // The members in this group are protected by mUnprocessedMutex
165 UnprocessedModuleLoads mUnprocessedModuleLoads
166 MOZ_GUARDED_BY(mUnprocessedMutex
);
167 nsCOMPtr
<nsIRunnable
> mIdleRunnable
MOZ_GUARDED_BY(mUnprocessedMutex
);
169 // This member must only be touched on mThread
170 UntrustedModulesData mProcessedModuleLoads
;
172 enum class Status
{ StartingUp
, Allowed
, ShuttingDown
};
174 // This member may be touched by any thread
175 Atomic
<Status
> mStatus
;
177 // Cache all module records, including ones trusted and ones loaded in
178 // child processes, in the browser process to avoid evaluating the same
179 // module multiple times
180 ModulesMap mGlobalModuleCache
MOZ_GUARDED_BY(mModuleCacheMutex
);
183 } // namespace mozilla
185 #endif // mozilla_UntrustedModulesProcessor_h