Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Unified Diff: chrome/browser/prefs/pref_hash_store_impl.cc

Issue 126093007: Introduce a hash_of_hashes dictionary. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: histogram desc Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/prefs/pref_hash_store_impl.cc
diff --git a/chrome/browser/prefs/pref_hash_store_impl.cc b/chrome/browser/prefs/pref_hash_store_impl.cc
index ef698fc75fcef3ca1726764ae3cfe8e2f25fbe3e..2b62bac61fc473a789fbf5239a362afb384f4ec7 100644
--- a/chrome/browser/prefs/pref_hash_store_impl.cc
+++ b/chrome/browser/prefs/pref_hash_store_impl.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/prefs/pref_hash_store_impl.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
@@ -17,7 +18,11 @@ PrefHashStoreImpl::PrefHashStoreImpl(const std::string& hash_store_id,
PrefService* local_state)
: hash_store_id_(hash_store_id),
pref_hash_calculator_(seed, device_id),
- local_state_(local_state) {}
+ local_state_(local_state),
+ initial_hashes_dictionary_trusted_(IsHashDictionaryTrusted()) {
+ UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
+ initial_hashes_dictionary_trusted_);
+}
// static
void PrefHashStoreImpl::RegisterPrefs(PrefRegistrySimple* registry) {
@@ -35,42 +40,82 @@ PrefHashStore::ValueState PrefHashStoreImpl::CheckValue(
&hashed_prefs);
std::string last_hash;
- if (!hashed_prefs || !hashed_prefs->GetString(path, &last_hash))
- return PrefHashStore::UNKNOWN_VALUE;
+ if (!hashed_prefs || !hashed_prefs->GetString(path, &last_hash)) {
+ // In the absence of a hash for this pref, always trust a NULL value, but
+ // only trust an existing value if the initial hashes dictionary is trusted.
+ return (!initial_value || initial_hashes_dictionary_trusted_) ?
+ TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
+ }
PrefHashCalculator::ValidationResult validation_result =
pref_hash_calculator_.Validate(path, initial_value, last_hash);
switch (validation_result) {
case PrefHashCalculator::VALID:
- return PrefHashStore::UNCHANGED;
+ return UNCHANGED;
case PrefHashCalculator::VALID_LEGACY:
- return PrefHashStore::MIGRATED;
+ return MIGRATED;
case PrefHashCalculator::INVALID:
- return initial_value ? PrefHashStore::CHANGED : PrefHashStore::CLEARED;
+ return initial_value ? CHANGED : CLEARED;
}
NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: "
<< validation_result;
- return PrefHashStore::UNKNOWN_VALUE;
+ return UNTRUSTED_UNKNOWN_VALUE;
}
void PrefHashStoreImpl::StoreHash(
const std::string& path, const base::Value* new_value) {
{
DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes);
- base::DictionaryValue* child_dictionary = NULL;
// Get the dictionary corresponding to the profile name, which may have a
// '.'
+ base::DictionaryValue* hashes_dict = NULL;
if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_,
- &child_dictionary)) {
- child_dictionary = new base::DictionaryValue;
- update->SetWithoutPathExpansion(hash_store_id_, child_dictionary);
+ &hashes_dict)) {
+ hashes_dict = new base::DictionaryValue;
+ update->SetWithoutPathExpansion(hash_store_id_, hashes_dict);
}
- child_dictionary->SetString(
+ hashes_dict->SetString(
path, pref_hash_calculator_.Calculate(path, new_value));
+
+ // Get the dictionary where the hash of hashes are stored.
+ base::DictionaryValue* hash_of_hashes_dict = NULL;
+ if (!update->GetDictionaryWithoutPathExpansion(internals::kHashOfHashesPref,
+ &hash_of_hashes_dict)) {
+ hash_of_hashes_dict = new base::DictionaryValue;
+ update->SetWithoutPathExpansion(internals::kHashOfHashesPref,
+ hash_of_hashes_dict);
+ }
+ // Use the |hash_store_id_| as the hashed path to avoid having the hash
+ // depend on kProfilePreferenceHashes.
+ std::string hash_of_hashes(pref_hash_calculator_.Calculate(hash_store_id_,
+ hashes_dict));
+ hash_of_hashes_dict->SetStringWithoutPathExpansion(hash_store_id_,
+ hash_of_hashes);
}
// TODO(erikwright): During tests, pending writes were still waiting when the
// IO thread is already gone. Consider other solutions.
local_state_->CommitPendingWrite();
}
+
+bool PrefHashStoreImpl::IsHashDictionaryTrusted() const {
+ const base::DictionaryValue* pref_hash_dicts =
+ local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
+ const base::DictionaryValue* hashes_dict = NULL;
+ const base::DictionaryValue* hash_of_hashes_dict = NULL;
+ std::string hash_of_hashes;
+ // The absence of the hashes dictionary isn't trusted. Nor is the absence of
+ // the hash of hashes for this |hash_store_id_|.
+ if (!pref_hash_dicts->GetDictionaryWithoutPathExpansion(
+ hash_store_id_, &hashes_dict) ||
+ !pref_hash_dicts->GetDictionaryWithoutPathExpansion(
+ internals::kHashOfHashesPref, &hash_of_hashes_dict) ||
+ !hash_of_hashes_dict->GetStringWithoutPathExpansion(
+ hash_store_id_, &hash_of_hashes)) {
+ return false;
+ }
+
+ return pref_hash_calculator_.Validate(
+ hash_store_id_, hashes_dict, hash_of_hashes) == PrefHashCalculator::VALID;
+}

Powered by Google App Engine
This is Rietveld 408576698