mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1546154 p3: Explicitly load COM functions from combase.dll to prevent ole32 loading. r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D124931
This commit is contained in:
parent
31688610ce
commit
972b41f513
@ -9,6 +9,7 @@ Library("winlauncher")
|
||||
FORCE_STATIC_LIB = True
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"/ipc/mscom/COMWrappers.cpp",
|
||||
"/ipc/mscom/ProcessRuntime.cpp",
|
||||
"/toolkit/xre/WinTokenUtils.cpp",
|
||||
"/widget/windows/WindowsConsole.cpp",
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include <objbase.h>
|
||||
#include "mozilla/mscom/COMWrappers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
@ -25,14 +24,14 @@ class MOZ_NON_TEMPORARY_CLASS ApartmentRegion final {
|
||||
constexpr ApartmentRegion() : mInitResult(CO_E_NOTINITIALIZED) {}
|
||||
|
||||
explicit ApartmentRegion(COINIT aAptType)
|
||||
: mInitResult(::CoInitializeEx(nullptr, aAptType)) {
|
||||
: mInitResult(wrapped::CoInitializeEx(nullptr, aAptType)) {
|
||||
// If this fires then we're probably mixing apartments on the same thread
|
||||
MOZ_ASSERT(IsValid());
|
||||
}
|
||||
|
||||
~ApartmentRegion() {
|
||||
if (IsValid()) {
|
||||
::CoUninitialize();
|
||||
wrapped::CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +43,7 @@ class MOZ_NON_TEMPORARY_CLASS ApartmentRegion final {
|
||||
|
||||
bool Init(COINIT aAptType) {
|
||||
MOZ_ASSERT(mInitResult == CO_E_NOTINITIALIZED);
|
||||
mInitResult = ::CoInitializeEx(nullptr, aAptType);
|
||||
mInitResult = wrapped::CoInitializeEx(nullptr, aAptType);
|
||||
MOZ_ASSERT(IsValid());
|
||||
return IsValid();
|
||||
}
|
||||
|
101
ipc/mscom/COMWrappers.cpp
Normal file
101
ipc/mscom/COMWrappers.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/mscom/COMWrappers.h"
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
|
||||
|
||||
namespace mozilla::mscom::wrapped {
|
||||
|
||||
HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoInitializeEx)>
|
||||
pCoInitializeEx(L"combase.dll", "CoInitializeEx");
|
||||
if (!pCoInitializeEx) {
|
||||
return ::CoInitializeEx(pvReserved, dwCoInit);
|
||||
}
|
||||
|
||||
return pCoInitializeEx(pvReserved, dwCoInit);
|
||||
}
|
||||
|
||||
void CoUninitialize() {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoUninitialize)>
|
||||
pCoUninitialize(L"combase.dll", "CoUninitialize");
|
||||
if (!pCoUninitialize) {
|
||||
return ::CoUninitialize();
|
||||
}
|
||||
|
||||
return pCoUninitialize();
|
||||
}
|
||||
|
||||
HRESULT CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<
|
||||
decltype(&::CoIncrementMTAUsage)>
|
||||
pCoIncrementMTAUsage(L"combase.dll", "CoIncrementMTAUsage");
|
||||
// This API is only available beginning with Windows 8.
|
||||
if (!pCoIncrementMTAUsage) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT hr = pCoIncrementMTAUsage(pCookie);
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CoGetApartmentType(APTTYPE* pAptType, APTTYPEQUALIFIER* pAptQualifier) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<
|
||||
decltype(&::CoGetApartmentType)>
|
||||
pCoGetApartmentType(L"combase.dll", "CoGetApartmentType");
|
||||
if (!pCoGetApartmentType) {
|
||||
return ::CoGetApartmentType(pAptType, pAptQualifier);
|
||||
}
|
||||
|
||||
return pCoGetApartmentType(pAptType, pAptQualifier);
|
||||
}
|
||||
|
||||
HRESULT CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
|
||||
SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
|
||||
void* pReserved1, DWORD dwAuthnLevel,
|
||||
DWORD dwImpLevel, void* pAuthList,
|
||||
DWORD dwCapabilities, void* pReserved3) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<
|
||||
decltype(&::CoInitializeSecurity)>
|
||||
pCoInitializeSecurity(L"combase.dll", "CoInitializeSecurity");
|
||||
if (!pCoInitializeSecurity) {
|
||||
return ::CoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1,
|
||||
dwAuthnLevel, dwImpLevel, pAuthList,
|
||||
dwCapabilities, pReserved3);
|
||||
}
|
||||
|
||||
return pCoInitializeSecurity(pSecDesc, cAuthSvc, asAuthSvc, pReserved1,
|
||||
dwAuthnLevel, dwImpLevel, pAuthList,
|
||||
dwCapabilities, pReserved3);
|
||||
}
|
||||
|
||||
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
|
||||
DWORD dwClsContext, REFIID riid, LPVOID* ppv) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoCreateInstance)>
|
||||
pCoCreateInstance(L"combase.dll", "CoCreateInstance");
|
||||
if (!pCoCreateInstance) {
|
||||
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
|
||||
}
|
||||
|
||||
return pCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
|
||||
}
|
||||
|
||||
HRESULT CoCreateGuid(GUID* pguid) {
|
||||
static const StaticDynamicallyLinkedFunctionPtr<decltype(&::CoCreateGuid)>
|
||||
pCoCreateGuid(L"combase.dll", "CoCreateGuid");
|
||||
if (!pCoCreateGuid) {
|
||||
return ::CoCreateGuid(pguid);
|
||||
}
|
||||
|
||||
return pCoCreateGuid(pguid);
|
||||
}
|
||||
|
||||
} // namespace mozilla::mscom::wrapped
|
44
ipc/mscom/COMWrappers.h
Normal file
44
ipc/mscom/COMWrappers.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_mscom_COMWrappers_h
|
||||
#define mozilla_mscom_COMWrappers_h
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
#if (NTDDI_VERSION < NTDDI_WIN8)
|
||||
// Win8+ API that we use very carefully
|
||||
DECLARE_HANDLE(CO_MTA_USAGE_COOKIE);
|
||||
HRESULT WINAPI CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
|
||||
#endif // (NTDDI_VERSION < NTDDI_WIN8)
|
||||
|
||||
// A set of wrapped COM functions, so that we can dynamically link to the
|
||||
// functions in combase.dll on win8+. This prevents ole32.dll and many other
|
||||
// DLLs loading, which are not required when we have win32k locked down.
|
||||
namespace mozilla::mscom::wrapped {
|
||||
|
||||
HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
|
||||
|
||||
void CoUninitialize();
|
||||
|
||||
HRESULT CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
|
||||
|
||||
HRESULT CoGetApartmentType(APTTYPE* pAptType, APTTYPEQUALIFIER* pAptQualifier);
|
||||
|
||||
HRESULT CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
|
||||
SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
|
||||
void* pReserved1, DWORD dwAuthnLevel,
|
||||
DWORD dwImpLevel, void* pAuthList,
|
||||
DWORD dwCapabilities, void* pReserved3);
|
||||
|
||||
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
|
||||
DWORD dwClsContext, REFIID riid, LPVOID* ppv);
|
||||
|
||||
HRESULT CoCreateGuid(GUID* pguid);
|
||||
|
||||
} // namespace mozilla::mscom::wrapped
|
||||
|
||||
#endif // mozilla_mscom_COMWrappers_h
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/mscom/COMWrappers.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/StaticLocalPtr.h"
|
||||
@ -17,14 +18,6 @@
|
||||
|
||||
#include "private/pprthred.h"
|
||||
|
||||
#include <combaseapi.h>
|
||||
|
||||
#if (NTDDI_VERSION < NTDDI_WIN8)
|
||||
// Win8+ API that we use very carefully
|
||||
DECLARE_HANDLE(CO_MTA_USAGE_COOKIE);
|
||||
HRESULT WINAPI CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE* pCookie);
|
||||
#endif // (NTDDI_VERSION < NTDDI_WIN8)
|
||||
|
||||
namespace {
|
||||
|
||||
class EnterMTARunnable : public mozilla::Runnable {
|
||||
@ -32,7 +25,7 @@ class EnterMTARunnable : public mozilla::Runnable {
|
||||
EnterMTARunnable() : mozilla::Runnable("EnterMTARunnable") {}
|
||||
NS_IMETHOD Run() override {
|
||||
mozilla::DebugOnly<HRESULT> hr =
|
||||
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
mozilla::mscom::wrapped::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -52,7 +45,7 @@ class BackgroundMTAData {
|
||||
if (mThread) {
|
||||
mThread->Dispatch(
|
||||
NS_NewRunnableFunction("BackgroundMTAData::~BackgroundMTAData",
|
||||
&::CoUninitialize),
|
||||
&mozilla::mscom::wrapped::CoUninitialize),
|
||||
NS_DISPATCH_NORMAL);
|
||||
mThread->Shutdown();
|
||||
}
|
||||
@ -80,28 +73,19 @@ EnsureMTA::EnsureMTA() {
|
||||
// We intentionally don't check rv unless we need it when
|
||||
// CoIncremementMTAUsage is unavailable.
|
||||
|
||||
// This API is only available beginning with Windows 8. Even though this
|
||||
// constructor will only be called once, we intentionally use
|
||||
// StaticDynamicallyLinkedFunctionPtr here to hang onto the ole32 module.
|
||||
static const StaticDynamicallyLinkedFunctionPtr<
|
||||
decltype(&::CoIncrementMTAUsage)>
|
||||
pCoIncrementMTAUsage(L"ole32.dll", "CoIncrementMTAUsage");
|
||||
if (pCoIncrementMTAUsage) {
|
||||
// Calling this function initializes the MTA without needing to explicitly
|
||||
// create a thread and call CoInitializeEx to do it.
|
||||
// We don't retain the cookie because once we've incremented the MTA, we
|
||||
// leave it that way for the lifetime of the process.
|
||||
CO_MTA_USAGE_COOKIE mtaCookie = nullptr;
|
||||
HRESULT hr = pCoIncrementMTAUsage(&mtaCookie);
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Start the persistent MTA thread (mostly) asynchronously.
|
||||
Unused << GetPersistentMTAThread();
|
||||
}
|
||||
|
||||
return;
|
||||
// Calling this function initializes the MTA without needing to explicitly
|
||||
// create a thread and call CoInitializeEx to do it.
|
||||
// We don't retain the cookie because once we've incremented the MTA, we
|
||||
// leave it that way for the lifetime of the process.
|
||||
CO_MTA_USAGE_COOKIE mtaCookie = nullptr;
|
||||
HRESULT hr = wrapped::CoIncrementMTAUsage(&mtaCookie);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Start the persistent MTA thread (mostly) asynchronously.
|
||||
Unused << GetPersistentMTAThread();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// In the fallback case, we simply initialize our persistent MTA thread.
|
||||
@ -128,8 +112,8 @@ EnsureMTA::CreateInstanceInternal(REFCLSID aClsid, REFIID aIid) {
|
||||
MOZ_ASSERT(IsCurrentThreadExplicitMTA());
|
||||
|
||||
RefPtr<IUnknown> iface;
|
||||
HRESULT hr = ::CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER, aIid,
|
||||
getter_AddRefs(iface));
|
||||
HRESULT hr = wrapped::CoCreateInstance(aClsid, nullptr, CLSCTX_INPROC_SERVER,
|
||||
aIid, getter_AddRefs(iface));
|
||||
if (FAILED(hr)) {
|
||||
return CreateInstanceAgileRefPromise::CreateAndReject(hr, __func__);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// defined(MOZ_HAS_MOZGLUE))
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
|
||||
#include "mozilla/mscom/COMWrappers.h"
|
||||
#include "mozilla/mscom/ProcessRuntimeShared.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
@ -287,9 +288,9 @@ void ProcessRuntime::InitInsideApartment() {
|
||||
|
||||
if (prevInitState < ProcessInitState::PartialGlobalOptions) {
|
||||
RefPtr<IGlobalOptions> globalOpts;
|
||||
mInitResult =
|
||||
::CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_IGlobalOptions, getter_AddRefs(globalOpts));
|
||||
mInitResult = wrapped::CoCreateInstance(
|
||||
CLSID_GlobalOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IGlobalOptions,
|
||||
getter_AddRefs(globalOpts));
|
||||
MOZ_ASSERT(SUCCEEDED(mInitResult));
|
||||
if (FAILED(mInitResult)) {
|
||||
return;
|
||||
@ -468,7 +469,7 @@ ProcessRuntime::InitializeSecurity(const ProcessCategory aProcessCategory) {
|
||||
return HRESULT_FROM_WIN32(::GetLastError());
|
||||
}
|
||||
|
||||
return ::CoInitializeSecurity(
|
||||
return wrapped::CoInitializeSecurity(
|
||||
&sd, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT,
|
||||
RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_NONE, nullptr);
|
||||
}
|
||||
|
@ -17,13 +17,13 @@
|
||||
#endif
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/mscom/COMWrappers.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/mscom/Objref.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
#include <objbase.h>
|
||||
#include <objidl.h>
|
||||
#include <shlwapi.h>
|
||||
#include <winnt.h>
|
||||
@ -40,14 +40,14 @@ namespace mscom {
|
||||
bool IsCOMInitializedOnCurrentThread() {
|
||||
APTTYPE aptType;
|
||||
APTTYPEQUALIFIER aptTypeQualifier;
|
||||
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
return hr != CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
bool IsCurrentThreadMTA() {
|
||||
APTTYPE aptType;
|
||||
APTTYPEQUALIFIER aptTypeQualifier;
|
||||
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
@ -58,7 +58,7 @@ bool IsCurrentThreadMTA() {
|
||||
bool IsCurrentThreadExplicitMTA() {
|
||||
APTTYPE aptType;
|
||||
APTTYPEQUALIFIER aptTypeQualifier;
|
||||
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
@ -70,7 +70,7 @@ bool IsCurrentThreadExplicitMTA() {
|
||||
bool IsCurrentThreadImplicitMTA() {
|
||||
APTTYPE aptType;
|
||||
APTTYPEQUALIFIER aptTypeQualifier;
|
||||
HRESULT hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
HRESULT hr = wrapped::CoGetApartmentType(&aptType, &aptTypeQualifier);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ EXPORTS.mozilla.mscom += [
|
||||
"ApartmentRegion.h",
|
||||
"AsyncInvoker.h",
|
||||
"COMPtrHolder.h",
|
||||
"COMWrappers.h",
|
||||
"EnsureMTA.h",
|
||||
"Objref.h",
|
||||
"PassthruProxy.h",
|
||||
@ -30,6 +31,7 @@ SOURCES += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"AgileReference.cpp",
|
||||
"COMWrappers.cpp",
|
||||
"EnsureMTA.cpp",
|
||||
"Objref.cpp",
|
||||
"PassthruProxy.cpp",
|
||||
|
@ -8,6 +8,7 @@ Library("mscom_oop")
|
||||
|
||||
SOURCES += [
|
||||
"../ActivationContext.cpp",
|
||||
"../COMWrappers.cpp",
|
||||
"../Objref.cpp",
|
||||
"../Registration.cpp",
|
||||
"../StructStream.cpp",
|
||||
|
@ -79,6 +79,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
||||
|
||||
if not CONFIG["JS_STANDALONE"]:
|
||||
SOURCES += [
|
||||
"/ipc/mscom/COMWrappers.cpp",
|
||||
"/ipc/mscom/ProcessRuntime.cpp",
|
||||
"PreXULSkeletonUI.cpp",
|
||||
]
|
||||
|
@ -20,6 +20,8 @@ forbid-mscom-init:
|
||||
exclude:
|
||||
# These files are the only allowable locations
|
||||
- ipc/mscom/ApartmentRegion.h
|
||||
- ipc/mscom/COMWrappers.cpp
|
||||
- ipc/mscom/COMWrappers.h
|
||||
- ipc/mscom/ProcessRuntime.cpp
|
||||
- ipc/mscom/EnsureMTA.cpp
|
||||
# These files are existing locations that must eventually be fixed.
|
||||
|
@ -5,8 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include <windows.h>
|
||||
# include <objbase.h>
|
||||
# include "mozilla/mscom/COMWrappers.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
# include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
@ -95,7 +94,7 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsID* aId) {
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
HRESULT hr = CoCreateGuid((GUID*)aId);
|
||||
HRESULT hr = mozilla::mscom::wrapped::CoCreateGuid((GUID*)aId);
|
||||
if (FAILED(hr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user