diff --git a/netwerk/ipc/PSocketProcess.ipdl b/netwerk/ipc/PSocketProcess.ipdl index 6062cd8371e9..7a98d3052c6c 100644 --- a/netwerk/ipc/PSocketProcess.ipdl +++ b/netwerk/ipc/PSocketProcess.ipdl @@ -50,6 +50,12 @@ using mozilla::net::SocketInfo from "mozilla/net/DashboardTypes.h"; using mozilla::net::DNSCacheEntries from "mozilla/net/DashboardTypes.h"; using mozilla::net::HttpRetParams from "mozilla/net/DashboardTypes.h"; +#if defined(XP_WIN) +[MoveOnly] using mozilla::UntrustedModulesData from "mozilla/UntrustedModulesData.h"; +[MoveOnly] using mozilla::ModulePaths from "mozilla/UntrustedModulesData.h"; +[MoveOnly] using mozilla::ModulesMapResult from "mozilla/UntrustedModulesData.h"; +#endif // defined(XP_WIN) + namespace mozilla { namespace net { @@ -147,6 +153,11 @@ parent: // https://firefox-source-docs.mozilla.org/toolkit/components/glean/dev/ipc.html async FOGData(ByteBuf buf); +#if defined(XP_WIN) + async GetModulesTrust(ModulePaths aModPaths, bool aRunAtNormalPriority) + returns (ModulesMapResult? modMapResult); +#endif // defined(XP_WIN) + child: async Init(SocketPorcessInitAttributes aAttributes); async PreferenceUpdate(Pref pref); @@ -207,6 +218,10 @@ child: // The unused returned value is to have a promise we can await. async TestTriggerMetrics() returns (bool unused); +#if defined(XP_WIN) + async GetUntrustedModulesData() returns (UntrustedModulesData? data); +#endif // defined(XP_WIN) + both: async PFileDescriptorSet(FileDescriptor fd); async PDNSRequest(nsCString hostName, nsCString trrServer, uint16_t type, diff --git a/netwerk/ipc/SocketProcessChild.cpp b/netwerk/ipc/SocketProcessChild.cpp index 482a7b17569c..4c0d0fc59a2c 100644 --- a/netwerk/ipc/SocketProcessChild.cpp +++ b/netwerk/ipc/SocketProcessChild.cpp @@ -55,6 +55,8 @@ #if defined(XP_WIN) # include + +# include "mozilla/WinDllServices.h" #else # include #endif @@ -176,6 +178,11 @@ bool SocketProcessChild::Init(base::ProcessId aParentPid, return false; } +#if defined(XP_WIN) + RefPtr dllSvc(DllServices::Get()); + dllSvc->StartUntrustedModulesProcessor(); +#endif // defined(XP_WIN) + return true; } @@ -694,5 +701,19 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvTestTriggerMetrics( return IPC_OK(); } +#if defined(XP_WIN) +mozilla::ipc::IPCResult SocketProcessChild::RecvGetUntrustedModulesData( + GetUntrustedModulesDataResolver&& aResolver) { + RefPtr dllSvc(DllServices::Get()); + dllSvc->GetUntrustedModulesData()->Then( + GetMainThreadSerialEventTarget(), __func__, + [aResolver](Maybe&& aData) { + aResolver(std::move(aData)); + }, + [aResolver](nsresult aReason) { aResolver(Nothing()); }); + return IPC_OK(); +} +#endif // defined(XP_WIN) + } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/SocketProcessChild.h b/netwerk/ipc/SocketProcessChild.h index 4771ee0f4cc0..23f2ecc8c7c6 100644 --- a/netwerk/ipc/SocketProcessChild.h +++ b/netwerk/ipc/SocketProcessChild.h @@ -153,6 +153,11 @@ class SocketProcessChild final mozilla::ipc::IPCResult RecvTestTriggerMetrics( TestTriggerMetricsResolver&& aResolve); +#if defined(XP_WIN) + mozilla::ipc::IPCResult RecvGetUntrustedModulesData( + GetUntrustedModulesDataResolver&& aResolver); +#endif // defined(XP_WIN) + protected: friend class SocketProcessImpl; ~SocketProcessChild(); diff --git a/netwerk/ipc/SocketProcessParent.cpp b/netwerk/ipc/SocketProcessParent.cpp index a2606e99a94a..e4476547163d 100644 --- a/netwerk/ipc/SocketProcessParent.cpp +++ b/netwerk/ipc/SocketProcessParent.cpp @@ -42,6 +42,9 @@ # include "mozilla/java/GeckoProcessManagerWrappers.h" # include "mozilla/java/GeckoProcessTypeWrappers.h" #endif // defined(MOZ_WIDGET_ANDROID) +#if defined(XP_WIN) +# include "mozilla/WinDllServices.h" +#endif namespace mozilla { namespace net { @@ -475,5 +478,21 @@ mozilla::ipc::IPCResult SocketProcessParent::RecvFOGData(ByteBuf&& aBuf) { return IPC_OK(); } +#if defined(XP_WIN) +mozilla::ipc::IPCResult SocketProcessParent::RecvGetModulesTrust( + ModulePaths&& aModPaths, bool aRunAtNormalPriority, + GetModulesTrustResolver&& aResolver) { + RefPtr dllSvc(DllServices::Get()); + dllSvc->GetModulesTrust(std::move(aModPaths), aRunAtNormalPriority) + ->Then( + GetMainThreadSerialEventTarget(), __func__, + [aResolver](ModulesMapResult&& aResult) { + aResolver(Some(ModulesMapResult(std::move(aResult)))); + }, + [aResolver](nsresult aRv) { aResolver(Nothing()); }); + return IPC_OK(); +} +#endif // defined(XP_WIN) + } // namespace net } // namespace mozilla diff --git a/netwerk/ipc/SocketProcessParent.h b/netwerk/ipc/SocketProcessParent.h index 739f3fa88f05..14bdeca8134f 100644 --- a/netwerk/ipc/SocketProcessParent.h +++ b/netwerk/ipc/SocketProcessParent.h @@ -133,6 +133,12 @@ class SocketProcessParent final mozilla::ipc::IPCResult RecvFOGData(ByteBuf&& aBuf); +#if defined(XP_WIN) + mozilla::ipc::IPCResult RecvGetModulesTrust( + ModulePaths&& aModPaths, bool aRunAtNormalPriority, + GetModulesTrustResolver&& aResolver); +#endif // defined(XP_WIN) + private: SocketProcessHost* mHost; UniquePtr mMemoryReportRequest; diff --git a/toolkit/components/telemetry/other/UntrustedModules.cpp b/toolkit/components/telemetry/other/UntrustedModules.cpp index db77ad8e9615..d0e8545a9a15 100644 --- a/toolkit/components/telemetry/other/UntrustedModules.cpp +++ b/toolkit/components/telemetry/other/UntrustedModules.cpp @@ -8,6 +8,7 @@ #include "mozilla/dom/ContentParent.h" #include "mozilla/MozPromise.h" +#include "mozilla/net/SocketProcessParent.h" #include "mozilla/RDDChild.h" #include "mozilla/RDDProcessManager.h" #include "mozilla/WinDllServices.h" @@ -131,6 +132,10 @@ MultiGetUntrustedModulesData::GetUntrustedModuleLoadEvents() { AddPending(contentParent->SendGetUntrustedModulesData()); } + if (auto* socketActor = net::SocketProcessParent::GetSingleton()) { + AddPending(socketActor->SendGetUntrustedModulesData()); + } + if (RDDProcessManager* rddMgr = RDDProcessManager::Get()) { if (RDDChild* rddChild = rddMgr->GetRDDChild()) { AddPending(rddChild->SendGetUntrustedModulesData()); diff --git a/toolkit/xre/dllservices/UntrustedModulesProcessor.cpp b/toolkit/xre/dllservices/UntrustedModulesProcessor.cpp index 084aa6680f2b..3eee709325b5 100644 --- a/toolkit/xre/dllservices/UntrustedModulesProcessor.cpp +++ b/toolkit/xre/dllservices/UntrustedModulesProcessor.cpp @@ -12,6 +12,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/Likely.h" +#include "mozilla/net/SocketProcessChild.h" #include "mozilla/RDDParent.h" #include "mozilla/ScopeExit.h" #include "mozilla/Services.h" @@ -92,6 +93,7 @@ bool UntrustedModulesProcessor::IsSupportedProcessType() { switch (XRE_GetProcessType()) { case GeckoProcessType_Default: case GeckoProcessType_Content: + case GeckoProcessType_Socket: return Telemetry::CanRecordReleaseData(); case GeckoProcessType_RDD: // For RDD process, we check the telemetry settings in RDDChild::Init() @@ -538,6 +540,36 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() { MOZ_ASSERT(NS_SUCCEEDED(rv)); } +UntrustedModulesProcessor::LoadsVec +UntrustedModulesProcessor::ExtractLoadingEventsToProcess(size_t aMaxLength) { + LoadsVec loadsToProcess; + + MutexAutoLock lock(mUnprocessedMutex); + CancelScheduledProcessing(lock); + + // The potential size of mProcessedModuleLoads if all of the unprocessed + // events are from third-party modules. + const size_t newDataLength = + mProcessedModuleLoads.mEvents.length() + mUnprocessedModuleLoads.length(); + if (newDataLength <= aMaxLength) { + loadsToProcess.swap(mUnprocessedModuleLoads); + } else { + // To prevent mProcessedModuleLoads from exceeding |aMaxLength|, + // we process the first items in the mUnprocessedModuleLoads, + // leaving the the remaining events for the next time. + const size_t capacity = + aMaxLength > mProcessedModuleLoads.mEvents.length() + ? (aMaxLength - mProcessedModuleLoads.mEvents.length()) + : 0; + auto moveRangeBegin = mUnprocessedModuleLoads.begin(); + auto moveRangeEnd = moveRangeBegin + capacity; + Unused << loadsToProcess.moveAppend(moveRangeBegin, moveRangeEnd); + mUnprocessedModuleLoads.erase(moveRangeBegin, moveRangeEnd); + } + + return loadsToProcess; +} + // This function contains multiple |mAllowProcessing| checks so that we can // quickly bail out at the first sign of shutdown. This may be important when // the current thread is running under background priority. @@ -548,34 +580,8 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() { return; } - Vector loadsToProcess; - - { // Scope for lock - MutexAutoLock lock(mUnprocessedMutex); - CancelScheduledProcessing(lock); - - // The potential size of mProcessedModuleLoads if all of the unprocessed - // events are from third-party modules. - const size_t newDataLength = mProcessedModuleLoads.mEvents.length() + - mUnprocessedModuleLoads.length(); - if (newDataLength <= UntrustedModulesData::kMaxEvents) { - loadsToProcess.swap(mUnprocessedModuleLoads); - } else { - // To prevent mProcessedModuleLoads from exceeding |kMaxEvents|, - // we process the first items in the mUnprocessedModuleLoads, - // leaving the the remaining events for the next time. - const size_t capacity = UntrustedModulesData::kMaxEvents > - mProcessedModuleLoads.mEvents.length() - ? (UntrustedModulesData::kMaxEvents - - mProcessedModuleLoads.mEvents.length()) - : 0; - auto moveRangeBegin = mUnprocessedModuleLoads.begin(); - auto moveRangeEnd = moveRangeBegin + capacity; - Unused << loadsToProcess.moveAppend(moveRangeBegin, moveRangeEnd); - mUnprocessedModuleLoads.erase(moveRangeBegin, moveRangeEnd); - } - } - + LoadsVec loadsToProcess = + ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents); if (!mAllowProcessing || loadsToProcess.empty()) { return; } @@ -695,6 +701,15 @@ UntrustedModulesProcessor::SendGetModulesTrust(ModulePaths&& aModules, return ::mozilla::SendGetModulesTrust(RDDParent::GetSingleton(), std::move(aModules), runNormal); } + case GeckoProcessType_Socket: { + printf_stderr( + "!!!! UntrustedModulesProcessor::SendGetModulesTrust for Socket - " + "%llu\n", + aModules.mModuleNtPaths.as().Count()); + return ::mozilla::SendGetModulesTrust( + net::SocketProcessChild::GetSingleton(), std::move(aModules), + runNormal); + } default: { MOZ_ASSERT_UNREACHABLE("Unsupported process type"); return GetModulesTrustIpcPromise::CreateAndReject( @@ -723,14 +738,8 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess( AssertRunningOnLazyIdleThread(); MOZ_ASSERT(!XRE_IsParentProcess()); - Vector loadsToProcess; - - { // Scope for lock - MutexAutoLock lock(mUnprocessedMutex); - CancelScheduledProcessing(lock); - loadsToProcess.swap(mUnprocessedModuleLoads); - } - + LoadsVec loadsToProcess = + ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents); if (loadsToProcess.empty()) { // Nothing to process return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__); diff --git a/toolkit/xre/dllservices/UntrustedModulesProcessor.h b/toolkit/xre/dllservices/UntrustedModulesProcessor.h index 2bd3329ff280..a604186c1ba3 100644 --- a/toolkit/xre/dllservices/UntrustedModulesProcessor.h +++ b/toolkit/xre/dllservices/UntrustedModulesProcessor.h @@ -81,6 +81,11 @@ class UntrustedModulesProcessor final : public nsIObserver { using LoadsVec = Vector; + // Extract the loading events from mUnprocessedModuleLoads to process and + // move to mProcessedModuleLoads. It's guaranteed that the total length of + // mProcessedModuleLoads will not exceed |aMaxLength|. + LoadsVec ExtractLoadingEventsToProcess(size_t aMaxLength); + class ModulesMapResultWithLoads final { public: ModulesMapResultWithLoads(Maybe&& aModMapResult,