Bug 1746114 - Part2. Collect the third-party modules ping from socket process. r=mhowell,necko-reviewers,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D133846
This commit is contained in:
Toshihito Kikuchi 2021-12-23 02:15:36 +00:00
parent 7d38851282
commit 66d4a1eb24
8 changed files with 121 additions and 36 deletions

View File

@ -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,

View File

@ -55,6 +55,8 @@
#if defined(XP_WIN)
# include <process.h>
# include "mozilla/WinDllServices.h"
#else
# include <unistd.h>
#endif
@ -176,6 +178,11 @@ bool SocketProcessChild::Init(base::ProcessId aParentPid,
return false;
}
#if defined(XP_WIN)
RefPtr<DllServices> 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<DllServices> dllSvc(DllServices::Get());
dllSvc->GetUntrustedModulesData()->Then(
GetMainThreadSerialEventTarget(), __func__,
[aResolver](Maybe<UntrustedModulesData>&& aData) {
aResolver(std::move(aData));
},
[aResolver](nsresult aReason) { aResolver(Nothing()); });
return IPC_OK();
}
#endif // defined(XP_WIN)
} // namespace net
} // namespace mozilla

View File

@ -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();

View File

@ -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<DllServices> 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

View File

@ -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<dom::MemoryReportRequestHost> mMemoryReportRequest;

View File

@ -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());

View File

@ -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<glue::EnhancedModuleLoadInfo> 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<ModulePaths::SetType>().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<glue::EnhancedModuleLoadInfo> 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__);

View File

@ -81,6 +81,11 @@ class UntrustedModulesProcessor final : public nsIObserver {
using LoadsVec = Vector<glue::EnhancedModuleLoadInfo>;
// 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<ModulesMapResult>&& aModMapResult,