Skip to content

Commit 972b41f

Browse files
committed
Bug 1546154 p3: Explicitly load COM functions from combase.dll to prevent ole32 loading. r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D124931
1 parent 3168861 commit 972b41f

File tree

12 files changed

+185
-50
lines changed

12 files changed

+185
-50
lines changed

browser/app/winlauncher/moz.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Library("winlauncher")
99
FORCE_STATIC_LIB = True
1010

1111
UNIFIED_SOURCES += [
12+
"/ipc/mscom/COMWrappers.cpp",
1213
"/ipc/mscom/ProcessRuntime.cpp",
1314
"/toolkit/xre/WinTokenUtils.cpp",
1415
"/widget/windows/WindowsConsole.cpp",

ipc/mscom/ApartmentRegion.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
#include "mozilla/Assertions.h"
1111
#include "mozilla/Attributes.h"
12-
13-
#include <objbase.h>
12+
#include "mozilla/mscom/COMWrappers.h"
1413

1514
namespace mozilla {
1615
namespace mscom {
@@ -25,14 +24,14 @@ class MOZ_NON_TEMPORARY_CLASS ApartmentRegion final {
2524
constexpr ApartmentRegion() : mInitResult(CO_E_NOTINITIALIZED) {}
2625

2726
explicit ApartmentRegion(COINIT aAptType)
28-
: mInitResult(::CoInitializeEx(nullptr, aAptType)) {
27+
: mInitResult(wrapped::CoInitializeEx(nullptr, aAptType)) {
2928
// If this fires then we're probably mixing apartments on the same thread
3029
MOZ_ASSERT(IsValid());
3130
}
3231

3332
~ApartmentRegion() {
3433
if (IsValid()) {
35-
::CoUninitialize();
34+
wrapped::CoUninitialize();
3635
}
3736
}
3837

@@ -44,7 +43,7 @@ class MOZ_NON_TEMPORARY_CLASS ApartmentRegion final {
4443

4544
bool Init(COINIT aAptType) {
4645
MOZ_ASSERT(mInitResult == CO_E_NOTINITIALIZED);
47-
mInitResult = ::CoInitializeEx(nullptr, aAptType);
46+
mInitResult = wrapped::CoInitializeEx(nullptr, aAptType);
4847
MOZ_ASSERT(IsValid());
4948
return IsValid();
5049
}

ipc/mscom/COMWrappers.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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/. */
6+
7+
#include "mozilla/mscom/COMWrappers.h"
8+
9+
#include <objbase.h>
10+
11+
#include "mozilla/Assertions.h"
12+
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
13+
14+
namespace mozilla::mscom::wrapped {
15+
16+
HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit) {
17+
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoInitializeEx)>
18+
pCoInitializeEx(L"combase.dll", "CoInitializeEx");
19+
if (!pCoInitializeEx) {
20+
return ::CoInitializeEx(pvReserved, dwCoInit);
21+
}
22+
23+
return pCoInitializeEx(pvReserved, dwCoInit);
24+
}
25+
26+
void CoUninitialize() {
27+
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoUninitialize)>
28+
pCoUninitialize(L"combase.dll", "CoUninitialize");
29+
if (!pCoUninitialize) {
30+
return ::CoUninitialize();
31+
}
32+
33+
return pCoUninitialize();
34+
}
35+
36+
HRESULT CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie) {
37+
static const StaticDynamicallyLinkedFunctionPtr<
38+
decltype(&::CoIncrementMTAUsage)>
39+
pCoIncrementMTAUsage(L"combase.dll", "CoIncrementMTAUsage");
40+
// This API is only available beginning with Windows 8.
41+
if (!pCoIncrementMTAUsage) {
42+
return E_NOTIMPL;
43+
}
44+
45+
HRESULT hr = pCoIncrementMTAUsage(pCookie);
46+
MOZ_ASSERT(SUCCEEDED(hr));
47+
return hr;
48+
}
49+
50+
HRESULT CoGetApartmentType(APTTYPE* pAptType, APTTYPEQUALIFIER* pAptQualifier) {
51+
static const StaticDynamicallyLinkedFunctionPtr<
52+
decltype(&::CoGetApartmentType)>
53+
pCoGetApartmentType(L"combase.dll", "CoGetApartmentType");
54+
if (!pCoGetApartmentType) {
55+
return ::CoGetApartmentType(pAptType, pAptQualifier);
56+
}
57+
58+
return pCoGetApartmentType(pAptType, pAptQualifier);
59+
}
60+
61+
HRESULT CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
62+
SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
63+
void* pReserved1, DWORD dwAuthnLevel,
64+
DWORD dwImpLevel, void* pAuthList,
65+
DWORD dwCapabilities, void* pReserved3) {
66+
static const StaticDynamicallyLinkedFunctionPtr<
67+
decltype(&::CoInitializeSecurity)>
68+
pCoInitializeSecurity(L"combase.dll", "CoInitializeSecurity");
69+
if (!pCoInitializeSecurity) {
70+
return ::CoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1,
71+
dwAuthnLevel, dwImpLevel, pAuthList,
72+
dwCapabilities, pReserved3);
73+
}
74+
75+
return pCoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1,
76+
dwAuthnLevel, dwImpLevel, pAuthList,
77+
dwCapabilities, pReserved3);
78+
}
79+
80+
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
81+
DWORD dwClsContext, REFIID riid, LPVOID* ppv) {
82+
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoCreateInstance)>
83+
pCoCreateInstance(L"combase.dll", "CoCreateInstance");
84+
if (!pCoCreateInstance) {
85+
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
86+
}
87+
88+
return pCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
89+
}
90+
91+
HRESULT CoCreateGuid(GUID* pguid) {
92+
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoCreateGuid)>
93+
pCoCreateGuid(L"combase.dll", "CoCreateGuid");
94+
if (!pCoCreateGuid) {
95+
return ::CoCreateGuid(pguid);
96+
}
97+
98+
return pCoCreateGuid(pguid);
99+
}
100+
101+
} // namespace mozilla::mscom::wrapped

