| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 // Memory space for histograms is determined by the max. ALWAYS ADD | 221 // Memory space for histograms is determined by the max. ALWAYS ADD |
| 222 // NEW VALUES BEFORE THIS ONE. | 222 // NEW VALUES BEFORE THIS ONE. |
| 223 PREFIX_SET_EVENT_MAX | 223 PREFIX_SET_EVENT_MAX |
| 224 }; | 224 }; |
| 225 | 225 |
| 226 void RecordPrefixSetInfo(PrefixSetEvent event_type) { | 226 void RecordPrefixSetInfo(PrefixSetEvent event_type) { |
| 227 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, | 227 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, |
| 228 PREFIX_SET_EVENT_MAX); | 228 PREFIX_SET_EVENT_MAX); |
| 229 } | 229 } |
| 230 | 230 |
| 231 // Verify that |GetPrefixes()| returns the same set of prefixes as | 231 // Generate a |PrefixSet| instance from the contents of |
| 232 // |prefixes|. This is necessary so that the | 232 // |add_prefixes|. Additionally performs various checks to make sure |
| 233 // that the resulting prefix set is valid, so that the |
| 233 // PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT_INVALID histogram in | 234 // PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT_INVALID histogram in |
| 234 // ContainsBrowseUrl() can be trustworthy. | 235 // ContainsBrowseUrl() can be trustworthy. |
| 235 void CheckPrefixSet(const safe_browsing::PrefixSet& prefix_set, | 236 safe_browsing::PrefixSet* PrefixSetFromAddPrefixes( |
| 236 const std::vector<SBPrefix>& prefixes) { | 237 const std::vector<SBAddPrefix>& add_prefixes) { |
| 238 // TODO(shess): If |add_prefixes| were sorted by the prefix, it |
| 239 // could be passed directly to |PrefixSet()|, removing the need for |
| 240 // |prefixes|. For now, |prefixes| is useful while debugging |
| 241 // things. |
| 242 std::vector<SBPrefix> prefixes; |
| 243 for (size_t i = 0; i < add_prefixes.size(); ++i) { |
| 244 prefixes.push_back(add_prefixes[i].prefix); |
| 245 } |
| 246 |
| 247 std::sort(prefixes.begin(), prefixes.end()); |
| 248 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), |
| 249 prefixes.end()); |
| 250 |
| 251 scoped_ptr<safe_browsing::PrefixSet> |
| 252 prefix_set(new safe_browsing::PrefixSet(prefixes)); |
| 253 |
| 237 std::vector<SBPrefix> restored; | 254 std::vector<SBPrefix> restored; |
| 238 prefix_set.GetPrefixes(&restored); | 255 prefix_set->GetPrefixes(&restored); |
| 239 | |
| 240 const std::set<SBPrefix> unique(prefixes.begin(), prefixes.end()); | |
| 241 | 256 |
| 242 // Expect them to be equal. | 257 // Expect them to be equal. |
| 243 if (restored.size() == unique.size() && | 258 if (restored.size() == prefixes.size() && |
| 244 std::equal(unique.begin(), unique.end(), restored.begin())) | 259 std::equal(prefixes.begin(), prefixes.end(), restored.begin())) |
| 245 return; | 260 return prefix_set.release(); |
| 246 | 261 |
| 247 // Log BROKEN for continuity with previous release, and SIZE to | 262 // Log BROKEN for continuity with previous release, and SIZE to |
| 248 // distinguish which test failed. | 263 // distinguish which test failed. |
| 249 NOTREACHED(); | 264 NOTREACHED(); |
| 250 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN); | 265 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN); |
| 251 if (restored.size() != unique.size()) | 266 if (restored.size() != prefixes.size()) |
| 252 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN_SIZE); | 267 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN_SIZE); |
| 253 | 268 |
| 254 // Try to distinguish between updates from one broken user and a | 269 // Try to distinguish between updates from one broken user and a |
| 255 // distributed problem. | 270 // distributed problem. |
| 256 static bool logged_broken = false; | 271 static bool logged_broken = false; |
| 257 if (!logged_broken) { | 272 if (!logged_broken) { |
| 258 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_FIRST_BROKEN); | 273 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_FIRST_BROKEN); |
| 259 logged_broken = true; | 274 logged_broken = true; |
| 260 } | 275 } |
| 261 | 276 |
| 262 // This seems so very very unlikely. But if it ever were true, then | 277 // This seems so very very unlikely. But if it ever were true, then |
| 263 // it could explain why GetPrefixes() seemed broken. | 278 // it could explain why GetPrefixes() seemed broken. |
| 264 if (sizeof(int) != sizeof(int32)) | 279 if (sizeof(int) != sizeof(int32)) |
| 265 RecordPrefixSetInfo(PREFIX_SET_SBPREFIX_WAS_BROKEN); | 280 RecordPrefixSetInfo(PREFIX_SET_SBPREFIX_WAS_BROKEN); |
| 281 |
| 282 return prefix_set.release(); |
| 266 } | 283 } |
| 267 | 284 |
| 268 } // namespace | 285 } // namespace |
| 269 | 286 |
| 270 // The default SafeBrowsingDatabaseFactory. | 287 // The default SafeBrowsingDatabaseFactory. |
| 271 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { | 288 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { |
| 272 public: | 289 public: |
| 273 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( | 290 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( |
| 274 bool enable_download_protection, | 291 bool enable_download_protection, |
| 275 bool enable_client_side_whitelist) { | 292 bool enable_client_side_whitelist) { |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 // Create and populate |filter| from |add_prefixes|. | 1015 // Create and populate |filter| from |add_prefixes|. |
| 999 // TODO(shess): The bloom filter doesn't need to be a | 1016 // TODO(shess): The bloom filter doesn't need to be a |
| 1000 // scoped_refptr<> for this code. Refactor that away. | 1017 // scoped_refptr<> for this code. Refactor that away. |
| 1001 const int filter_size = | 1018 const int filter_size = |
| 1002 BloomFilter::FilterSizeForKeyCount(add_prefixes.size()); | 1019 BloomFilter::FilterSizeForKeyCount(add_prefixes.size()); |
| 1003 scoped_refptr<BloomFilter> filter(new BloomFilter(filter_size)); | 1020 scoped_refptr<BloomFilter> filter(new BloomFilter(filter_size)); |
| 1004 for (size_t i = 0; i < add_prefixes.size(); ++i) { | 1021 for (size_t i = 0; i < add_prefixes.size(); ++i) { |
| 1005 filter->Insert(add_prefixes[i].prefix); | 1022 filter->Insert(add_prefixes[i].prefix); |
| 1006 } | 1023 } |
| 1007 | 1024 |
| 1008 std::vector<SBPrefix> prefixes; | |
| 1009 for (size_t i = 0; i < add_prefixes.size(); ++i) { | |
| 1010 prefixes.push_back(add_prefixes[i].prefix); | |
| 1011 } | |
| 1012 std::sort(prefixes.begin(), prefixes.end()); | |
| 1013 scoped_ptr<safe_browsing::PrefixSet> | 1025 scoped_ptr<safe_browsing::PrefixSet> |
| 1014 prefix_set(new safe_browsing::PrefixSet(prefixes)); | 1026 prefix_set(PrefixSetFromAddPrefixes(add_prefixes)); |
| 1015 | |
| 1016 CheckPrefixSet(*(prefix_set.get()), prefixes); | |
| 1017 | 1027 |
| 1018 // This needs to be in sorted order by prefix for efficient access. | 1028 // This needs to be in sorted order by prefix for efficient access. |
| 1019 std::sort(add_full_hashes.begin(), add_full_hashes.end(), | 1029 std::sort(add_full_hashes.begin(), add_full_hashes.end(), |
| 1020 SBAddFullHashPrefixLess); | 1030 SBAddFullHashPrefixLess); |
| 1021 | 1031 |
| 1022 // Swap in the newly built filter and cache. | 1032 // Swap in the newly built filter and cache. |
| 1023 { | 1033 { |
| 1024 base::AutoLock locked(lookup_lock_); | 1034 base::AutoLock locked(lookup_lock_); |
| 1025 full_browse_hashes_.swap(add_full_hashes); | 1035 full_browse_hashes_.swap(add_full_hashes); |
| 1026 | 1036 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 DVLOG(1) << "SafeBrowsingDatabaseNew read bloom filter in " | 1124 DVLOG(1) << "SafeBrowsingDatabaseNew read bloom filter in " |
| 1115 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | 1125 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; |
| 1116 | 1126 |
| 1117 if (!browse_bloom_filter_.get()) | 1127 if (!browse_bloom_filter_.get()) |
| 1118 RecordFailure(FAILURE_DATABASE_FILTER_READ); | 1128 RecordFailure(FAILURE_DATABASE_FILTER_READ); |
| 1119 | 1129 |
| 1120 // Manually re-generate the prefix set from the main database. | 1130 // Manually re-generate the prefix set from the main database. |
| 1121 // TODO(shess): Write/read for prefix set. | 1131 // TODO(shess): Write/read for prefix set. |
| 1122 std::vector<SBAddPrefix> add_prefixes; | 1132 std::vector<SBAddPrefix> add_prefixes; |
| 1123 browse_store_->GetAddPrefixes(&add_prefixes); | 1133 browse_store_->GetAddPrefixes(&add_prefixes); |
| 1124 std::vector<SBPrefix> prefixes; | 1134 prefix_set_.reset(PrefixSetFromAddPrefixes(add_prefixes)); |
| 1125 for (size_t i = 0; i < add_prefixes.size(); ++i) { | |
| 1126 prefixes.push_back(add_prefixes[i].prefix); | |
| 1127 } | |
| 1128 std::sort(prefixes.begin(), prefixes.end()); | |
| 1129 prefix_set_.reset(new safe_browsing::PrefixSet(prefixes)); | |
| 1130 CheckPrefixSet(*(prefix_set_.get()), prefixes); | |
| 1131 } | 1135 } |
| 1132 | 1136 |
| 1133 bool SafeBrowsingDatabaseNew::Delete() { | 1137 bool SafeBrowsingDatabaseNew::Delete() { |
| 1134 DCHECK_EQ(creation_loop_, MessageLoop::current()); | 1138 DCHECK_EQ(creation_loop_, MessageLoop::current()); |
| 1135 | 1139 |
| 1136 const bool r1 = browse_store_->Delete(); | 1140 const bool r1 = browse_store_->Delete(); |
| 1137 if (!r1) | 1141 if (!r1) |
| 1138 RecordFailure(FAILURE_DATABASE_STORE_DELETE); | 1142 RecordFailure(FAILURE_DATABASE_STORE_DELETE); |
| 1139 | 1143 |
| 1140 const bool r2 = download_store_.get() ? download_store_->Delete() : true; | 1144 const bool r2 = download_store_.get() ? download_store_->Delete() : true; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 if (std::binary_search(new_csd_whitelist.begin(), new_csd_whitelist.end(), | 1197 if (std::binary_search(new_csd_whitelist.begin(), new_csd_whitelist.end(), |
| 1194 kill_switch)) { | 1198 kill_switch)) { |
| 1195 // The kill switch is whitelisted hence we whitelist all URLs. | 1199 // The kill switch is whitelisted hence we whitelist all URLs. |
| 1196 CsdWhitelistAllUrls(); | 1200 CsdWhitelistAllUrls(); |
| 1197 } else { | 1201 } else { |
| 1198 base::AutoLock locked(lookup_lock_); | 1202 base::AutoLock locked(lookup_lock_); |
| 1199 csd_whitelist_all_urls_ = false; | 1203 csd_whitelist_all_urls_ = false; |
| 1200 csd_whitelist_.swap(new_csd_whitelist); | 1204 csd_whitelist_.swap(new_csd_whitelist); |
| 1201 } | 1205 } |
| 1202 } | 1206 } |
| OLD | NEW |