/* -*- 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/. */
EnsureMTA(); /** * From this point forward, all threads in this process are implicitly * members of the multi-threaded apartment, with the following exceptions: * 1. If any Win32 GUI APIs were called on the current thread prior to * executing this constructor, then this thread has already been implicitly * initialized as the process's main STA thread; or * 2. A thread explicitly and successfully calls CoInitialize(Ex) to specify * otherwise.
*/
constbool isCurThreadImplicitMTA = IsCurrentThreadImplicitMTA(); // We only assert that the implicit MTA precondition holds when not running // as the Gecko parent process.
MOZ_DIAGNOSTIC_ASSERT(aProcessCategory ==
ProcessCategory::GeckoBrowserParent ||
isCurThreadImplicitMTA);
# ifdefined(MOZ_SANDBOX) constbool isLockedDownChildProcess =
mProcessCategory == ProcessCategory::GeckoChild && IsWin32kLockedDown(); // If our process is running under Win32k lockdown, we cannot initialize // COM with a single-threaded apartment. This is because STAs create a hidden // window, which implicitly requires user32 and Win32k, which are blocked. // Instead we start the multi-threaded apartment and conduct our process-wide // COM initialization there. if (isLockedDownChildProcess) { // Make sure we're still running with the sandbox's privileged impersonation // token.
HANDLE rawCurThreadImpToken; if (!::OpenThreadToken(::GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &rawCurThreadImpToken)) {
mInitResult = HRESULT_FROM_WIN32(::GetLastError()); return;
}
nsAutoHandle curThreadImpToken(rawCurThreadImpToken);
// Ensure that our current token is still an impersonation token (ie, we // have not yet called RevertToSelf() on this thread).
DWORD len;
TOKEN_TYPE tokenType;
MOZ_RELEASE_ASSERT(
::GetTokenInformation(rawCurThreadImpToken, TokenType, &tokenType, sizeof(tokenType), &len) &&
len == sizeof(tokenType) && tokenType == TokenImpersonation);
// Ideally we want our current thread to be running implicitly inside the // MTA, but if for some wacky reason we did not end up with that, we may // compensate by completing initialization via EnsureMTA's persistent // thread. if (!isCurThreadImplicitMTA) {
InitUsingPersistentMTAThread(curThreadImpToken); return;
}
} # endif // defined(MOZ_SANDBOX) #endif// defined(MOZILLA_INTERNAL_API)
// It can happen that we are not the outermost COM initialization on this // thread. In fact it should regularly be the case that the outermost // initialization occurs from outside of XUL, before we show the skeleton UI, // at which point we still need to run some things here from within XUL. if (!mAptRegion.IsValidOutermost()) {
mInitResult = mAptRegion.GetHResult(); #ifdefined(MOZILLA_INTERNAL_API)
MOZ_ASSERT(mProcessCategory == ProcessCategory::GeckoBrowserParent); if (mProcessCategory != ProcessCategory::GeckoBrowserParent) { // This is unexpected unless we're GeckoBrowserParent return;
}
ProcessInitLock lock;
// Is another instance of ProcessRuntime responsible for the outer // initialization? constbool prevInit =
lock.GetInitState() == ProcessInitState::FullyInitialized;
MOZ_ASSERT(prevInit); if (prevInit) {
PostInit();
} #endif// defined(MOZILLA_INTERNAL_API) return;
}
InitInsideApartment(); if (FAILED(mInitResult)) { return;
}
#ifdefined(MOZILLA_INTERNAL_API) # ifdefined(MOZ_SANDBOX) if (isLockedDownChildProcess) { // In locked-down child processes, defer PostInit until priv drop
SandboxTarget::Instance()->RegisterSandboxStartCallback([self = this]() { // Ensure that we're still live and the init was successful before // calling PostInit() if (self == sInstance && SUCCEEDED(self->mInitResult)) {
PostInit();
}
}); return;
} # endif // defined(MOZ_SANDBOX)
SandboxTarget::Instance()->RegisterSandboxStartCallback(
[self = this]() -> void {
EnsureMTA(
[]() -> void { // This is a security risk if it fails, so we release assert
MOZ_RELEASE_ASSERT(::RevertToSelf(), "mscom::ProcessRuntime RevertToSelf failed");
},
EnsureMTA::Option::ForceDispatchToPersistentThread);
// Ensure that we're still live and the init was successful before // calling PostInit() if (self == sInstance && SUCCEEDED(self->mInitResult)) {
PostInit();
}
});
} # endif // defined(MOZ_SANDBOX) #endif// defined(MOZILLA_INTERNAL_API)
/* static */
COINIT ProcessRuntime::GetDesiredApartmentType( const ProcessRuntime::ProcessCategory aProcessCategory) { switch (aProcessCategory) { case ProcessCategory::GeckoBrowserParent: return COINIT_APARTMENTTHREADED; case ProcessCategory::GeckoChild: if (!IsWin32kLockedDown()) { // If Win32k is not locked down then we probably still need STA. // We disable DDE since that is not usable from child processes. returnstatic_cast<COINIT>(COINIT_APARTMENTTHREADED |
COINIT_DISABLE_OLE1DDE);
}
void ProcessRuntime::InitInsideApartment() {
ProcessInitLock lock; const ProcessInitState prevInitState = lock.GetInitState(); if (prevInitState == ProcessInitState::FullyInitialized) { // COM has already been initialized by a previous ProcessRuntime instance
mInitResult = S_OK; return;
}
if (prevInitState < ProcessInitState::PartialSecurityInitialized) { // We are required to initialize security prior to configuring global // options.
mInitResult = InitializeSecurity(mProcessCategory); // Downgrading from a MOZ_DIAGNOSTIC_ASSERT while investigating // bug 1930846.
MOZ_ASSERT(SUCCEEDED(mInitResult));
// Even though this isn't great, we should try to proceed even when // CoInitializeSecurity has previously been called: the additional settings // we want to change are important enough that we don't want to skip them. if (FAILED(mInitResult) && mInitResult != RPC_E_TOO_LATE) { return;
}
// Disable the BSTR cache (as it never invalidates, thus leaking memory) // (This function is itself idempotent, so we do not concern ourselves with // tracking whether or not we've already called it.)
::SetOaNoCache();
#ifdefined(MOZILLA_INTERNAL_API) /** * Guaranteed to run *after* the COM (and possible sandboxing) initialization * has successfully completed and stabilized. This method MUST BE IDEMPOTENT!
*/ /* static */ void ProcessRuntime::PostInit() { // Currently "roughed-in" but unused.
} #endif// defined(MOZILLA_INTERNAL_API)
/* static */
DWORD
ProcessRuntime::GetClientThreadId() {
DWORD callerTid;
HRESULT hr = ::CoGetCallerTID(&callerTid); // Don't return callerTid unless the call succeeded and returned S_FALSE, // indicating that the caller originates from a different process. if (hr != S_FALSE) { return 0;
}
UniquePtr<BYTE[]> tokenAppContainerInfBuf;
len = 0;
::GetTokenInformation(token, TokenAppContainerSid, nullptr, len, &len); if (len) {
tokenAppContainerInfBuf = MakeUnique<BYTE[]>(len);
ok = ::GetTokenInformation(token, TokenAppContainerSid,
tokenAppContainerInfBuf.get(), len, &len); if (!ok) { // Don't fail if we get an error retrieving an app container SID.
tokenAppContainerInfBuf = nullptr;
}
}
// Grant access to SYSTEM, Administrators, the user, our app container (if in // one) and when running as the browser process on Windows 8+, all non // restricted app containers. const size_t kMaxInlineEntries = 5;
mozilla::Vector<EXPLICIT_ACCESS_W, kMaxInlineEntries> entries;
if (tokenAppContainerInfBuf) {
TOKEN_APPCONTAINER_INFORMATION& tokenAppContainerInf =
*reinterpret_cast<TOKEN_APPCONTAINER_INFORMATION*>(
tokenAppContainerInfBuf.get());
// TokenAppContainer will be null if we are not in an app container. if (tokenAppContainerInf.TokenAppContainer) {
Unused << entries.append(EXPLICIT_ACCESS_W{
COM_RIGHTS_EXECUTE,
GRANT_ACCESS,
NO_INHERITANCE,
{nullptr, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_USER, reinterpret_cast<LPWSTR>(tokenAppContainerInf.TokenAppContainer)}});
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.