ipc/mscom/COMWrappers.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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/. */
6+
7+
#ifndef mozilla_mscom_COMWrappers_h
8+
#define mozilla_mscom_COMWrappers_h
9+
10+
#include <objbase.h>
11+
12+
#if (NTDDI_VERSION < NTDDI_WIN8)
13+
// Win8+ API that we use very carefully
14+
DECLARE_HANDLE(CO_MTA_USAGE_COOKIE);
15+
HRESULT WINAPI CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
16+
#endif // (NTDDI_VERSION < NTDDI_WIN8)
17+
18+
// A set of wrapped COM functions, so that we can dynamically link to the
19+
// functions in combase.dll on win8+. This prevents ole32.dll and many other
20+
// DLLs loading, which are not required when we have win32k locked down.
21+
namespace mozilla::mscom::wrapped {
22+
23+
HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
24+
25+
void CoUninitialize();
26+
27+
HRESULT CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
28+
29+
HRESULT CoGetApartmentType(APTTYPE* pAptType, APTTYPEQUALIFIER* pAptQualifier);
30+
31+
HRESULT CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
32+
SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
33+
void* pReserved1, DWORD dwAuthnLevel,
34+
DWORD dwImpLevel, void* pAuthList,
35+
DWORD dwCapabilities, void* pReserved3);
36+
37+
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
38+
DWORD dwClsContext, REFIID riid, LPVOID* ppv);
39+
40+
HRESULT CoCreateGuid(GUID* pguid);
41+
42+
} // namespace mozilla::mscom::wrapped
43+
44+
#endif // mozilla_mscom_COMWrappers_h

ipc/mscom/EnsureMTA.cpp

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "mozilla/Assertions.h"
1010
#include "mozilla/ClearOnShutdown.h"
1111
#include "mozilla/DebugOnly.h"
12+
#include "mozilla/mscom/COMWrappers.h"
1213
#include "mozilla/mscom/Utils.h"
1314
#include "mozilla/SchedulerGroup.h"
1415
#include "mozilla/StaticLocalPtr.h"
@@ -17,22 +18,14 @@
1718

1819
#include "private/pprthred.h"
1920

20-
#include <combaseapi.h>
21-
22-
#if (NTDDI_VERSION < NTDDI_WIN8)
23-
// Win8+ API that we use very carefully
24-
DECLARE_HANDLE(CO_MTA_USAGE_COOKIE);
25-
HRESULT WINAPI CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
26-
#endif // (NTDDI_VERSION < NTDDI_WIN8)
27-
2821
namespace {
2922

3023
class EnterMTARunnable : public mozilla::Runnable {
3124
public:
3225
EnterMTARunnable() : mozilla::Runnable("EnterMTARunnable") {}
3326
NS_IMETHOD Run() override {
3427
mozilla::DebugOnly<HRESULT> hr =
35-
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
28+
mozilla::mscom::wrapped::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
3629
MOZ_ASSERT(SUCCEEDED(hr));
3730
return NS_OK;
3831
}
@@ -52,7 +45,7 @@ class BackgroundMTAData {
5245
if (mThread) {
5346
mThread->Dispatch(
5447
NS_NewRunnableFunction("BackgroundMTAData::~BackgroundMTAData",
55-
&::CoUninitialize),
48+
&mozilla::mscom::wrapped::CoUninitialize),
5649
NS_DISPATCH_NORMAL);
5750
mThread->Shutdown();
5851
}
@@ -80,28 +73,19 @@ EnsureMTA::EnsureMTA() {
8073
// We intentionally don't check rv unless we need it when
8174
// CoIncremementMTAUsage is unavailable.
8275

83-
// This API is only available beginning with Windows 8. Even though this
84-
// constructor will only be called once, we intentionally use
85-
// StaticDynamicallyLinkedFunctionPtr here to hang onto the ole32 module.
86-
static const StaticDynamicallyLinkedFunctionPtr<
87-
decltype(&::CoIncrementMTAUsage)>
88-
pCoIncrementMTAUsage(L"ole32.dll", "CoIncrementMTAUsage");
89-
if (pCoIncrementMTAUsage) {
90-
// Calling this function initializes the MTA without needing to explicitly
91-
// create a thread and call CoInitializeEx to do it.
92-
// We don't retain the cookie because once we've incremented the MTA, we
93-
// leave it that way for the lifetime of the process.
94-
CO_MTA_USAGE_COOKIE mtaCookie = nullptr;
95-
HRESULT hr = pCoIncrementMTAUsage(&mtaCookie);
96-
MOZ_ASSERT(SUCCEEDED(hr));
97-
if (SUCCEEDED(hr)) {
98-
if (NS_SUCCEEDED(rv)) {
99-
// Start the persistent MTA thread (mostly) asynchronously.
100-
Unused << GetPersistentMTAThread();
101-
}
102-
103-
return;
76+
// Calling this function initializes the MTA without needing to explicitly
77+
// create a thread and call CoInitializeEx to do it.
78+
// We don't retain the cookie because once we've incremented the MTA, we
79+
// leave it that way for the lifetime of the process.
80+
CO_MTA_USAGE_COOKIE mtaCookie = nullptr;
81+
HRESULT hr = wrapped::CoIncrementMTAUsage(&mtaCookie);
82+
if (SUCCEEDED(hr)) {
83+
if (NS_SUCCEEDED(rv)) {
84+
// Start the persistent MTA thread (mostly) asynchronously.
85+
Unused << GetPersistentMTAThread();
10486
}
87+
88+
return;
10589
}
10690

10791
// In the fallback case, we simply initialize our persistent MTA thread.
@@ -128,8 +112,8 @@ EnsureMTA::CreateInstanceInternal(REFCLSID aClsid, REFIID aIid) {
128112
MOZ_ASSERT(IsCurrentThreadExplicitMTA());
129113

130114
RefPtr<IUnknown> iface;
131-
HRESULT hr = ::CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER, aIid,
132-
getter_AddRefs(iface));
115+
HRESULT hr = wrapped::CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER,
116+
aIid, getter_AddRefs(iface));
133117
if (FAILED(hr)) {
134118
return CreateInstanceAgileRefPromise::CreateAndReject(hr, __func__);
135119
}

ipc/mscom/ProcessRuntime.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// defined(MOZ_HAS_MOZGLUE))
1414
#include "mozilla/Assertions.h"
1515
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
16+
#include "mozilla/mscom/COMWrappers.h"
1617
#include "mozilla/mscom/ProcessRuntimeShared.h"
1718
#include "mozilla/RefPtr.h"
1819
#include "mozilla/UniquePtr.h"
@@ -287,9 +288,9 @@ void ProcessRuntime::InitInsideApartment() {
287288

288289
if (prevInitState < ProcessInitState::PartialGlobalOptions) {
289290
RefPtr<IGlobalOptions> globalOpts;
290-
mInitResult =
291-
::CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC_SERVER,
292-
IID_IGlobalOptions, getter_AddRefs(globalOpts));
291+
mInitResult = wrapped::CoCreateInstance(
292+
CLSID_GlobalOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IGlobalOptions,
293+
getter_AddRefs(globalOpts));
293294
MOZ_ASSERT(SUCCEEDED(mInitResult));
294295
if (FAILED(mInitResult)) {
295296
return;
@@ -468,7 +469,7 @@ ProcessRuntime::InitializeSecurity(const ProcessCategory aProcessCategory) {
468469
return HRESULT_FROM_WIN32(::GetLastError());
469470
}
470471

471-
return ::CoInitializeSecurity(
472+
return wrapped::CoInitializeSecurity(
472473
&sd, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT,
473474
RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_NONE, nullptr);
474475
}

ipc/mscom/Utils.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
#endif
1818

1919
#include "mozilla/ArrayUtils.h"
20+
#include "mozilla/mscom/COMWrappers.h"
2021
#include "mozilla/DebugOnly.h"
2122
#include "mozilla/mscom/Objref.h"
2223
#include "mozilla/mscom/Utils.h"
2324
#include "mozilla/RefPtr.h"
2425
#include "mozilla/WindowsVersion.h"
2526

26-
#include <objbase.h>
2727
#include <objidl.h>
2828
#include <shlwapi.h>
2929
#include <winnt.h>
@@ -40,14 +40,14 @@ namespace mscom {
4040
bool IsCOMInitializedOnCurrentThread() {
4141
APTTYPE aptType;
4242
APTTYPEQUALIFIER aptTypeQualifier;
43-
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
43+
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
4444
return hr != CO_E_NOTINITIALIZED;
4545
}
4646

4747
bool IsCurrentThreadMTA() {
4848
APTTYPE aptType;
4949
APTTYPEQUALIFIER aptTypeQualifier;
50-
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
50+
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
5151
if (FAILED(hr)) {
5252
return false;
5353
}
@@ -58,7 +58,7 @@ bool IsCurrentThreadMTA() {
5858
bool IsCurrentThreadExplicitMTA() {
5959
APTTYPE aptType;
6060
APTTYPEQUALIFIER aptTypeQualifier;
61-
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
61+
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
6262
if (FAILED(hr)) {
6363
return false;
6464
}
@@ -70,7 +70,7 @@ bool IsCurrentThreadExplicitMTA() {
7070
bool IsCurrentThreadImplicitMTA() {
7171
APTTYPE aptType;
7272
APTTYPEQUALIFIER aptTypeQualifier;
73-
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
73+
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
7474
if (FAILED(hr)) {
7575
return false;
7676
}

ipc/mscom/moz.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ EXPORTS.mozilla.mscom += [
1010
"ApartmentRegion.h",
1111
"AsyncInvoker.h",
1212
"COMPtrHolder.h",
13+
"COMWrappers.h",
1314
"EnsureMTA.h",
1415
"Objref.h",
1516
"PassthruProxy.h",
@@ -30,6 +31,7 @@ SOURCES += [
3031

3132
UNIFIED_SOURCES += [
3233
"AgileReference.cpp",
34+
"COMWrappers.cpp",
3335
"EnsureMTA.cpp",
3436
"Objref.cpp",
3537
"PassthruProxy.cpp",

ipc/mscom/oop/moz.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Library("mscom_oop")
88

99
SOURCES += [
1010
"../ActivationContext.cpp",
11+
"../COMWrappers.cpp",
1112
"../Objref.cpp",
1213
"../Registration.cpp",
1314
"../StructStream.cpp",

mozglue/misc/moz.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
7979

8080
if not CONFIG["JS_STANDALONE"]:
8181
SOURCES += [
82+
"/ipc/mscom/COMWrappers.cpp",
8283
"/ipc/mscom/ProcessRuntime.cpp",
8384
"PreXULSkeletonUI.cpp",
8485
]

0 commit comments

Comments
 (0)