Index: base/metrics/persistent_histogram_allocator.cc |
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc |
index 5320d3fa45920353dc272d0a4fab3a376208673e..c6197873708f180fc4239f41f0b0995613a59765 100644 |
--- a/base/metrics/persistent_histogram_allocator.cc |
+++ b/base/metrics/persistent_histogram_allocator.cc |
@@ -38,6 +38,8 @@ enum : uint32_t { |
kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2 |
kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1 |
kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1 |
+ |
+ kTypeIdHistogramUnderConstruction = ~kTypeIdHistogram, |
}; |
// The current globally-active persistent allocator for all new histograms. |
@@ -274,8 +276,15 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram( |
memory_allocator_->GetAsObject<PersistentHistogramData>( |
ref, kTypeIdHistogram); |
size_t length = memory_allocator_->GetAllocSize(ref); |
+ |
+ // Check that metadata is reasonable: name is NUL terminated and non-empty, |
+ // ID fields have been loaded with a hash of the name (0 is considered |
+ // unset/invalid). |
if (!histogram_data || |
- reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') { |
+ reinterpret_cast<char*>(histogram_data)[length - 1] != '\0' || |
+ histogram_data->name[0] == '\0' || |
+ histogram_data->samples_metadata.id == 0 || |
+ histogram_data->logged_metadata.id == 0) { |
RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA); |
NOTREACHED(); |
return nullptr; |
@@ -302,14 +311,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( |
// Create the metadata necessary for a persistent sparse histogram. This |
// is done first because it is a small subset of what is required for |
- // other histograms. |
+ // other histograms. The type is "under construction" so that a crash |
+ // during the datafill doesn't leave a bad record around that could cause |
+ // confusion by another process trying to read it. It will be corrected |
+ // once histogram construction is complete. |
PersistentMemoryAllocator::Reference histogram_ref = |
memory_allocator_->Allocate( |
offsetof(PersistentHistogramData, name) + name.length() + 1, |
- kTypeIdHistogram); |
+ kTypeIdHistogramUnderConstruction); |
PersistentHistogramData* histogram_data = |
- memory_allocator_->GetAsObject<PersistentHistogramData>(histogram_ref, |
- kTypeIdHistogram); |
+ memory_allocator_->GetAsObject<PersistentHistogramData>( |
+ histogram_ref, kTypeIdHistogramUnderConstruction); |
if (histogram_data) { |
memcpy(histogram_data->name, name.c_str(), name.size() + 1); |
histogram_data->histogram_type = histogram_type; |
@@ -365,6 +377,11 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( |
// correct before commiting the new histogram to persistent space. |
std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data); |
DCHECK(histogram); |
+ DCHECK_NE(0U, histogram_data->samples_metadata.id); |
+ DCHECK_NE(0U, histogram_data->logged_metadata.id); |
+ memory_allocator_->ChangeType(histogram_ref, kTypeIdHistogram, |
+ kTypeIdHistogramUnderConstruction); |
+ |
if (ref_ptr != nullptr) |
*ref_ptr = histogram_ref; |