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

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_database.cc

Issue 10834045: Instrument to catch corruption constructing safe-browsing filters. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 4 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/safe_browsing/prefix_set.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 // - Any prefix set hit should be a bloom filter hit. 235 // - Any prefix set hit should be a bloom filter hit.
236 // - Bloom filter false positives are prefix set misses. 236 // - Bloom filter false positives are prefix set misses.
237 // The following is to log actual performance to verify this. 237 // The following is to log actual performance to verify this.
238 enum PrefixSetEvent { 238 enum PrefixSetEvent {
239 // Hits to prefix set and bloom filter. 239 // Hits to prefix set and bloom filter.
240 PREFIX_SET_HIT, 240 PREFIX_SET_HIT,
241 PREFIX_SET_BLOOM_HIT, 241 PREFIX_SET_BLOOM_HIT,
242 // These were to track bloom misses which hit the prefix set, with 242 // These were to track bloom misses which hit the prefix set, with
243 // _INVALID to track where the item didn't appear to actually be in 243 // _INVALID to track where the item didn't appear to actually be in
244 // the prefix set. _INVALID was never hit. 244 // the prefix set. _INVALID was never hit.
245 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT, 245 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT_OBSOLETE,
246 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT_INVALID_OBSOLETE, 246 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT_INVALID_OBSOLETE,
247 // GetPrefixes() after creation failed to get the same prefixes. 247 // GetPrefixes() after creation failed to get the same prefixes.
248 PREFIX_SET_GETPREFIXES_BROKEN, 248 PREFIX_SET_GETPREFIXES_BROKEN,
249 // Fine-grained tests which didn't provide any good direction. 249 // Fine-grained tests which didn't provide any good direction.
250 PREFIX_SET_GETPREFIXES_BROKEN_SIZE_OBSOLETE, 250 PREFIX_SET_GETPREFIXES_BROKEN_SIZE_OBSOLETE,
251 PREFIX_SET_GETPREFIXES_FIRST_BROKEN_OBSOLETE, 251 PREFIX_SET_GETPREFIXES_FIRST_BROKEN_OBSOLETE,
252 PREFIX_SET_SBPREFIX_WAS_BROKEN_OBSOLETE, 252 PREFIX_SET_SBPREFIX_WAS_BROKEN_OBSOLETE,
253 PREFIX_SET_GETPREFIXES_BROKEN_SORTING_OBSOLETE, 253 PREFIX_SET_GETPREFIXES_BROKEN_SORTING_OBSOLETE,
254 PREFIX_SET_GETPREFIXES_BROKEN_DUPLICATION_OBSOLETE, 254 PREFIX_SET_GETPREFIXES_BROKEN_DUPLICATION_OBSOLETE,
255 PREFIX_SET_GETPREFIXES_UNSORTED_IS_DELTA_OBSOLETE, 255 PREFIX_SET_GETPREFIXES_UNSORTED_IS_DELTA_OBSOLETE,
256 PREFIX_SET_GETPREFIXES_UNSORTED_IS_INDEX_OBSOLETE, 256 PREFIX_SET_GETPREFIXES_UNSORTED_IS_INDEX_OBSOLETE,
257 // Failed checksum when creating prefix set. 257 // Failed checksums when creating filters.
258 PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM, 258 PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM,
259 PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM,
260 PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM,
261 PREFIX_SET_CREATE_PREFIXES_CHECKSUM,
262 PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM,
263 // Failed checksums when probing the filters.
264 PREFIX_SET_MISMATCH_PREFIX_SET_CHECKSUM,
265 PREFIX_SET_MISMATCH_BLOOM_FILTER_CHECKSUM,
266
267 // Recorded once per update if the impossible occurs.
268 PREFIX_SET_BLOOM_MISS_PREFIX_HIT,
259 269
260 // Memory space for histograms is determined by the max. ALWAYS ADD 270 // Memory space for histograms is determined by the max. ALWAYS ADD
261 // NEW VALUES BEFORE THIS ONE. 271 // NEW VALUES BEFORE THIS ONE.
262 PREFIX_SET_EVENT_MAX 272 PREFIX_SET_EVENT_MAX
263 }; 273 };
264 274
265 void RecordPrefixSetInfo(PrefixSetEvent event_type) { 275 void RecordPrefixSetInfo(PrefixSetEvent event_type) {
266 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, 276 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type,
267 PREFIX_SET_EVENT_MAX); 277 PREFIX_SET_EVENT_MAX);
268 } 278 }
269 279
270 // Helper to reduce code duplication. 280 // Helper to reduce code duplication.
271 safe_browsing::PrefixSet* CreateEmptyPrefixSet() { 281 safe_browsing::PrefixSet* CreateEmptyPrefixSet() {
272 return new safe_browsing::PrefixSet(std::vector<SBPrefix>()); 282 return new safe_browsing::PrefixSet(std::vector<SBPrefix>());
273 } 283 }
274 284
275 // Generate a |PrefixSet| instance from the contents of 285 // Generate xor "checksum" of SBPrefix part of add prefixes. Pass 0
276 // |add_prefixes|. Additionally performs various checks to make sure 286 // for |seed| will return a checksum, passing a previous checksum for
277 // that the resulting prefix set is valid, so that histograms in 287 // |seed| will return 0 (if it checks out). Coded this way in hopes
278 // ContainsBrowseUrl() can be trustworthy. 288 // that the compiler won't optimize separate runs into a single
279 safe_browsing::PrefixSet* PrefixSetFromAddPrefixes( 289 // temporary.
280 const SBAddPrefixes& add_prefixes) { 290 SBPrefix ChecksumAddPrefixes(SBPrefix seed,
291 const SBAddPrefixes& add_prefixes) {
292 SBPrefix checksum = seed;
293 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin();
294 iter != add_prefixes.end(); ++iter) {
295 checksum ^= iter->prefix;
296 }
297 return checksum;
298 }
299
300 // Generate xor "checksum" of prefixes.
301 SBPrefix ChecksumPrefixes(SBPrefix seed,
302 const std::vector<SBPrefix>& prefixes) {
303 SBPrefix checksum = seed;
304 for (std::vector<SBPrefix>::const_iterator iter = prefixes.begin();
305 iter != prefixes.end(); ++iter) {
306 checksum ^= *iter;
307 }
308 return checksum;
309 }
310
311 // Prefix set doesn't store duplicates, making it hard to verify that
312 // checksums match. Also hard is verifying that nothing was corrupted
313 // while removing duplicates from a vector. So this generates a
314 // checksum of only the unique elements.
315 SBPrefix ChecksumUniquePrefixes(const std::vector<SBPrefix>& prefixes) {
316 // Handle edge case up front.
317 if (prefixes.size() == 0)
318 return 0;
319
320 std::vector<SBPrefix>::const_iterator iter = prefixes.begin();
321 SBPrefix checksum = *iter++;
322 while (iter != prefixes.end()) {
323 if (*(iter - 1) != *iter)
324 checksum ^= *iter;
325 iter++;
326 }
327 return checksum;
328 }
329
330 // NOTE(shess): Past histograms have indicated that in a given day,
331 // about 1 in 100,000 updates result in a PrefixSet which was
332 // inconsistent relative to the BloomFilter. Windows is about 5x more
333 // likely to build an inconsistent PrefixSet than Mac. A number of
334 // developers have reviewed the code, and I ran extensive fuzzing with
335 // random data, so at this point I'm trying to demonstrate memory
336 // corruption.
337 //
338 // Other findings from past instrumentation:
339 // - half of one percent of brokenness cases implied duplicate items
340 // in |prefixes|. Per the code above, this should not be possible.
341 // - about 1/20 of broken cases happened more than once for a given
342 // user. Note that empty updates generally don't hit this code at
343 // all, so that may not imply a specific input pattern breaking
344 // things.
345 // - about 1/3 of broken cases show a checksum mismatch between the
346 // checksum calculated while creating |prefix_set| and the checksum
347 // calculated immediately after creation. This is almost certainly
348 // memory corruption.
349
350 // Generate |PrefixSet| and |BloomFilter| instances from the contents
351 // of |add_prefixes|. Verify that the results are internally
352 // consistent, and that the input maintained consistence while
353 // constructing (which should assure that they are mutually
354 // consistent). Returns an empty prefix set if any of the checks
355 // fail.
356 void FiltersFromAddPrefixes(
357 const SBAddPrefixes& add_prefixes,
358 scoped_refptr<BloomFilter>* bloom_filter,
359 scoped_ptr<safe_browsing::PrefixSet>* prefix_set) {
360 const int filter_size =
361 BloomFilter::FilterSizeForKeyCount(add_prefixes.size());
362 *bloom_filter = new BloomFilter(filter_size);
363 if (add_prefixes.empty()) {
364 prefix_set->reset(CreateEmptyPrefixSet());
365 return;
366 }
367
368 const SBPrefix add_prefixes_checksum = ChecksumAddPrefixes(0, add_prefixes);
369
281 // TODO(shess): If |add_prefixes| were sorted by the prefix, it 370 // TODO(shess): If |add_prefixes| were sorted by the prefix, it
282 // could be passed directly to |PrefixSet()|, removing the need for 371 // could be passed directly to |PrefixSet()|, removing the need for
283 // |prefixes|. For now, |prefixes| is useful while debugging 372 // |prefixes|.
284 // things.
285 std::vector<SBPrefix> prefixes; 373 std::vector<SBPrefix> prefixes;
286 prefixes.reserve(add_prefixes.size()); 374 prefixes.reserve(add_prefixes.size());
287 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin(); 375 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin();
288 iter != add_prefixes.end(); ++iter) { 376 iter != add_prefixes.end(); ++iter) {
289 prefixes.push_back(iter->prefix); 377 prefixes.push_back(iter->prefix);
290 } 378 }
379 std::sort(prefixes.begin(), prefixes.end());
291 380
292 std::sort(prefixes.begin(), prefixes.end()); 381 const SBPrefix unique_prefixes_checksum = ChecksumUniquePrefixes(prefixes);
293 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()),
294 prefixes.end());
295 382
296 scoped_ptr<safe_browsing::PrefixSet> 383 for (std::vector<SBPrefix>::const_iterator iter = prefixes.begin();
297 prefix_set(new safe_browsing::PrefixSet(prefixes)); 384 iter != prefixes.end(); ++iter) {
385 bloom_filter->get()->Insert(*iter);
386 }
298 387
299 std::vector<SBPrefix> restored; 388 prefix_set->reset(new safe_browsing::PrefixSet(prefixes));
300 prefix_set->GetPrefixes(&restored);
301 389
302 // Expect them to be equal. 390 // "unit test" for ChecksumUniquePrefixes() and GetPrefixesChecksum().
303 if (restored.size() == prefixes.size() && 391 if (DCHECK_IS_ON()) {
304 std::equal(prefixes.begin(), prefixes.end(), restored.begin())) 392 std::vector<SBPrefix> unique(prefixes);
305 return prefix_set.release(); 393 unique.erase(std::unique(unique.begin(), unique.end()), unique.end());
394 DCHECK_EQ(0, ChecksumPrefixes(unique_prefixes_checksum, unique));
306 395
307 // NOTE(shess): Past histograms have indicated that in a given day, 396 std::vector<SBPrefix> restored;
308 // about 1 in 100,000 updates result in a PrefixSet which was 397 prefix_set->get()->GetPrefixes(&restored);
309 // inconsistent relative to the BloomFilter. Windows is about 5x 398 DCHECK_EQ(0, ChecksumPrefixes(prefix_set->get()->GetPrefixesChecksum(),
310 // more likely to build an inconsistent PrefixSet than Mac. A 399 restored));
311 // number of developers have reviewed the code, and I ran extensive 400 }
312 // fuzzing with random data, so at this point I'm trying to
313 // demonstrate memory corruption.
314 //
315 // Other findings from past instrumentation:
316 // - half of one percent of brokenness cases implied duplicate items
317 // in |prefixes|. Per the code above, this should not be
318 // possible.
319 // - about 1/20 of broken cases happened more than once for a given
320 // user. Note that empty updates generally don't hit this code at
321 // all, so that may not imply a specific input pattern breaking things.
322 // - about 1/3 of broken cases show a checksum mismatch between the
323 // checksum calculated while creating |prefix_set| and the
324 // checksum calculated immediately after creation. This is almost
325 // certainly memory corruption.
326 NOTREACHED();
327 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN);
328 401
329 // Broken because internal memory was corrupted during construction. 402 // TODO(shess): Need a barrier to prevent ordering checks above here
330 if (!prefix_set->CheckChecksum()) 403 // or construction below here?
404
405 bool get_prefixes_broken =
406 (unique_prefixes_checksum != prefix_set->get()->GetPrefixesChecksum());
407 bool prefix_set_broken = !prefix_set->get()->CheckChecksum();
408 bool bloom_filter_broken = !bloom_filter->get()->CheckChecksum();
409 bool prefixes_input_broken =
410 (0 != ChecksumPrefixes(add_prefixes_checksum, prefixes));
411 bool add_prefixes_input_broken =
412 (0 != ChecksumAddPrefixes(add_prefixes_checksum, add_prefixes));
413
414 if (add_prefixes_input_broken) {
415 RecordPrefixSetInfo(PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM);
416 } else if (prefixes_input_broken) {
417 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIXES_CHECKSUM);
418 }
419
420 if (prefix_set_broken)
331 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM); 421 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM);
332 422
333 // TODO(shess): Test whether |prefixes| changed during construction. 423 // TODO(shess): Obviously this is a problem for operation of the
424 // bloom filter! But for purposes of checking prefix set operation,
425 // all that matters is not messing up the histograms recorded later.
426 if (bloom_filter_broken)
427 RecordPrefixSetInfo(PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM);
334 428
335 return CreateEmptyPrefixSet(); 429 // Attempt to isolate the case where the output of GetPrefixes()
430 // would differ from the input presented. This case implies that
431 // PrefixSet has an actual implementation flaw, and may in the
432 // future warrant more aggressive action, such as somehow dumping
433 // |prefixes| up to the crash server.
434 if (get_prefixes_broken && !prefix_set_broken && !prefixes_input_broken)
435 RecordPrefixSetInfo(PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM);
436
437 // If anything broke, clear the prefix set to prevent pollution of
438 // histograms generated later.
439 if (get_prefixes_broken || prefix_set_broken || bloom_filter_broken ||
440 prefixes_input_broken || add_prefixes_input_broken) {
441 DCHECK(!get_prefixes_broken);
442 DCHECK(!prefix_set_broken);
443 DCHECK(!bloom_filter_broken);
444 DCHECK(!prefixes_input_broken);
445 DCHECK(!add_prefixes_input_broken);
446 prefix_set->reset(CreateEmptyPrefixSet());
447 }
336 } 448 }
337 449
338 } // namespace 450 } // namespace
339 451
340 // The default SafeBrowsingDatabaseFactory. 452 // The default SafeBrowsingDatabaseFactory.
341 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { 453 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
342 public: 454 public:
343 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 455 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
344 bool enable_download_protection, 456 bool enable_download_protection,
345 bool enable_client_side_whitelist, 457 bool enable_client_side_whitelist,
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 base::AutoLock locked(lookup_lock_); 698 base::AutoLock locked(lookup_lock_);
587 699
588 if (!browse_bloom_filter_.get()) 700 if (!browse_bloom_filter_.get())
589 return false; 701 return false;
590 DCHECK(prefix_set_.get()); 702 DCHECK(prefix_set_.get());
591 703
592 // |prefix_set_| is empty until the first update, only log info if 704 // |prefix_set_| is empty until the first update, only log info if
593 // not empty. 705 // not empty.
594 const bool prefix_set_empty = !prefix_set_->GetSize(); 706 const bool prefix_set_empty = !prefix_set_->GetSize();
595 707
708 // Track cases where the filters were not consistent with each other.
709 bool bloom_hit_prefix_miss = false;
710 bool bloom_miss_prefix_hit = false;
711
596 size_t miss_count = 0; 712 size_t miss_count = 0;
597 for (size_t i = 0; i < full_hashes.size(); ++i) { 713 for (size_t i = 0; i < full_hashes.size(); ++i) {
598 bool found = prefix_set_->Exists(full_hashes[i].prefix); 714 bool found = prefix_set_->Exists(full_hashes[i].prefix);
599 715
600 if (browse_bloom_filter_->Exists(full_hashes[i].prefix)) { 716 if (browse_bloom_filter_->Exists(full_hashes[i].prefix)) {
601 if (!prefix_set_empty) { 717 if (!prefix_set_empty) {
602 RecordPrefixSetInfo(PREFIX_SET_BLOOM_HIT); 718 RecordPrefixSetInfo(PREFIX_SET_BLOOM_HIT);
603 // This should be less than PREFIX_SET_BLOOM_HIT by the 719 // This should be less than PREFIX_SET_BLOOM_HIT by the
604 // false positive rate. 720 // false positive rate.
605 if (found) 721 if (found) {
606 RecordPrefixSetInfo(PREFIX_SET_HIT); 722 RecordPrefixSetInfo(PREFIX_SET_HIT);
723 } else {
724 // Could be false positive, but _could_ be corruption.
725 bloom_hit_prefix_miss = true;
726 }
607 } 727 }
608 prefix_hits->push_back(full_hashes[i].prefix); 728 prefix_hits->push_back(full_hashes[i].prefix);
609 if (prefix_miss_cache_.count(full_hashes[i].prefix) > 0) 729 if (prefix_miss_cache_.count(full_hashes[i].prefix) > 0)
610 ++miss_count; 730 ++miss_count;
611 } else { 731 } else {
612 // Bloom filter misses should never be in prefix set. 732 // Bloom filter misses should never be in prefix set. Check
733 // to see if the prefix set or bloom filter have changed since
734 // being created.
613 DCHECK(!found); 735 DCHECK(!found);
614 if (found) 736 if (found && !prefix_set_empty)
615 RecordPrefixSetInfo(PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT); 737 bloom_miss_prefix_hit = true;
616 } 738 }
617 } 739 }
618 740
741 // In case of inconsistent results, verify the checksums and record
742 // failures (in case of corruption inconsistencies would be
743 // expected). In case of corruption clear out |prefix_set_|, once
744 // we've noticed corruption there is no point to future comparisons.
745 if (bloom_miss_prefix_hit || bloom_hit_prefix_miss) {
746 if (!prefix_set_->CheckChecksum()) {
747 RecordPrefixSetInfo(PREFIX_SET_MISMATCH_PREFIX_SET_CHECKSUM);
748 prefix_set_.reset(CreateEmptyPrefixSet());
749 } else if (!browse_bloom_filter_->CheckChecksum()) {
750 RecordPrefixSetInfo(PREFIX_SET_MISMATCH_BLOOM_FILTER_CHECKSUM);
751 prefix_set_.reset(CreateEmptyPrefixSet());
752 } else if (bloom_miss_prefix_hit) {
753 // This case should be impossible if the filters are both valid.
754 RecordPrefixSetInfo(PREFIX_SET_BLOOM_MISS_PREFIX_HIT);
755 }
756 }
757
619 // If all the prefixes are cached as 'misses', don't issue a GetHash. 758 // If all the prefixes are cached as 'misses', don't issue a GetHash.
620 if (miss_count == prefix_hits->size()) 759 if (miss_count == prefix_hits->size())
621 return false; 760 return false;
622 761
623 // Find the matching full-hash results. |full_browse_hashes_| are from the 762 // Find the matching full-hash results. |full_browse_hashes_| are from the
624 // database, |pending_browse_hashes_| are from GetHash requests between 763 // database, |pending_browse_hashes_| are from GetHash requests between
625 // updates. 764 // updates.
626 std::sort(prefix_hits->begin(), prefix_hits->end()); 765 std::sort(prefix_hits->begin(), prefix_hits->end());
627 766
628 GetCachedFullHashesForBrowse(*prefix_hits, full_browse_hashes_, 767 GetCachedFullHashesForBrowse(*prefix_hits, full_browse_hashes_,
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 const base::Time before = base::Time::Now(); 1320 const base::Time before = base::Time::Now();
1182 1321
1183 SBAddPrefixes add_prefixes; 1322 SBAddPrefixes add_prefixes;
1184 std::vector<SBAddFullHash> add_full_hashes; 1323 std::vector<SBAddFullHash> add_full_hashes;
1185 if (!browse_store_->FinishUpdate(pending_add_hashes, prefix_miss_cache_, 1324 if (!browse_store_->FinishUpdate(pending_add_hashes, prefix_miss_cache_,
1186 &add_prefixes, &add_full_hashes)) { 1325 &add_prefixes, &add_full_hashes)) {
1187 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_FINISH); 1326 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_FINISH);
1188 return; 1327 return;
1189 } 1328 }
1190 1329
1191 // Create and populate |filter| from |add_prefixes|. 1330 scoped_refptr<BloomFilter> bloom_filter;
1192 // TODO(shess): The bloom filter doesn't need to be a 1331 scoped_ptr<safe_browsing::PrefixSet> prefix_set;
1193 // scoped_refptr<> for this code. Refactor that away. 1332 FiltersFromAddPrefixes(add_prefixes, &bloom_filter, &prefix_set);
1194 const int filter_size =
1195 BloomFilter::FilterSizeForKeyCount(add_prefixes.size());
1196 scoped_refptr<BloomFilter> filter(new BloomFilter(filter_size));
1197 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin();
1198 iter != add_prefixes.end(); ++iter) {
1199 filter->Insert(iter->prefix);
1200 }
1201
1202 scoped_ptr<safe_browsing::PrefixSet>
1203 prefix_set(PrefixSetFromAddPrefixes(add_prefixes));
1204 1333
1205 // This needs to be in sorted order by prefix for efficient access. 1334 // This needs to be in sorted order by prefix for efficient access.
1206 std::sort(add_full_hashes.begin(), add_full_hashes.end(), 1335 std::sort(add_full_hashes.begin(), add_full_hashes.end(),
1207 SBAddFullHashPrefixLess); 1336 SBAddFullHashPrefixLess);
1208 1337
1209 // Swap in the newly built filter and cache. 1338 // Swap in the newly built filter and cache.
1210 { 1339 {
1211 base::AutoLock locked(lookup_lock_); 1340 base::AutoLock locked(lookup_lock_);
1212 full_browse_hashes_.swap(add_full_hashes); 1341 full_browse_hashes_.swap(add_full_hashes);
1213 1342
1214 // TODO(shess): If |CacheHashResults()| is posted between the 1343 // TODO(shess): If |CacheHashResults()| is posted between the
1215 // earlier lock and this clear, those pending hashes will be lost. 1344 // earlier lock and this clear, those pending hashes will be lost.
1216 // It could be fixed by only removing hashes which were collected 1345 // It could be fixed by only removing hashes which were collected
1217 // at the earlier point. I believe that is fail-safe as-is (the 1346 // at the earlier point. I believe that is fail-safe as-is (the
1218 // hash will be fetched again). 1347 // hash will be fetched again).
1219 pending_browse_hashes_.clear(); 1348 pending_browse_hashes_.clear();
1220 prefix_miss_cache_.clear(); 1349 prefix_miss_cache_.clear();
1221 browse_bloom_filter_.swap(filter); 1350 browse_bloom_filter_.swap(bloom_filter);
1222 prefix_set_.swap(prefix_set); 1351 prefix_set_.swap(prefix_set);
1223 } 1352 }
1224 1353
1225 const base::TimeDelta bloom_gen = base::Time::Now() - before; 1354 const base::TimeDelta bloom_gen = base::Time::Now() - before;
1226 1355
1227 // Persist the bloom filter to disk. Since only this thread changes 1356 // Persist the bloom filter to disk. Since only this thread changes
1228 // |browse_bloom_filter_|, there is no need to lock. 1357 // |browse_bloom_filter_|, there is no need to lock.
1229 WriteBloomFilter(); 1358 WriteBloomFilter();
1230 1359
1231 // Gather statistics. 1360 // Gather statistics.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), 1514 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1386 kill_switch)) { 1515 kill_switch)) {
1387 // The kill switch is whitelisted hence we whitelist all URLs. 1516 // The kill switch is whitelisted hence we whitelist all URLs.
1388 WhitelistEverything(whitelist); 1517 WhitelistEverything(whitelist);
1389 } else { 1518 } else {
1390 base::AutoLock locked(lookup_lock_); 1519 base::AutoLock locked(lookup_lock_);
1391 whitelist->second = false; 1520 whitelist->second = false;
1392 whitelist->first.swap(new_whitelist); 1521 whitelist->first.swap(new_whitelist);
1393 } 1522 }
1394 } 1523 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/prefix_set.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698