mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-13 18:27:35 +00:00
Bug 1756518 - Delay starting UntrustedModulesProcessor. r=mhowell,necko-reviewers,kershaw
This patch is to delay starting `UntrustedModulesProcessor` to avoid processing a massive amount of loaded modules in the browser process during startup. To achive that, this patch introduces "unblock-untrusted-modules-thread" notification. Before the notification, `UntrustedModulesProcessor` is created but marked as not ready. This means the processor does not go beyond `ScheduleNonEmptyQueueProcessing`. Once the notification is observed, we propagate it to all existing child processes, and afterward `UntrustedModulesProcessor` in new processes will be marked ready from the beginning. Differential Revision: https://phabricator.services.mozilla.com/D140123
This commit is contained in:
parent
ed39c78974
commit
c601fd8b0a
@ -2766,6 +2766,16 @@ BrowserGlue.prototype = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
condition: AppConstants.platform == "win",
|
||||||
|
task: () => {
|
||||||
|
Services.obs.notifyObservers(
|
||||||
|
null,
|
||||||
|
"unblock-untrusted-modules-thread"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// WebDriver components (Remote Agent and Marionette) need to be
|
// WebDriver components (Remote Agent and Marionette) need to be
|
||||||
// initialized as very last step.
|
// initialized as very last step.
|
||||||
{
|
{
|
||||||
|
@ -676,7 +676,8 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
|
|||||||
FullLookAndFeel&& aLookAndFeelData, dom::SystemFontList&& aFontList,
|
FullLookAndFeel&& aLookAndFeelData, dom::SystemFontList&& aFontList,
|
||||||
Maybe<SharedMemoryHandle>&& aSharedUASheetHandle,
|
Maybe<SharedMemoryHandle>&& aSharedUASheetHandle,
|
||||||
const uintptr_t& aSharedUASheetAddress,
|
const uintptr_t& aSharedUASheetAddress,
|
||||||
nsTArray<SharedMemoryHandle>&& aSharedFontListBlocks) {
|
nsTArray<SharedMemoryHandle>&& aSharedFontListBlocks,
|
||||||
|
const bool& aIsReadyForBackgroundProcessing) {
|
||||||
if (!sShutdownCanary) {
|
if (!sShutdownCanary) {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
@ -691,7 +692,8 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
|
|||||||
|
|
||||||
gfx::gfxVars::SetValuesForInitialize(aXPCOMInit.gfxNonDefaultVarUpdates());
|
gfx::gfxVars::SetValuesForInitialize(aXPCOMInit.gfxNonDefaultVarUpdates());
|
||||||
InitSharedUASheets(std::move(aSharedUASheetHandle), aSharedUASheetAddress);
|
InitSharedUASheets(std::move(aSharedUASheetHandle), aSharedUASheetAddress);
|
||||||
InitXPCOM(std::move(aXPCOMInit), aInitialData);
|
InitXPCOM(std::move(aXPCOMInit), aInitialData,
|
||||||
|
aIsReadyForBackgroundProcessing);
|
||||||
InitGraphicsDeviceData(aXPCOMInit.contentDeviceData());
|
InitGraphicsDeviceData(aXPCOMInit.contentDeviceData());
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@ -1323,7 +1325,8 @@ void ContentChild::InitSharedUASheets(Maybe<SharedMemoryHandle>&& aHandle,
|
|||||||
|
|
||||||
void ContentChild::InitXPCOM(
|
void ContentChild::InitXPCOM(
|
||||||
XPCOMInitData&& aXPCOMInit,
|
XPCOMInitData&& aXPCOMInit,
|
||||||
const mozilla::dom::ipc::StructuredCloneData& aInitialData) {
|
const mozilla::dom::ipc::StructuredCloneData& aInitialData,
|
||||||
|
bool aIsReadyForBackgroundProcessing) {
|
||||||
#ifdef MOZ_WIDGET_GTK
|
#ifdef MOZ_WIDGET_GTK
|
||||||
// LookAndFeel::NativeInit takes a long time to run on Linux, here we schedule
|
// LookAndFeel::NativeInit takes a long time to run on Linux, here we schedule
|
||||||
// it as soon as possible after BackgroundChild::Startup to give
|
// it as soon as possible after BackgroundChild::Startup to give
|
||||||
@ -1336,7 +1339,7 @@ void ContentChild::InitXPCOM(
|
|||||||
// DLL services untrusted modules processing depends on
|
// DLL services untrusted modules processing depends on
|
||||||
// BackgroundChild::Startup having been called
|
// BackgroundChild::Startup having been called
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
dllSvc->StartUntrustedModulesProcessor(aIsReadyForBackgroundProcessing);
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
|
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
|
||||||
@ -1463,6 +1466,14 @@ mozilla::ipc::IPCResult ContentChild::RecvGetUntrustedModulesData(
|
|||||||
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult ContentChild::RecvUnblockUntrustedModulesThread() {
|
||||||
|
if (nsCOMPtr<nsIObserverService> obs =
|
||||||
|
mozilla::services::GetObserverService()) {
|
||||||
|
obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
|
||||||
|
}
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
PCycleCollectWithLogsChild* ContentChild::AllocPCycleCollectWithLogsChild(
|
PCycleCollectWithLogsChild* ContentChild::AllocPCycleCollectWithLogsChild(
|
||||||
|
@ -124,7 +124,8 @@ class ContentChild final : public PContentChild,
|
|||||||
bool aIsForBrowser);
|
bool aIsForBrowser);
|
||||||
|
|
||||||
void InitXPCOM(XPCOMInitData&& aXPCOMInit,
|
void InitXPCOM(XPCOMInitData&& aXPCOMInit,
|
||||||
const mozilla::dom::ipc::StructuredCloneData& aInitialData);
|
const mozilla::dom::ipc::StructuredCloneData& aInitialData,
|
||||||
|
bool aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
void InitSharedUASheets(Maybe<base::SharedMemoryHandle>&& aHandle,
|
void InitSharedUASheets(Maybe<base::SharedMemoryHandle>&& aHandle,
|
||||||
uintptr_t aAddress);
|
uintptr_t aAddress);
|
||||||
@ -538,6 +539,7 @@ class ContentChild final : public PContentChild,
|
|||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
||||||
GetUntrustedModulesDataResolver&& aResolver);
|
GetUntrustedModulesDataResolver&& aResolver);
|
||||||
|
mozilla::ipc::IPCResult RecvUnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvSetXPCOMProcessAttributes(
|
mozilla::ipc::IPCResult RecvSetXPCOMProcessAttributes(
|
||||||
@ -545,7 +547,8 @@ class ContentChild final : public PContentChild,
|
|||||||
FullLookAndFeel&& aLookAndFeelData, SystemFontList&& aFontList,
|
FullLookAndFeel&& aLookAndFeelData, SystemFontList&& aFontList,
|
||||||
Maybe<base::SharedMemoryHandle>&& aSharedUASheetHandle,
|
Maybe<base::SharedMemoryHandle>&& aSharedUASheetHandle,
|
||||||
const uintptr_t& aSharedUASheetAddress,
|
const uintptr_t& aSharedUASheetAddress,
|
||||||
nsTArray<base::SharedMemoryHandle>&& aSharedFontListBlocks);
|
nsTArray<base::SharedMemoryHandle>&& aSharedFontListBlocks,
|
||||||
|
const bool& aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvProvideAnonymousTemporaryFile(
|
mozilla::ipc::IPCResult RecvProvideAnonymousTemporaryFile(
|
||||||
const uint64_t& aID, const FileDescOrError& aFD);
|
const uint64_t& aID, const FileDescOrError& aFD);
|
||||||
|
@ -2990,9 +2990,16 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
|
|||||||
sharedUASheetAddress = 0;
|
sharedUASheetAddress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isReadyForBackgroundProcessing = false;
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
|
isReadyForBackgroundProcessing = dllSvc->IsReadyForBackgroundProcessing();
|
||||||
|
#endif
|
||||||
|
|
||||||
Unused << SendSetXPCOMProcessAttributes(
|
Unused << SendSetXPCOMProcessAttributes(
|
||||||
xpcomInit, initialData, lnf, fontList, std::move(sharedUASheetHandle),
|
xpcomInit, initialData, lnf, fontList, std::move(sharedUASheetHandle),
|
||||||
sharedUASheetAddress, std::move(sharedFontListBlocks));
|
sharedUASheetAddress, std::move(sharedFontListBlocks),
|
||||||
|
isReadyForBackgroundProcessing);
|
||||||
|
|
||||||
ipc::WritableSharedMap* sharedData =
|
ipc::WritableSharedMap* sharedData =
|
||||||
nsFrameMessageManager::sParentProcessManager->SharedData();
|
nsFrameMessageManager::sParentProcessManager->SharedData();
|
||||||
|
@ -580,6 +580,13 @@ child:
|
|||||||
* to pull data from content processes.
|
* to pull data from content processes.
|
||||||
*/
|
*/
|
||||||
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to notifty a child process to start
|
||||||
|
* processing module loading events in UntrustedModulesProcessor.
|
||||||
|
* This should be called when the parent process has gone idle.
|
||||||
|
*/
|
||||||
|
async UnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -750,7 +757,8 @@ child:
|
|||||||
SystemFontList systemFontList,
|
SystemFontList systemFontList,
|
||||||
SharedMemoryHandle? sharedUASheetHandle,
|
SharedMemoryHandle? sharedUASheetHandle,
|
||||||
uintptr_t sharedUASheetAddress,
|
uintptr_t sharedUASheetAddress,
|
||||||
SharedMemoryHandle[] sharedFontListBlocks);
|
SharedMemoryHandle[] sharedFontListBlocks,
|
||||||
|
bool aIsStartingUp);
|
||||||
|
|
||||||
// Notify child that last-pb-context-exited notification was observed
|
// Notify child that last-pb-context-exited notification was observed
|
||||||
async LastPrivateDocShellDestroyed();
|
async LastPrivateDocShellDestroyed();
|
||||||
|
@ -38,7 +38,8 @@ protocol PRDD
|
|||||||
parent:
|
parent:
|
||||||
|
|
||||||
async Init(GfxVarUpdate[] vars, FileDescriptor? sandboxBroker,
|
async Init(GfxVarUpdate[] vars, FileDescriptor? sandboxBroker,
|
||||||
bool canRecordReleaseTelemetry);
|
bool canRecordReleaseTelemetry,
|
||||||
|
bool aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
async InitProfiler(Endpoint<PProfilerChild> endpoint);
|
async InitProfiler(Endpoint<PProfilerChild> endpoint);
|
||||||
|
|
||||||
@ -61,6 +62,13 @@ parent:
|
|||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to notifty a child process to start
|
||||||
|
* processing module loading events in UntrustedModulesProcessor.
|
||||||
|
* This should be called when the parent process has gone idle.
|
||||||
|
*/
|
||||||
|
async UnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
|
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
|
||||||
|
@ -59,7 +59,14 @@ bool RDDChild::Init() {
|
|||||||
|
|
||||||
nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
|
nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
|
||||||
|
|
||||||
SendInit(updates, brokerFd, Telemetry::CanRecordReleaseData());
|
bool isReadyForBackgroundProcessing = false;
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
|
isReadyForBackgroundProcessing = dllSvc->IsReadyForBackgroundProcessing();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SendInit(updates, brokerFd, Telemetry::CanRecordReleaseData(),
|
||||||
|
isReadyForBackgroundProcessing);
|
||||||
|
|
||||||
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
|
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
|
||||||
|
|
||||||
|
@ -124,7 +124,8 @@ void CGSShutdownServerConnections();
|
|||||||
|
|
||||||
mozilla::ipc::IPCResult RDDParent::RecvInit(
|
mozilla::ipc::IPCResult RDDParent::RecvInit(
|
||||||
nsTArray<GfxVarUpdate>&& vars, const Maybe<FileDescriptor>& aBrokerFd,
|
nsTArray<GfxVarUpdate>&& vars, const Maybe<FileDescriptor>& aBrokerFd,
|
||||||
const bool& aCanRecordReleaseTelemetry) {
|
const bool& aCanRecordReleaseTelemetry,
|
||||||
|
const bool& aIsReadyForBackgroundProcessing) {
|
||||||
for (const auto& var : vars) {
|
for (const auto& var : vars) {
|
||||||
gfxVars::ApplyUpdate(var);
|
gfxVars::ApplyUpdate(var);
|
||||||
}
|
}
|
||||||
@ -151,7 +152,7 @@ mozilla::ipc::IPCResult RDDParent::RecvInit(
|
|||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
if (aCanRecordReleaseTelemetry) {
|
if (aCanRecordReleaseTelemetry) {
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
dllSvc->StartUntrustedModulesProcessor(aIsReadyForBackgroundProcessing);
|
||||||
}
|
}
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@ -247,6 +248,14 @@ mozilla::ipc::IPCResult RDDParent::RecvGetUntrustedModulesData(
|
|||||||
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult RDDParent::RecvUnblockUntrustedModulesThread() {
|
||||||
|
if (nsCOMPtr<nsIObserverService> obs =
|
||||||
|
mozilla::services::GetObserverService()) {
|
||||||
|
obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
|
||||||
|
}
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RDDParent::RecvPreferenceUpdate(const Pref& aPref) {
|
mozilla::ipc::IPCResult RDDParent::RecvPreferenceUpdate(const Pref& aPref) {
|
||||||
|
@ -29,7 +29,8 @@ class RDDParent final : public PRDDParent {
|
|||||||
|
|
||||||
mozilla::ipc::IPCResult RecvInit(nsTArray<GfxVarUpdate>&& vars,
|
mozilla::ipc::IPCResult RecvInit(nsTArray<GfxVarUpdate>&& vars,
|
||||||
const Maybe<ipc::FileDescriptor>& aBrokerFd,
|
const Maybe<ipc::FileDescriptor>& aBrokerFd,
|
||||||
const bool& aCanRecordReleaseTelemetry);
|
const bool& aCanRecordReleaseTelemetry,
|
||||||
|
const bool& aIsReadyForBackgroundProcessing);
|
||||||
mozilla::ipc::IPCResult RecvInitProfiler(
|
mozilla::ipc::IPCResult RecvInitProfiler(
|
||||||
Endpoint<PProfilerChild>&& aEndpoint);
|
Endpoint<PProfilerChild>&& aEndpoint);
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ class RDDParent final : public PRDDParent {
|
|||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
||||||
GetUntrustedModulesDataResolver&& aResolver);
|
GetUntrustedModulesDataResolver&& aResolver);
|
||||||
|
mozilla::ipc::IPCResult RecvUnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref);
|
mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref);
|
||||||
mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref);
|
mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref);
|
||||||
|
@ -138,7 +138,7 @@ mozilla::ipc::IPCResult UtilityProcessChild::RecvInit(
|
|||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
if (aCanRecordReleaseTelemetry) {
|
if (aCanRecordReleaseTelemetry) {
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
dllSvc->StartUntrustedModulesProcessor(false);
|
||||||
}
|
}
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
|
@ -1318,7 +1318,7 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
|
|||||||
|
|
||||||
// Ensure that DLL Services are running
|
// Ensure that DLL Services are running
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
dllSvc->StartUntrustedModulesProcessor(true);
|
||||||
auto dllServicesDisable =
|
auto dllServicesDisable =
|
||||||
MakeScopeExit([&dllSvc]() { dllSvc->DisableFull(); });
|
MakeScopeExit([&dllSvc]() { dllSvc->DisableFull(); });
|
||||||
|
|
||||||
|
@ -85,6 +85,9 @@ struct SocketPorcessInitAttributes {
|
|||||||
bool mOffline;
|
bool mOffline;
|
||||||
bool mConnectivity;
|
bool mConnectivity;
|
||||||
bool mInitSandbox;
|
bool mInitSandbox;
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
bool mIsReadyForBackgroundProcessing;
|
||||||
|
#endif
|
||||||
FileDescriptor? mSandboxBroker;
|
FileDescriptor? mSandboxBroker;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -222,6 +225,13 @@ child:
|
|||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
async GetUntrustedModulesData() returns (UntrustedModulesData? data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to notifty a child process to start
|
||||||
|
* processing module loading events in UntrustedModulesProcessor.
|
||||||
|
* This should be called when the parent process has gone idle.
|
||||||
|
*/
|
||||||
|
async UnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
both:
|
both:
|
||||||
|
@ -169,11 +169,6 @@ bool SocketProcessChild::Init(base::ProcessId aParentPid,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
|
||||||
#endif // defined(XP_WIN)
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +223,12 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvInit(
|
|||||||
Unused << RecvInitLinuxSandbox(aAttributes.mSandboxBroker());
|
Unused << RecvInitLinuxSandbox(aAttributes.mSandboxBroker());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
|
dllSvc->StartUntrustedModulesProcessor(
|
||||||
|
aAttributes.mIsReadyForBackgroundProcessing());
|
||||||
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,6 +741,15 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvGetUntrustedModulesData(
|
|||||||
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
[aResolver](nsresult aReason) { aResolver(Nothing()); });
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult
|
||||||
|
SocketProcessChild::RecvUnblockUntrustedModulesThread() {
|
||||||
|
if (nsCOMPtr<nsIObserverService> obs =
|
||||||
|
mozilla::services::GetObserverService()) {
|
||||||
|
obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
|
||||||
|
}
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
@ -160,6 +160,7 @@ class SocketProcessChild final
|
|||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
mozilla::ipc::IPCResult RecvGetUntrustedModulesData(
|
||||||
GetUntrustedModulesDataResolver&& aResolver);
|
GetUntrustedModulesDataResolver&& aResolver);
|
||||||
|
mozilla::ipc::IPCResult RecvUnblockUntrustedModulesThread();
|
||||||
#endif // defined(XP_WIN)
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -176,6 +176,12 @@ void SocketProcessHost::InitAfterConnect(bool aSucceeded) {
|
|||||||
|
|
||||||
attributes.mInitSandbox() = false;
|
attributes.mInitSandbox() = false;
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
|
attributes.mIsReadyForBackgroundProcessing() =
|
||||||
|
dllSvc->IsReadyForBackgroundProcessing();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||||
if (GetEffectiveSocketProcessSandboxLevel() > 0) {
|
if (GetEffectiveSocketProcessSandboxLevel() > 0) {
|
||||||
auto policy = SandboxBrokerPolicyFactory::GetSocketProcessPolicy(
|
auto policy = SandboxBrokerPolicyFactory::GetSocketProcessPolicy(
|
||||||
|
@ -11,9 +11,13 @@
|
|||||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "mozilla/net/SocketProcessChild.h"
|
#include "mozilla/net/SocketProcessChild.h"
|
||||||
|
#include "mozilla/net/SocketProcessParent.h"
|
||||||
|
#include "mozilla/RDDChild.h"
|
||||||
#include "mozilla/RDDParent.h"
|
#include "mozilla/RDDParent.h"
|
||||||
|
#include "mozilla/RDDProcessManager.h"
|
||||||
#include "mozilla/ScopeExit.h"
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
@ -106,12 +110,14 @@ bool UntrustedModulesProcessor::IsSupportedProcessType() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
RefPtr<UntrustedModulesProcessor> UntrustedModulesProcessor::Create() {
|
RefPtr<UntrustedModulesProcessor> UntrustedModulesProcessor::Create(
|
||||||
|
bool aIsReadyForBackgroundProcessing) {
|
||||||
if (!IsSupportedProcessType()) {
|
if (!IsSupportedProcessType()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<UntrustedModulesProcessor> result(new UntrustedModulesProcessor());
|
RefPtr<UntrustedModulesProcessor> result(
|
||||||
|
new UntrustedModulesProcessor(aIsReadyForBackgroundProcessing));
|
||||||
return result.forget();
|
return result.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,14 +125,16 @@ NS_IMPL_ISUPPORTS(UntrustedModulesProcessor, nsIObserver)
|
|||||||
|
|
||||||
static const uint32_t kThreadTimeoutMS = 120000; // 2 minutes
|
static const uint32_t kThreadTimeoutMS = 120000; // 2 minutes
|
||||||
|
|
||||||
UntrustedModulesProcessor::UntrustedModulesProcessor()
|
UntrustedModulesProcessor::UntrustedModulesProcessor(
|
||||||
|
bool aIsReadyForBackgroundProcessing)
|
||||||
: mThread(new LazyIdleThread(kThreadTimeoutMS, "Untrusted Modules"_ns,
|
: mThread(new LazyIdleThread(kThreadTimeoutMS, "Untrusted Modules"_ns,
|
||||||
LazyIdleThread::ManualShutdown)),
|
LazyIdleThread::ManualShutdown)),
|
||||||
mUnprocessedMutex(
|
mUnprocessedMutex(
|
||||||
"mozilla::UntrustedModulesProcessor::mUnprocessedMutex"),
|
"mozilla::UntrustedModulesProcessor::mUnprocessedMutex"),
|
||||||
mModuleCacheMutex(
|
mModuleCacheMutex(
|
||||||
"mozilla::UntrustedModulesProcessor::mModuleCacheMutex"),
|
"mozilla::UntrustedModulesProcessor::mModuleCacheMutex"),
|
||||||
mAllowProcessing(true) {
|
mStatus(aIsReadyForBackgroundProcessing ? Status::Allowed
|
||||||
|
: Status::StartingUp) {
|
||||||
AddObservers();
|
AddObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,17 +142,22 @@ void UntrustedModulesProcessor::AddObservers() {
|
|||||||
nsCOMPtr<nsIObserverService> obsServ(services::GetObserverService());
|
nsCOMPtr<nsIObserverService> obsServ(services::GetObserverService());
|
||||||
obsServ->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
|
obsServ->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
|
||||||
obsServ->AddObserver(this, "xpcom-shutdown-threads", false);
|
obsServ->AddObserver(this, "xpcom-shutdown-threads", false);
|
||||||
|
obsServ->AddObserver(this, "unblock-untrusted-modules-thread", false);
|
||||||
if (XRE_IsContentProcess()) {
|
if (XRE_IsContentProcess()) {
|
||||||
obsServ->AddObserver(this, "content-child-will-shutdown", false);
|
obsServ->AddObserver(this, "content-child-will-shutdown", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UntrustedModulesProcessor::IsReadyForBackgroundProcessing() const {
|
||||||
|
return mStatus == Status::Allowed;
|
||||||
|
}
|
||||||
|
|
||||||
void UntrustedModulesProcessor::Disable() {
|
void UntrustedModulesProcessor::Disable() {
|
||||||
// Ensure that mThread cannot run at low priority anymore
|
// Ensure that mThread cannot run at low priority anymore
|
||||||
BackgroundPriorityRegion::Clear(mThread);
|
BackgroundPriorityRegion::Clear(mThread);
|
||||||
|
|
||||||
// No more background processing allowed beyond this point
|
// No more background processing allowed beyond this point
|
||||||
if (!mAllowProcessing.exchange(false)) {
|
if (mStatus.exchange(Status::ShuttingDown) != Status::Allowed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +184,37 @@ NS_IMETHODIMP UntrustedModulesProcessor::Observe(nsISupports* aSubject,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(aTopic, "unblock-untrusted-modules-thread")) {
|
||||||
|
nsCOMPtr<nsIObserverService> obs(services::GetObserverService());
|
||||||
|
obs->RemoveObserver(this, "unblock-untrusted-modules-thread");
|
||||||
|
|
||||||
|
mStatus.compareExchange(Status::StartingUp, Status::Allowed);
|
||||||
|
|
||||||
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
|
// If we're shutting down, stop here.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
// Propagate notification to child processes
|
||||||
|
nsTArray<dom::ContentParent*> contentProcesses;
|
||||||
|
dom::ContentParent::GetAll(contentProcesses);
|
||||||
|
for (auto* proc : contentProcesses) {
|
||||||
|
Unused << proc->SendUnblockUntrustedModulesThread();
|
||||||
|
}
|
||||||
|
if (auto* proc = net::SocketProcessParent::GetSingleton()) {
|
||||||
|
Unused << proc->SendUnblockUntrustedModulesThread();
|
||||||
|
}
|
||||||
|
if (auto* rddMgr = RDDProcessManager::Get()) {
|
||||||
|
if (auto* proc = rddMgr->GetRDDChild()) {
|
||||||
|
Unused << proc->SendUnblockUntrustedModulesThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_ASSERT_UNREACHABLE("Not reachable");
|
MOZ_ASSERT_UNREACHABLE("Not reachable");
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -180,6 +224,7 @@ void UntrustedModulesProcessor::RemoveObservers() {
|
|||||||
nsCOMPtr<nsIObserverService> obsServ(services::GetObserverService());
|
nsCOMPtr<nsIObserverService> obsServ(services::GetObserverService());
|
||||||
obsServ->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
|
obsServ->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
|
||||||
obsServ->RemoveObserver(this, "xpcom-shutdown-threads");
|
obsServ->RemoveObserver(this, "xpcom-shutdown-threads");
|
||||||
|
obsServ->RemoveObserver(this, "unblock-untrusted-modules-thread");
|
||||||
if (XRE_IsContentProcess()) {
|
if (XRE_IsContentProcess()) {
|
||||||
obsServ->RemoveObserver(this, "content-child-will-shutdown");
|
obsServ->RemoveObserver(this, "content-child-will-shutdown");
|
||||||
}
|
}
|
||||||
@ -204,7 +249,7 @@ void UntrustedModulesProcessor::ScheduleNonEmptyQueueProcessing(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +286,7 @@ void UntrustedModulesProcessor::CancelScheduledProcessing(
|
|||||||
void UntrustedModulesProcessor::DispatchBackgroundProcessing() {
|
void UntrustedModulesProcessor::DispatchBackgroundProcessing() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +299,7 @@ void UntrustedModulesProcessor::DispatchBackgroundProcessing() {
|
|||||||
|
|
||||||
void UntrustedModulesProcessor::Enqueue(
|
void UntrustedModulesProcessor::Enqueue(
|
||||||
glue::EnhancedModuleLoadInfo&& aModLoadInfo) {
|
glue::EnhancedModuleLoadInfo&& aModLoadInfo) {
|
||||||
if (!mAllowProcessing) {
|
if (mStatus == Status::ShuttingDown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +317,7 @@ void UntrustedModulesProcessor::Enqueue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UntrustedModulesProcessor::Enqueue(ModuleLoadInfoVec&& aEvents) {
|
void UntrustedModulesProcessor::Enqueue(ModuleLoadInfoVec&& aEvents) {
|
||||||
if (!mAllowProcessing) {
|
if (mStatus == Status::ShuttingDown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +360,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrust(
|
|||||||
ModulePaths&& aModPaths, bool aRunAtNormalPriority) {
|
ModulePaths&& aModPaths, bool aRunAtNormalPriority) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
|
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return ModulesTrustPromise::CreateAndReject(
|
return ModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -403,7 +448,7 @@ UntrustedModulesProcessor::GetProcessedDataInternalChildProcess() {
|
|||||||
self = std::move(self), source,
|
self = std::move(self), source,
|
||||||
whenProcessed = std::move(whenProcessed)]() {
|
whenProcessed = std::move(whenProcessed)]() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
if (!self->mAllowProcessing) {
|
if (!self->IsReadyForBackgroundProcessing()) {
|
||||||
// We can't do any more work, just reject all the things
|
// We can't do any more work, just reject all the things
|
||||||
whenProcessed->Then(
|
whenProcessed->Then(
|
||||||
GetMainThreadSerialEventTarget(), source,
|
GetMainThreadSerialEventTarget(), source,
|
||||||
@ -442,13 +487,13 @@ UntrustedModulesProcessor::GetProcessedDataInternalChildProcess() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueue() {
|
void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueue() {
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundPriorityRegion bgRgn;
|
BackgroundPriorityRegion bgRgn;
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +547,7 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() {
|
|||||||
self = std::move(self), source,
|
self = std::move(self), source,
|
||||||
whenProcessed = std::move(whenProcessed)]() {
|
whenProcessed = std::move(whenProcessed)]() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
if (!self->mAllowProcessing) {
|
if (!self->IsReadyForBackgroundProcessing()) {
|
||||||
// We can't do any more work, just no-op
|
// We can't do any more work, just no-op
|
||||||
whenProcessed->Then(
|
whenProcessed->Then(
|
||||||
GetMainThreadSerialEventTarget(), source,
|
GetMainThreadSerialEventTarget(), source,
|
||||||
@ -514,7 +559,7 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() {
|
|||||||
whenProcessed->Then(
|
whenProcessed->Then(
|
||||||
evtTarget, source,
|
evtTarget, source,
|
||||||
[self = std::move(self)](Maybe<ModulesMapResultWithLoads>&& aResult) {
|
[self = std::move(self)](Maybe<ModulesMapResultWithLoads>&& aResult) {
|
||||||
if (aResult.isNothing() || !self->mAllowProcessing) {
|
if (aResult.isNothing() || !self->IsReadyForBackgroundProcessing()) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -565,9 +610,9 @@ UntrustedModulesProcessor::ExtractLoadingEventsToProcess(size_t aMaxLength) {
|
|||||||
return loadsToProcess;
|
return loadsToProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function contains multiple |mAllowProcessing| checks so that we can
|
// This function contains multiple IsReadyForBackgroundProcessing() checks so
|
||||||
// quickly bail out at the first sign of shutdown. This may be important when
|
// that we can quickly bail out at the first sign of shutdown. This may be
|
||||||
// the current thread is running under background priority.
|
// important when the current thread is running under background priority.
|
||||||
void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
||||||
AssertRunningOnLazyIdleThread();
|
AssertRunningOnLazyIdleThread();
|
||||||
if (!XRE_IsParentProcess()) {
|
if (!XRE_IsParentProcess()) {
|
||||||
@ -577,7 +622,7 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
|
|
||||||
LoadsVec loadsToProcess =
|
LoadsVec loadsToProcess =
|
||||||
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
||||||
if (!mAllowProcessing || loadsToProcess.empty()) {
|
if (!IsReadyForBackgroundProcessing() || loadsToProcess.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +640,7 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
uint32_t trustTestFailures = 0;
|
uint32_t trustTestFailures = 0;
|
||||||
|
|
||||||
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +653,7 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +668,7 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,14 +684,14 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
mProcessedModuleLoads.mModules.LookupOrInsert(
|
mProcessedModuleLoads.mModules.LookupOrInsert(
|
||||||
event.mModule->mResolvedNtName, event.mModule);
|
event.mModule->mResolvedNtName, event.mModule);
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry::ProcessedStack processedStack =
|
Telemetry::ProcessedStack processedStack =
|
||||||
stackProcessor.GetStackAndModules(backtrace);
|
stackProcessor.GetStackAndModules(backtrace);
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +706,7 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,7 +786,7 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||||||
return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__);
|
return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return GetModulesTrustPromise::CreateAndReject(
|
return GetModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -750,7 +795,7 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||||||
|
|
||||||
// Build a set of modules to be processed by the parent
|
// Build a set of modules to be processed by the parent
|
||||||
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return GetModulesTrustPromise::CreateAndReject(
|
return GetModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -758,7 +803,7 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||||||
moduleNtPathSet.PutEntry(entry.mNtLoadInfo.mSectionName.AsString());
|
moduleNtPathSet.PutEntry(entry.mNtLoadInfo.mSectionName.AsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return GetModulesTrustPromise::CreateAndReject(
|
return GetModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -771,7 +816,7 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||||||
|
|
||||||
ModulePaths moduleNtPaths(std::move(moduleNtPathSet));
|
ModulePaths moduleNtPaths(std::move(moduleNtPathSet));
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return GetModulesTrustPromise::CreateAndReject(
|
return GetModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -787,7 +832,7 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||||||
RefPtr<GetModulesTrustPromise::Private> p(
|
RefPtr<GetModulesTrustPromise::Private> p(
|
||||||
new GetModulesTrustPromise::Private(__func__));
|
new GetModulesTrustPromise::Private(__func__));
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
p->Reject(NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
p->Reject(NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -815,7 +860,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
AssertRunningOnLazyIdleThread();
|
AssertRunningOnLazyIdleThread();
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,7 +882,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -850,7 +895,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
|
|
||||||
if (!modules.IsEmpty()) {
|
if (!modules.IsEmpty()) {
|
||||||
for (auto&& item : loads) {
|
for (auto&& item : loads) {
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,7 +905,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,7 +913,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
std::move(item.mNtLoadInfo.mBacktrace);
|
std::move(item.mNtLoadInfo.mBacktrace);
|
||||||
ProcessedModuleLoadEvent event(std::move(item), std::move(module));
|
ProcessedModuleLoadEvent event(std::move(item), std::move(module));
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +924,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,7 +935,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,7 +954,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,7 +976,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrustInternal(
|
|||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
AssertRunningOnLazyIdleThread();
|
AssertRunningOnLazyIdleThread();
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return ModulesTrustPromise::CreateAndReject(
|
return ModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -965,7 +1010,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrustInternal(
|
|||||||
|
|
||||||
for (auto& resolvedNtPath :
|
for (auto& resolvedNtPath :
|
||||||
aModPaths.mModuleNtPaths.as<ModulePaths::VecType>()) {
|
aModPaths.mModuleNtPaths.as<ModulePaths::VecType>()) {
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return ModulesTrustPromise::CreateAndReject(
|
return ModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -982,7 +1027,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrustInternal(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return ModulesTrustPromise::CreateAndReject(
|
return ModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
@ -993,7 +1038,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrustInternal(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAllowProcessing) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return ModulesTrustPromise::CreateAndReject(
|
return ModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,16 @@ using GetModulesTrustIpcPromise =
|
|||||||
|
|
||||||
class UntrustedModulesProcessor final : public nsIObserver {
|
class UntrustedModulesProcessor final : public nsIObserver {
|
||||||
public:
|
public:
|
||||||
static RefPtr<UntrustedModulesProcessor> Create();
|
static RefPtr<UntrustedModulesProcessor> Create(
|
||||||
|
bool aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
// Called to check if the parent process is ready when a child process
|
||||||
|
// is spanwed
|
||||||
|
bool IsReadyForBackgroundProcessing() const;
|
||||||
|
|
||||||
// Called by DLL Services to explicitly begin shutting down
|
// Called by DLL Services to explicitly begin shutting down
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
@ -65,7 +70,7 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
~UntrustedModulesProcessor() = default;
|
~UntrustedModulesProcessor() = default;
|
||||||
UntrustedModulesProcessor();
|
explicit UntrustedModulesProcessor(bool aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
static bool IsSupportedProcessType();
|
static bool IsSupportedProcessType();
|
||||||
|
|
||||||
@ -141,8 +146,10 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
|||||||
// This member must only be touched on mThread
|
// This member must only be touched on mThread
|
||||||
UntrustedModulesData mProcessedModuleLoads;
|
UntrustedModulesData mProcessedModuleLoads;
|
||||||
|
|
||||||
|
enum class Status { StartingUp, Allowed, ShuttingDown };
|
||||||
|
|
||||||
// This member may be touched by any thread
|
// This member may be touched by any thread
|
||||||
Atomic<bool> mAllowProcessing;
|
Atomic<Status> mStatus;
|
||||||
|
|
||||||
// Cache all module records, including ones trusted and ones loaded in
|
// Cache all module records, including ones trusted and ones loaded in
|
||||||
// child processes, in the browser process to avoid evaluating the same
|
// child processes, in the browser process to avoid evaluating the same
|
||||||
|
@ -59,10 +59,15 @@ DllServices* DllServices::Get() {
|
|||||||
|
|
||||||
DllServices::~DllServices() { DisableFull(); }
|
DllServices::~DllServices() { DisableFull(); }
|
||||||
|
|
||||||
void DllServices::StartUntrustedModulesProcessor() {
|
void DllServices::StartUntrustedModulesProcessor(bool aIsStartingUp) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(!mUntrustedModulesProcessor);
|
MOZ_ASSERT(!mUntrustedModulesProcessor);
|
||||||
mUntrustedModulesProcessor = UntrustedModulesProcessor::Create();
|
mUntrustedModulesProcessor = UntrustedModulesProcessor::Create(aIsStartingUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DllServices::IsReadyForBackgroundProcessing() const {
|
||||||
|
return mUntrustedModulesProcessor &&
|
||||||
|
mUntrustedModulesProcessor->IsReadyForBackgroundProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<UntrustedModulesPromise> DllServices::GetUntrustedModulesData() {
|
RefPtr<UntrustedModulesPromise> DllServices::GetUntrustedModulesData() {
|
||||||
|
@ -34,7 +34,8 @@ class DllServices final : public glue::DllServices {
|
|||||||
static const char* kTopicDllLoadedMainThread;
|
static const char* kTopicDllLoadedMainThread;
|
||||||
static const char* kTopicDllLoadedNonMainThread;
|
static const char* kTopicDllLoadedNonMainThread;
|
||||||
|
|
||||||
void StartUntrustedModulesProcessor();
|
void StartUntrustedModulesProcessor(bool aIsReadyForBackgroundProcessing);
|
||||||
|
bool IsReadyForBackgroundProcessing() const;
|
||||||
|
|
||||||
RefPtr<UntrustedModulesPromise> GetUntrustedModulesData();
|
RefPtr<UntrustedModulesPromise> GetUntrustedModulesData();
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ BOOL CALLBACK UntrustedModulesFixture::InitialModuleLoadOnce(PINIT_ONCE, void*,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<DllServices> dllSvc(DllServices::Get());
|
RefPtr<DllServices> dllSvc(DllServices::Get());
|
||||||
dllSvc->StartUntrustedModulesProcessor();
|
dllSvc->StartUntrustedModulesProcessor(true);
|
||||||
|
|
||||||
for (int i = 0; i < kLoadCountAfterDllServices; ++i) {
|
for (int i = 0; i < kLoadCountAfterDllServices; ++i) {
|
||||||
for (const auto& mod : kTestModules) {
|
for (const auto& mod : kTestModules) {
|
||||||
|
@ -5277,7 +5277,7 @@ nsresult XREMain::XRE_mainRun() {
|
|||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get());
|
RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get());
|
||||||
dllServices->StartUntrustedModulesProcessor();
|
dllServices->StartUntrustedModulesProcessor(false);
|
||||||
auto dllServicesDisable =
|
auto dllServicesDisable =
|
||||||
MakeScopeExit([&dllServices]() { dllServices->DisableFull(); });
|
MakeScopeExit([&dllServices]() { dllServices->DisableFull(); });
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user