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 |