/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
if (aResult.isSome()) {
mBackupSvc->Backup(std::move(aResult.ref()));
}
OnCompletion();
}
private: // Combinations of the flags defined under nsITelemetry. // (See "Flags for getUntrustedModuleLoadEvents" in nsITelemetry.idl)
uint32_t mFlags;
auto dynamicBlocklist = sharedSection->GetDynamicBlocklist(); for (constauto& blockedEntry : dynamicBlocklist) { if (!blockedEntry.IsValidDynamicBlocklistEntry()) { break;
}
blockedModules.AppendElement(
nsDependentSubstring(blockedEntry.mName.Buffer,
blockedEntry.mName.Length / sizeof(wchar_t)));
} return blockedModules;
} #endif
nsresult MultiGetUntrustedModulesData::SubmitToGlean() {
MOZ_ASSERT(mFlags == 0, "The Glean 'third-party-modules' ping doesn't know how to handle " "nsITelemetry's flags for getUntrustedModuleLoadEvents.");
const UntrustedModulesBackupData& stagingRef = mBackupSvc->Staging(); if (stagingRef.IsEmpty()) { return NS_OK;
}
glean::third_party_modules::ModulesObject modules;
glean::third_party_modules::ProcessesObject processes;
uint32_t modulesArrayIdx = 0; for (constauto& container : stagingRef.Values()) { if (!container) { continue;
} constauto& data = container->mData; // We are duplicating the module mapping that // UntrustedModulesDataSerializer::AddSingleData does because // 1) Accessing its mIndexMap at the correct time would be fragile. // 2) Decoupling data submission from JS serialization is arguably good.
nsTHashMap<nsStringHashKey, uint32_t> indexMap; for (constauto& entry : data.mModules) {
nsresult rv = NS_OK;
(void)indexMap.LookupOrInsertWith(entry.GetKey(), [&]() -> uint32_t { constauto record = entry.GetData(); if (!record) {
rv = NS_ERROR_FAILURE; return0;
}
glean::third_party_modules::ModulesObjectItem item;
item.resolvedDllName =
Some(NS_ConvertUTF16toUTF8(record->mSanitizedDllName)); if (record->mVersion.isSome()) { auto [major, minor, patch, build] = record->mVersion->AsTuple();
nsCString version;
version.AppendPrintf("%" PRIu16 ".%" PRIu16 ".%" PRIu16 ".%" PRIu16,
major, minor, patch, build);
item.fileVersion = Some(version);
} if (record->mVendorInfo.isSome()) {
MOZ_ASSERT(!record->mVendorInfo->mVendor.IsEmpty()); if (record->mVendorInfo->mVendor.IsEmpty()) { // Per `SerializeModule`, this is an error condition severe enough // to cease further processing.
rv = NS_ERROR_FAILURE; return0;
} switch (record->mVendorInfo->mSource) { case VendorInfo::Source::Signature:
item.signedBy =
Some(NS_ConvertUTF16toUTF8(record->mVendorInfo->mVendor)); break; case VendorInfo::Source::VersionInfo:
item.companyName =
Some(NS_ConvertUTF16toUTF8(record->mVendorInfo->mVendor)); break; default:
MOZ_ASSERT_UNREACHABLE("Unknown VendorInfo Source!");
rv = NS_ERROR_FAILURE; return0;
}
}
item.trustFlags = Some(static_cast<int64_t>(record->mTrustFlags));
modules.EmplaceBack(item); return modulesArrayIdx++;
});
if (modulesArrayIdx > kMaxModulesArrayLen) {
rv = NS_ERROR_CANNOT_CONVERT_DATA;
}
// UntrusteModulesDataSerializer::Add allows for multiple containers' data // to be for the same process (type and pid). // When that happens, the latest containers' data would take precedence. // By intuition, I don't think that happens so we don't need to worry. // And if it does, we'll get two items in the `processes` array: // analyses may merely take the latest one.
glean::third_party_modules::ProcessesObjectItem process{
.processType = Some(processType),
.sanitizationFailures = Some(data.mSanitizationFailures),
.trustTestFailures = Some(data.mTrustTestFailures),
};
uint32_t moduleIndex; if (!indexMap.Get(event.mModule->mResolvedNtName, &moduleIndex)) { // TODO: Should we instrument this somehow? continue;
}
eventItem.moduleIndex = Some(moduleIndex);
eventsArray.AppendElement(eventItem);
} if (eventsArray.Length()) {
process.events = Some(std::move(eventsArray));
}
nsresult rv; if (mFlags & nsITelemetry::INCLUDE_OLD_LOADEVENTS) { // When INCLUDE_OLD_LOADEVENTS is set, we need to return instances // from both "Staging" and "Settled" backup. if (mFlags & nsITelemetry::KEEP_LOADEVENTS_NEW) { // When INCLUDE_OLD_LOADEVENTS and KEEP_LOADEVENTS_NEW are set, we need to // return a JS object consisting of all instances from both "Staging" and // "Settled" backups, keeping instances in those backups as is. if (mFlags & nsITelemetry::EXCLUDE_STACKINFO_FROM_LOADEVENTS) { // Without the stack info, we can add multiple UntrustedModulesData to // the serializer directly.
rv = serializer.Add(mBackupSvc->Staging()); if (NS_WARN_IF(NS_FAILED(rv))) {
aPromise->MaybeReject(rv); return;
}
rv = serializer.Add(mBackupSvc->Settled()); if (NS_WARN_IF(NS_FAILED(rv))) {
aPromise->MaybeReject(rv); return;
}
} else { // Currently we don't have a method to merge UntrustedModulesData into // a serialized JS object because merging CombinedStack will be tricky. // Thus we return an error on this flag combination.
aPromise->MaybeReject(NS_ERROR_INVALID_ARG); return;
}
} else { // When KEEP_LOADEVENTS_NEW is not set, we can move data from "Staging" // to "Settled" first, then add "Settled" to the serializer.
mBackupSvc->SettleAllStagingData();
rv = serializer.Add(settledRef); if (NS_WARN_IF(NS_FAILED(rv))) {
aPromise->MaybeReject(rv); return;
}
}
} else { // When INCLUDE_OLD_LOADEVENTS is not set, we serialize only the "Staging" // into a JS object. const UntrustedModulesBackupData& stagingRef = mBackupSvc->Staging();
if (stagingRef.IsEmpty()) {
aPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE); return;
}
rv = serializer.Add(stagingRef); if (NS_WARN_IF(NS_FAILED(rv))) {
aPromise->MaybeReject(rv); return;
}
// When KEEP_LOADEVENTS_NEW is not set, we move all "Staging" instances // to the "Settled". if (!(mFlags & nsITelemetry::KEEP_LOADEVENTS_NEW)) {
mBackupSvc->SettleAllStagingData();
}
}
#ifdefined(XP_WIN)
nsTArray<nsDependentSubstring> blockedModules = GetBlockedModules(); if (!blockedModules.IsEmpty()) {
rv = serializer.AddBlockedModules(blockedModules); if (NS_WARN_IF(NS_FAILED(rv))) {
aPromise->MaybeReject(rv); return;
}
} #endif
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 und die Messung sind noch experimentell.