OLD | NEW |
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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM, | 289 PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM, |
290 PREFIX_SET_CREATE_PREFIXES_CHECKSUM, | 290 PREFIX_SET_CREATE_PREFIXES_CHECKSUM, |
291 PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM, | 291 PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM, |
292 // Failed checksums when probing the filters. | 292 // Failed checksums when probing the filters. |
293 PREFIX_SET_MISMATCH_PREFIX_SET_CHECKSUM, | 293 PREFIX_SET_MISMATCH_PREFIX_SET_CHECKSUM, |
294 PREFIX_SET_MISMATCH_BLOOM_FILTER_CHECKSUM, | 294 PREFIX_SET_MISMATCH_BLOOM_FILTER_CHECKSUM, |
295 | 295 |
296 // Recorded once per update if the impossible occurs. | 296 // Recorded once per update if the impossible occurs. |
297 PREFIX_SET_BLOOM_MISS_PREFIX_HIT, | 297 PREFIX_SET_BLOOM_MISS_PREFIX_HIT, |
298 | 298 |
| 299 // Corresponding CHECKSUM failed, but on retry it succeeded. |
| 300 PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM_SUCCEEDED, |
| 301 PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM_SUCCEEDED, |
| 302 |
299 // Memory space for histograms is determined by the max. ALWAYS ADD | 303 // Memory space for histograms is determined by the max. ALWAYS ADD |
300 // NEW VALUES BEFORE THIS ONE. | 304 // NEW VALUES BEFORE THIS ONE. |
301 PREFIX_SET_EVENT_MAX | 305 PREFIX_SET_EVENT_MAX |
302 }; | 306 }; |
303 | 307 |
304 void RecordPrefixSetInfo(PrefixSetEvent event_type) { | 308 void RecordPrefixSetInfo(PrefixSetEvent event_type) { |
305 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, | 309 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, |
306 PREFIX_SET_EVENT_MAX); | 310 PREFIX_SET_EVENT_MAX); |
307 } | 311 } |
308 | 312 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 | 428 |
425 std::vector<SBPrefix> restored; | 429 std::vector<SBPrefix> restored; |
426 prefix_set->get()->GetPrefixes(&restored); | 430 prefix_set->get()->GetPrefixes(&restored); |
427 DCHECK_EQ(0, ChecksumPrefixes(prefix_set->get()->GetPrefixesChecksum(), | 431 DCHECK_EQ(0, ChecksumPrefixes(prefix_set->get()->GetPrefixesChecksum(), |
428 restored)); | 432 restored)); |
429 } | 433 } |
430 | 434 |
431 // TODO(shess): Need a barrier to prevent ordering checks above here | 435 // TODO(shess): Need a barrier to prevent ordering checks above here |
432 // or construction below here? | 436 // or construction below here? |
433 | 437 |
| 438 // NOTE(shess): So far, the fallout is: |
| 439 // 605 PREFIX_SET_CHECKSUM (failed prefix_set->CheckChecksum()). |
| 440 // 32 BLOOM_FILTER_CHECKSUM (failed bloom_filter->CheckChecksum()). |
| 441 // 1 ADD_PREFIXES_CHECKSUM (contents of add_prefixes changed). |
| 442 // 7 PREFIXES_CHECKSUM (contents of prefixes changed). |
| 443 |
434 bool get_prefixes_broken = | 444 bool get_prefixes_broken = |
435 (unique_prefixes_checksum != prefix_set->get()->GetPrefixesChecksum()); | 445 (unique_prefixes_checksum != prefix_set->get()->GetPrefixesChecksum()); |
436 bool prefix_set_broken = !prefix_set->get()->CheckChecksum(); | 446 bool prefix_set_broken = !prefix_set->get()->CheckChecksum(); |
437 bool bloom_filter_broken = !bloom_filter->get()->CheckChecksum(); | 447 bool bloom_filter_broken = !bloom_filter->get()->CheckChecksum(); |
438 bool prefixes_input_broken = | 448 bool prefixes_input_broken = |
439 (0 != ChecksumPrefixes(add_prefixes_checksum, prefixes)); | 449 (0 != ChecksumPrefixes(add_prefixes_checksum, prefixes)); |
440 bool add_prefixes_input_broken = | 450 bool add_prefixes_input_broken = |
441 (0 != ChecksumAddPrefixes(add_prefixes_checksum, add_prefixes)); | 451 (0 != ChecksumAddPrefixes(add_prefixes_checksum, add_prefixes)); |
442 | 452 |
443 if (add_prefixes_input_broken) { | 453 if (add_prefixes_input_broken) { |
444 RecordPrefixSetInfo(PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM); | 454 RecordPrefixSetInfo(PREFIX_SET_CREATE_ADD_PREFIXES_CHECKSUM); |
445 } else if (prefixes_input_broken) { | 455 } else if (prefixes_input_broken) { |
446 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIXES_CHECKSUM); | 456 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIXES_CHECKSUM); |
447 } | 457 } |
448 | 458 |
449 if (prefix_set_broken) | 459 if (prefix_set_broken) { |
450 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM); | 460 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM); |
451 | 461 |
| 462 // Failing PrefixSet::CheckChecksum() implies that the set's |
| 463 // internal data changed during construction. If the retry |
| 464 // consistently succeeds, that implies memory corruption. If the |
| 465 // retry consistently fails, that implies PrefixSet is broken. |
| 466 scoped_ptr<safe_browsing::PrefixSet> retry_set( |
| 467 new safe_browsing::PrefixSet(prefixes)); |
| 468 if (retry_set->CheckChecksum()) |
| 469 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM_SUCCEEDED); |
| 470 |
| 471 // TODO(shess): In case of double failure, consider pinning the |
| 472 // data and calling NOTREACHED(). But it's a lot of data. Could |
| 473 // also implement a binary search to constrain the amount of input |
| 474 // to consider, but that's a lot of complexity. |
| 475 } |
| 476 |
452 // TODO(shess): Obviously this is a problem for operation of the | 477 // TODO(shess): Obviously this is a problem for operation of the |
453 // bloom filter! But for purposes of checking prefix set operation, | 478 // bloom filter! But for purposes of checking prefix set operation, |
454 // all that matters is not messing up the histograms recorded later. | 479 // all that matters is not messing up the histograms recorded later. |
455 if (bloom_filter_broken) | 480 if (bloom_filter_broken) { |
456 RecordPrefixSetInfo(PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM); | 481 RecordPrefixSetInfo(PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM); |
457 | 482 |
| 483 // As for PrefixSet, failing BloomFilter::CheckChecksum() implies |
| 484 // that the filter's internal data was changed. |
| 485 scoped_refptr<BloomFilter> retry_filter(new BloomFilter(filter_size)); |
| 486 for (std::vector<SBPrefix>::const_iterator iter = prefixes.begin(); |
| 487 iter != prefixes.end(); ++iter) { |
| 488 retry_filter->Insert(*iter); |
| 489 } |
| 490 if (retry_filter->CheckChecksum()) |
| 491 RecordPrefixSetInfo(PREFIX_SET_CREATE_BLOOM_FILTER_CHECKSUM_SUCCEEDED); |
| 492 } |
| 493 |
458 // Attempt to isolate the case where the output of GetPrefixes() | 494 // Attempt to isolate the case where the output of GetPrefixes() |
459 // would differ from the input presented. This case implies that | 495 // would differ from the input presented. This case implies that |
460 // PrefixSet has an actual implementation flaw, and may in the | 496 // PrefixSet has an actual implementation flaw, and may in the |
461 // future warrant more aggressive action, such as somehow dumping | 497 // future warrant more aggressive action, such as somehow dumping |
462 // |prefixes| up to the crash server. | 498 // |prefixes| up to the crash server. |
463 if (get_prefixes_broken && !prefix_set_broken && !prefixes_input_broken) | 499 if (get_prefixes_broken && !prefix_set_broken && !prefixes_input_broken) |
464 RecordPrefixSetInfo(PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM); | 500 RecordPrefixSetInfo(PREFIX_SET_CREATE_GET_PREFIXES_CHECKSUM); |
465 | 501 |
466 // If anything broke, clear the prefix set to prevent pollution of | 502 // If anything broke, clear the prefix set to prevent pollution of |
467 // histograms generated later. | 503 // histograms generated later. |
(...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), | 1592 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), |
1557 kill_switch)) { | 1593 kill_switch)) { |
1558 // The kill switch is whitelisted hence we whitelist all URLs. | 1594 // The kill switch is whitelisted hence we whitelist all URLs. |
1559 WhitelistEverything(whitelist); | 1595 WhitelistEverything(whitelist); |
1560 } else { | 1596 } else { |
1561 base::AutoLock locked(lookup_lock_); | 1597 base::AutoLock locked(lookup_lock_); |
1562 whitelist->second = false; | 1598 whitelist->second = false; |
1563 whitelist->first.swap(new_whitelist); | 1599 whitelist->first.swap(new_whitelist); |
1564 } | 1600 } |
1565 } | 1601 } |
OLD | NEW |