зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1744362 - Part 5: Access the shared section through DllServices r=handyman
Differential Revision: https://phabricator.services.mozilla.com/D164487
This commit is contained in:
Родитель
7f7af2303a
Коммит
99ea21dafe
|
@ -13,6 +13,9 @@ namespace mozilla {
|
|||
|
||||
extern "C" MOZ_EXPORT nt::LoaderAPI* GetNtLoaderAPI(
|
||||
nt::LoaderObserver* aNewObserver) {
|
||||
// Make sure the caller is inside mozglue.dll - we don't want to allow
|
||||
// external access to this function, as it contains details about
|
||||
// the SharedSection which is used to sandbox future child processes.
|
||||
const bool isCallerMozglue =
|
||||
CheckForAddress(RETURN_ADDRESS(), L"mozglue.dll");
|
||||
MOZ_ASSERT(isCallerMozglue);
|
||||
|
|
|
@ -88,6 +88,7 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS LoaderPrivateAPIImp final
|
|||
nt::AllocatedUnicodeString GetSectionName(void* aSectionAddr) final;
|
||||
nt::LoaderAPI::InitDllBlocklistOOPFnPtr GetDllBlocklistInitFn() final;
|
||||
nt::LoaderAPI::HandleLauncherErrorFnPtr GetHandleLauncherErrorFn() final;
|
||||
nt::SharedSection* GetSharedSection() final;
|
||||
|
||||
// LoaderPrivateAPI
|
||||
void NotifyBeginDllLoad(void** aContext,
|
||||
|
@ -222,6 +223,10 @@ LoaderPrivateAPIImp::GetHandleLauncherErrorFn() {
|
|||
return &HandleLauncherError;
|
||||
}
|
||||
|
||||
nt::SharedSection* LoaderPrivateAPIImp::GetSharedSection() {
|
||||
return &gSharedSection;
|
||||
}
|
||||
|
||||
nt::MemorySectionNameBuf LoaderPrivateAPIImp::GetSectionNameBuffer(
|
||||
void* aSectionAddr) {
|
||||
const HANDLE kCurrentProcess = reinterpret_cast<HANDLE>(-1);
|
||||
|
|
|
@ -247,23 +247,5 @@ LauncherVoidResult SharedSection::TransferHandle(
|
|||
sizeof(remoteHandle));
|
||||
}
|
||||
|
||||
// This exported function is invoked by SandboxBroker of xul.dll
|
||||
// in order to add dependent modules to the CIG exception list.
|
||||
extern "C" MOZ_EXPORT const wchar_t* GetDependentModulePaths() {
|
||||
// We enable pre-spawn CIG only in early Beta or earlier for now
|
||||
// because it caused a compat issue (bug 1682304 and 1704373).
|
||||
#if defined(EARLY_BETA_OR_EARLIER)
|
||||
const bool isCallerXul = CheckForAddress(RETURN_ADDRESS(), L"xul.dll");
|
||||
MOZ_ASSERT(isCallerXul);
|
||||
if (!isCallerXul) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gSharedSection.GetDependentModules().data();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace freestanding
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_freestanding_SharedSection_h
|
||||
#define mozilla_freestanding_SharedSection_h
|
||||
|
||||
#include "mozilla/glue/SharedSection.h"
|
||||
#include "mozilla/NativeNt.h"
|
||||
#include "mozilla/interceptor/MMPolicies.h"
|
||||
|
||||
|
@ -59,7 +60,7 @@ struct MOZ_TRIVIAL_CTOR_DTOR Kernel32ExportsSolver final
|
|||
// | | ... |
|
||||
// | | L"" |
|
||||
// +--------------------------------------------------------------+
|
||||
class MOZ_TRIVIAL_CTOR_DTOR SharedSection final {
|
||||
class MOZ_TRIVIAL_CTOR_DTOR SharedSection final : public nt::SharedSection {
|
||||
struct Layout final {
|
||||
enum class State {
|
||||
kUninitialized,
|
||||
|
@ -116,7 +117,7 @@ class MOZ_TRIVIAL_CTOR_DTOR SharedSection final {
|
|||
// Map |sSectionHandle| to a copy-on-write page and return a writable pointer
|
||||
// to each structure, or null if Layout failed to resolve exports.
|
||||
Kernel32ExportsSolver* GetKernel32Exports();
|
||||
Span<const wchar_t> GetDependentModules();
|
||||
Span<const wchar_t> GetDependentModules() final override;
|
||||
|
||||
// Transfer |sSectionHandle| to a process associated with |aTransferMgr|.
|
||||
static LauncherVoidResult TransferHandle(
|
||||
|
|
|
@ -265,29 +265,6 @@ class ChildProcess final {
|
|||
return 1;
|
||||
}
|
||||
|
||||
auto getDependentModulePaths =
|
||||
reinterpret_cast<const wchar_t* (*)()>(::GetProcAddress(
|
||||
::GetModuleHandleW(nullptr), "GetDependentModulePaths"));
|
||||
if (!getDependentModulePaths) {
|
||||
printf(
|
||||
"TEST-FAILED | TestCrossProcessWin | "
|
||||
"Failed to get a pointer to GetDependentModulePaths - %08lx.\n",
|
||||
::GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !defined(DEBUG)
|
||||
// GetDependentModulePaths does not allow a caller other than xul.dll.
|
||||
// Skip on Debug build because it hits MOZ_ASSERT.
|
||||
if (getDependentModulePaths()) {
|
||||
printf(
|
||||
"TEST-FAILED | TestCrossProcessWin | "
|
||||
"GetDependentModulePaths should return zero if the caller is "
|
||||
"not xul.dll.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif // !defined(DEBUG)
|
||||
|
||||
if (!VerifySharedSection(gSharedSection)) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -431,20 +431,21 @@ static void AddCachedDirRule(sandbox::TargetPolicy* aPolicy,
|
|||
// (e.g. when the launcher process is disabled), so the process should not
|
||||
// enable pre-spawn CIG.
|
||||
static const Maybe<Vector<const wchar_t*>>& GetPrespawnCigExceptionModules() {
|
||||
// sDependentModules points to a shared section created in the launcher
|
||||
// process and the mapped address is static in each process, so we cache
|
||||
// it as a static variable instead of retrieving it every time.
|
||||
// We enable pre-spawn CIG only in early Beta or earlier for now
|
||||
// because it caused a compat issue (bug 1682304 and 1704373).
|
||||
#if defined(EARLY_BETA_OR_EARLIER)
|
||||
// The shared section contains a list of dependent modules as a
|
||||
// null-delimited string. We convert it to a string vector and
|
||||
// cache it to avoid converting the same data every time.
|
||||
static Maybe<Vector<const wchar_t*>> sDependentModules =
|
||||
[]() -> Maybe<Vector<const wchar_t*>> {
|
||||
using GetDependentModulePathsFn = const wchar_t* (*)();
|
||||
GetDependentModulePathsFn getDependentModulePaths =
|
||||
reinterpret_cast<GetDependentModulePathsFn>(::GetProcAddress(
|
||||
::GetModuleHandleW(nullptr), "GetDependentModulePaths"));
|
||||
if (!getDependentModulePaths) {
|
||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||
auto sharedSection = dllSvc->GetSharedSection();
|
||||
if (!sharedSection) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
const wchar_t* arrayBase = getDependentModulePaths();
|
||||
const wchar_t* arrayBase = sharedSection->GetDependentModules().data();
|
||||
if (!arrayBase) {
|
||||
return Nothing();
|
||||
}
|
||||
|
@ -463,6 +464,9 @@ static const Maybe<Vector<const wchar_t*>>& GetPrespawnCigExceptionModules() {
|
|||
}();
|
||||
|
||||
return sDependentModules;
|
||||
#else
|
||||
return Nothing();
|
||||
#endif
|
||||
}
|
||||
|
||||
static sandbox::ResultCode InitSignedPolicyRulesToBypassCig(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_LoaderAPIInterfaces_h
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/glue/SharedSection.h"
|
||||
#include "mozilla/ModuleLoadInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -104,14 +105,18 @@ class NS_NO_VTABLE LoaderAPI {
|
|||
*/
|
||||
virtual InitDllBlocklistOOPFnPtr GetDllBlocklistInitFn() = 0;
|
||||
virtual HandleLauncherErrorFnPtr GetHandleLauncherErrorFn() = 0;
|
||||
virtual SharedSection* GetSharedSection() = 0;
|
||||
};
|
||||
|
||||
struct WinLauncherFunctions final {
|
||||
struct WinLauncherServices final {
|
||||
nt::LoaderAPI::InitDllBlocklistOOPFnPtr mInitDllBlocklistOOP;
|
||||
nt::LoaderAPI::HandleLauncherErrorFnPtr mHandleLauncherError;
|
||||
SharedSection* mSharedSection;
|
||||
|
||||
WinLauncherFunctions()
|
||||
: mInitDllBlocklistOOP(nullptr), mHandleLauncherError(nullptr) {}
|
||||
WinLauncherServices()
|
||||
: mInitDllBlocklistOOP(nullptr),
|
||||
mHandleLauncherError(nullptr),
|
||||
mSharedSection(nullptr) {}
|
||||
};
|
||||
|
||||
} // namespace nt
|
||||
|
|
|
@ -28,9 +28,8 @@ nt::LoaderAPI* ModuleLoadFrame::sLoaderAPI;
|
|||
using GetNtLoaderAPIFn = decltype(&mozilla::GetNtLoaderAPI);
|
||||
|
||||
/* static */
|
||||
void ModuleLoadFrame::StaticInit(
|
||||
nt::LoaderObserver* aNewObserver,
|
||||
nt::WinLauncherFunctions* aOutWinLauncherFunctions) {
|
||||
void ModuleLoadFrame::StaticInit(nt::LoaderObserver* aNewObserver,
|
||||
nt::WinLauncherServices* aOutWinLauncher) {
|
||||
const auto pGetNtLoaderAPI = reinterpret_cast<GetNtLoaderAPIFn>(
|
||||
::GetProcAddress(::GetModuleHandleW(nullptr), "GetNtLoaderAPI"));
|
||||
if (!pGetNtLoaderAPI) {
|
||||
|
@ -39,9 +38,9 @@ void ModuleLoadFrame::StaticInit(
|
|||
gFallbackLoaderAPI.SetObserver(aNewObserver);
|
||||
sLoaderAPI = &gFallbackLoaderAPI;
|
||||
|
||||
if (aOutWinLauncherFunctions) {
|
||||
aOutWinLauncherFunctions->mHandleLauncherError =
|
||||
[](const mozilla::LauncherError&, const char*) {};
|
||||
if (aOutWinLauncher) {
|
||||
aOutWinLauncher->mHandleLauncherError = [](const mozilla::LauncherError&,
|
||||
const char*) {};
|
||||
// We intentionally leave mInitDllBlocklistOOP null to make sure calling
|
||||
// mInitDllBlocklistOOP in non-Firefox hits MOZ_RELEASE_ASSERT.
|
||||
}
|
||||
|
@ -51,11 +50,11 @@ void ModuleLoadFrame::StaticInit(
|
|||
sLoaderAPI = pGetNtLoaderAPI(aNewObserver);
|
||||
MOZ_ASSERT(sLoaderAPI);
|
||||
|
||||
if (aOutWinLauncherFunctions) {
|
||||
aOutWinLauncherFunctions->mInitDllBlocklistOOP =
|
||||
sLoaderAPI->GetDllBlocklistInitFn();
|
||||
aOutWinLauncherFunctions->mHandleLauncherError =
|
||||
if (aOutWinLauncher) {
|
||||
aOutWinLauncher->mInitDllBlocklistOOP = sLoaderAPI->GetDllBlocklistInitFn();
|
||||
aOutWinLauncher->mHandleLauncherError =
|
||||
sLoaderAPI->GetHandleLauncherErrorFn();
|
||||
aOutWinLauncher->mSharedSection = sLoaderAPI->GetSharedSection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class MOZ_RAII ModuleLoadFrame final {
|
|||
ModuleLoadFrame& operator=(ModuleLoadFrame&&) = delete;
|
||||
|
||||
static void StaticInit(nt::LoaderObserver* aNewObserver,
|
||||
nt::WinLauncherFunctions* aOutWinLauncherFunctions);
|
||||
nt::WinLauncherServices* aOutWinLauncher);
|
||||
|
||||
private:
|
||||
bool mAlreadyLoaded;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* -*- 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_glue_SharedSection_h
|
||||
#define mozilla_glue_SharedSection_h
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
namespace mozilla::nt {
|
||||
|
||||
// This interface provides a way to access winlauncher's shared section
|
||||
// through DllServices.
|
||||
struct NS_NO_VTABLE SharedSection {
|
||||
virtual Span<const wchar_t> GetDependentModules() = 0;
|
||||
};
|
||||
|
||||
} // namespace mozilla::nt
|
||||
|
||||
#endif // mozilla_glue_SharedSection_h
|
|
@ -597,7 +597,7 @@ static WindowsDllInterceptor Kernel32Intercept;
|
|||
static void GetNativeNtBlockSetWriter();
|
||||
|
||||
static glue::LoaderObserver gMozglueLoaderObserver;
|
||||
static nt::WinLauncherFunctions gWinLauncherFunctions;
|
||||
static nt::WinLauncherServices gWinLauncher;
|
||||
|
||||
MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags) {
|
||||
if (sBlocklistInitAttempted) {
|
||||
|
@ -607,8 +607,7 @@ MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags) {
|
|||
|
||||
sInitFlags = aInitFlags;
|
||||
|
||||
glue::ModuleLoadFrame::StaticInit(&gMozglueLoaderObserver,
|
||||
&gWinLauncherFunctions);
|
||||
glue::ModuleLoadFrame::StaticInit(&gMozglueLoaderObserver, &gWinLauncher);
|
||||
|
||||
#ifdef _M_AMD64
|
||||
if (!IsWin8OrLater()) {
|
||||
|
@ -764,7 +763,7 @@ MFBT_API void DllBlocklist_SetFullDllServices(
|
|||
glue::AutoExclusiveLock lock(gDllServicesLock);
|
||||
if (aSvc) {
|
||||
aSvc->SetAuthenticodeImpl(GetAuthenticode());
|
||||
aSvc->SetWinLauncherFunctions(gWinLauncherFunctions);
|
||||
aSvc->SetWinLauncherServices(gWinLauncher);
|
||||
gMozglueLoaderObserver.Forward(aSvc);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,23 +58,24 @@ class DllServicesBase : public Authenticode {
|
|||
mAuthenticode = aAuthenticode;
|
||||
}
|
||||
|
||||
void SetWinLauncherFunctions(const nt::WinLauncherFunctions& aFunctions) {
|
||||
mWinLauncherFunctions = aFunctions;
|
||||
void SetWinLauncherServices(const nt::WinLauncherServices& aWinLauncher) {
|
||||
mWinLauncher = aWinLauncher;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
LauncherVoidResultWithLineInfo InitDllBlocklistOOP(Args&&... aArgs) {
|
||||
MOZ_RELEASE_ASSERT(mWinLauncherFunctions.mInitDllBlocklistOOP);
|
||||
return mWinLauncherFunctions.mInitDllBlocklistOOP(
|
||||
std::forward<Args>(aArgs)...);
|
||||
MOZ_RELEASE_ASSERT(mWinLauncher.mInitDllBlocklistOOP);
|
||||
return mWinLauncher.mInitDllBlocklistOOP(std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void HandleLauncherError(Args&&... aArgs) {
|
||||
MOZ_RELEASE_ASSERT(mWinLauncherFunctions.mHandleLauncherError);
|
||||
mWinLauncherFunctions.mHandleLauncherError(std::forward<Args>(aArgs)...);
|
||||
MOZ_RELEASE_ASSERT(mWinLauncher.mHandleLauncherError);
|
||||
mWinLauncher.mHandleLauncherError(std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
nt::SharedSection* GetSharedSection() { return mWinLauncher.mSharedSection; }
|
||||
|
||||
// In debug builds we override GetBinaryOrgName to add a Gecko-specific
|
||||
// assertion. OTOH, we normally do not want people overriding this function,
|
||||
// so we'll make it final in the release case, thus covering all bases.
|
||||
|
@ -112,7 +113,7 @@ class DllServicesBase : public Authenticode {
|
|||
|
||||
private:
|
||||
Authenticode* mAuthenticode;
|
||||
nt::WinLauncherFunctions mWinLauncherFunctions;
|
||||
nt::WinLauncherServices mWinLauncher;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -79,6 +79,11 @@ FallbackLoaderAPI::GetHandleLauncherErrorFn() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nt::SharedSection* FallbackLoaderAPI::GetSharedSection() {
|
||||
MOZ_ASSERT_UNREACHABLE("This should not be called so soon!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FallbackLoaderAPI::SetObserver(nt::LoaderObserver* aLoaderObserver) {
|
||||
mLoaderObserver = aLoaderObserver;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FallbackLoaderAPI final
|
|||
nt::AllocatedUnicodeString GetSectionName(void* aSectionAddr) final;
|
||||
nt::LoaderAPI::InitDllBlocklistOOPFnPtr GetDllBlocklistInitFn() final;
|
||||
nt::LoaderAPI::HandleLauncherErrorFnPtr GetHandleLauncherErrorFn() final;
|
||||
nt::SharedSection* GetSharedSection() final;
|
||||
|
||||
void SetObserver(nt::LoaderObserver* aLoaderObserver);
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ EXPORTS.mozilla += [
|
|||
]
|
||||
|
||||
EXPORTS.mozilla.glue += [
|
||||
"SharedSection.h",
|
||||
"WindowsDllServices.h",
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче