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 http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_glue_WindowsDllServices_h
8 #define mozilla_glue_WindowsDllServices_h
12 #include "mozilla/Assertions.h"
13 #include "mozilla/Authenticode.h"
14 #include "mozilla/LoaderAPIInterfaces.h"
15 #include "mozilla/UniquePtr.h"
16 #include "mozilla/Vector.h"
17 #include "mozilla/WinHeaderOnlyUtils.h"
18 #include "mozilla/WindowsDllBlocklist.h"
19 #include "mozilla/mozalloc.h"
21 #if defined(MOZILLA_INTERNAL_API)
22 # include "MainThreadUtils.h"
23 # include "nsISupportsImpl.h"
24 # include "nsString.h"
25 # include "nsThreadUtils.h"
26 # include "prthread.h"
27 # include "mozilla/SchedulerGroup.h"
28 #endif // defined(MOZILLA_INTERNAL_API)
30 // For PCUNICODE_STRING
37 class DllServicesBase
: public Authenticode
{
40 * WARNING: This method is called from within an unsafe context that holds
41 * multiple locks inside the Windows loader. The only thing that
42 * this function should be used for is dispatching the event to our
43 * event loop so that it may be handled in a safe context.
45 virtual void DispatchDllLoadNotification(ModuleLoadInfo
&& aModLoadInfo
) = 0;
48 * This function accepts module load events to be processed later for
49 * the untrusted modules telemetry ping.
51 * WARNING: This method is run from within the Windows loader and should
52 * only perform trivial, loader-friendly operations.
54 virtual void DispatchModuleLoadBacklogNotification(
55 ModuleLoadInfoVec
&& aEvents
) = 0;
57 void SetAuthenticodeImpl(Authenticode
* aAuthenticode
) {
58 mAuthenticode
= aAuthenticode
;
61 void SetInitDllBlocklistOOPFnPtr(
62 nt::LoaderAPI::InitDllBlocklistOOPFnPtr aPtr
) {
63 mInitDllBlocklistOOPFnPtr
= aPtr
;
66 template <typename
... Args
>
67 LauncherVoidResultWithLineInfo
InitDllBlocklistOOP(Args
&&... aArgs
) {
68 MOZ_RELEASE_ASSERT(mInitDllBlocklistOOPFnPtr
);
69 return mInitDllBlocklistOOPFnPtr(std::forward
<Args
>(aArgs
)...);
72 // In debug builds we override GetBinaryOrgName to add a Gecko-specific
73 // assertion. OTOH, we normally do not want people overriding this function,
74 // so we'll make it final in the release case, thus covering all bases.
76 UniquePtr
<wchar_t[]> GetBinaryOrgName(
77 const wchar_t* aFilePath
,
78 AuthenticodeFlags aFlags
= AuthenticodeFlags::Default
) override
80 UniquePtr
<wchar_t[]> GetBinaryOrgName(
81 const wchar_t* aFilePath
,
82 AuthenticodeFlags aFlags
= AuthenticodeFlags::Default
) final
83 #endif // defined(DEBUG)
89 return mAuthenticode
->GetBinaryOrgName(aFilePath
, aFlags
);
92 virtual void DisableFull() { DllBlocklist_SetFullDllServices(nullptr); }
94 DllServicesBase(const DllServicesBase
&) = delete;
95 DllServicesBase(DllServicesBase
&&) = delete;
96 DllServicesBase
& operator=(const DllServicesBase
&) = delete;
97 DllServicesBase
& operator=(DllServicesBase
&&) = delete;
101 : mAuthenticode(nullptr), mInitDllBlocklistOOPFnPtr(nullptr) {}
103 virtual ~DllServicesBase() = default;
105 void EnableFull() { DllBlocklist_SetFullDllServices(this); }
106 void EnableBasic() { DllBlocklist_SetBasicDllServices(this); }
109 Authenticode
* mAuthenticode
;
110 nt::LoaderAPI::InitDllBlocklistOOPFnPtr mInitDllBlocklistOOPFnPtr
;
113 } // namespace detail
115 #if defined(MOZILLA_INTERNAL_API)
117 struct EnhancedModuleLoadInfo final
{
118 explicit EnhancedModuleLoadInfo(ModuleLoadInfo
&& aModLoadInfo
)
119 : mNtLoadInfo(std::move(aModLoadInfo
)) {
120 // Only populate mThreadName when we're on the same thread as the event
121 if (mNtLoadInfo
.mThreadId
== ::GetCurrentThreadId()) {
122 mThreadName
= PR_GetThreadName(PR_GetCurrentThread());
124 MOZ_ASSERT(!mNtLoadInfo
.mSectionName
.IsEmpty());
127 EnhancedModuleLoadInfo(EnhancedModuleLoadInfo
&&) = default;
128 EnhancedModuleLoadInfo
& operator=(EnhancedModuleLoadInfo
&&) = default;
130 EnhancedModuleLoadInfo(const EnhancedModuleLoadInfo
&) = delete;
131 EnhancedModuleLoadInfo
& operator=(const EnhancedModuleLoadInfo
&) = delete;
133 nsDependentString
GetSectionName() const {
134 return mNtLoadInfo
.mSectionName
.AsString();
137 using BacktraceType
= decltype(ModuleLoadInfo::mBacktrace
);
139 ModuleLoadInfo mNtLoadInfo
;
140 nsCString mThreadName
;
143 class DllServices
: public detail::DllServicesBase
{
145 void DispatchDllLoadNotification(ModuleLoadInfo
&& aModLoadInfo
) final
{
146 nsCOMPtr
<nsIRunnable
> runnable(
147 NewRunnableMethod
<StoreCopyPassByRRef
<EnhancedModuleLoadInfo
>>(
148 "DllServices::NotifyDllLoad", this, &DllServices::NotifyDllLoad
,
149 std::move(aModLoadInfo
)));
151 SchedulerGroup::Dispatch(TaskCategory::Other
, runnable
.forget());
154 void DispatchModuleLoadBacklogNotification(
155 ModuleLoadInfoVec
&& aEvents
) final
{
156 nsCOMPtr
<nsIRunnable
> runnable(
157 NewRunnableMethod
<StoreCopyPassByRRef
<ModuleLoadInfoVec
>>(
158 "DllServices::NotifyModuleLoadBacklog", this,
159 &DllServices::NotifyModuleLoadBacklog
, std::move(aEvents
)));
161 SchedulerGroup::Dispatch(TaskCategory::Other
, runnable
.forget());
165 UniquePtr
<wchar_t[]> GetBinaryOrgName(
166 const wchar_t* aFilePath
,
167 AuthenticodeFlags aFlags
= AuthenticodeFlags::Default
) final
{
168 // This function may perform disk I/O, so we should never call it on the
170 MOZ_ASSERT(!NS_IsMainThread());
171 return detail::DllServicesBase::GetBinaryOrgName(aFilePath
, aFlags
);
173 # endif // defined(DEBUG)
175 NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(DllServices
)
178 DllServices() = default;
179 ~DllServices() = default;
181 virtual void NotifyDllLoad(EnhancedModuleLoadInfo
&& aModLoadInfo
) = 0;
182 virtual void NotifyModuleLoadBacklog(ModuleLoadInfoVec
&& aEvents
) = 0;
187 class BasicDllServices final
: public detail::DllServicesBase
{
189 BasicDllServices() { EnableBasic(); }
191 ~BasicDllServices() = default;
193 // Not useful in this class, so provide a default implementation
194 virtual void DispatchDllLoadNotification(
195 ModuleLoadInfo
&& aModLoadInfo
) override
{}
197 virtual void DispatchModuleLoadBacklogNotification(
198 ModuleLoadInfoVec
&& aEvents
) override
{}
201 #endif // defined(MOZILLA_INTERNAL_API)
204 } // namespace mozilla
206 #endif // mozilla_glue_WindowsDllServices_h