Chromium Code Reviews| 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 return base::FilePath(db_filename.value() + kIPBlacklistDBFile); | 425 return base::FilePath(db_filename.value() + kIPBlacklistDBFile); |
| 426 } | 426 } |
| 427 | 427 |
| 428 // static | 428 // static |
| 429 base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename( | 429 base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename( |
| 430 const base::FilePath& db_filename) { | 430 const base::FilePath& db_filename) { |
| 431 return base::FilePath(db_filename.value() + kUnwantedSoftwareDBFile); | 431 return base::FilePath(db_filename.value() + kUnwantedSoftwareDBFile); |
| 432 } | 432 } |
| 433 | 433 |
| 434 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { | 434 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { |
| 435 // Stores are not thread safe. | |
| 436 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 437 | |
| 435 if (list_id == safe_browsing_util::PHISH || | 438 if (list_id == safe_browsing_util::PHISH || |
| 436 list_id == safe_browsing_util::MALWARE) { | 439 list_id == safe_browsing_util::MALWARE) { |
| 437 return browse_store_.get(); | 440 return browse_store_.get(); |
| 438 } else if (list_id == safe_browsing_util::BINURL) { | 441 } else if (list_id == safe_browsing_util::BINURL) { |
| 439 return download_store_.get(); | 442 return download_store_.get(); |
| 440 } else if (list_id == safe_browsing_util::CSDWHITELIST) { | 443 } else if (list_id == safe_browsing_util::CSDWHITELIST) { |
| 441 return csd_whitelist_store_.get(); | 444 return csd_whitelist_store_.get(); |
| 442 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) { | 445 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) { |
| 443 return download_whitelist_store_.get(); | 446 return download_whitelist_store_.get(); |
| 444 } else if (list_id == safe_browsing_util::EXTENSIONBLACKLIST) { | 447 } else if (list_id == safe_browsing_util::EXTENSIONBLACKLIST) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 | 483 |
| 481 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( | 484 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( |
| 482 SafeBrowsingStore* browse_store, | 485 SafeBrowsingStore* browse_store, |
| 483 SafeBrowsingStore* download_store, | 486 SafeBrowsingStore* download_store, |
| 484 SafeBrowsingStore* csd_whitelist_store, | 487 SafeBrowsingStore* csd_whitelist_store, |
| 485 SafeBrowsingStore* download_whitelist_store, | 488 SafeBrowsingStore* download_whitelist_store, |
| 486 SafeBrowsingStore* extension_blacklist_store, | 489 SafeBrowsingStore* extension_blacklist_store, |
| 487 SafeBrowsingStore* side_effect_free_whitelist_store, | 490 SafeBrowsingStore* side_effect_free_whitelist_store, |
| 488 SafeBrowsingStore* ip_blacklist_store, | 491 SafeBrowsingStore* ip_blacklist_store, |
| 489 SafeBrowsingStore* unwanted_software_store) | 492 SafeBrowsingStore* unwanted_software_store) |
| 490 : creation_loop_(base::MessageLoop::current()), | 493 : browse_store_(browse_store), |
| 491 browse_store_(browse_store), | |
| 492 download_store_(download_store), | 494 download_store_(download_store), |
| 493 csd_whitelist_store_(csd_whitelist_store), | 495 csd_whitelist_store_(csd_whitelist_store), |
| 494 download_whitelist_store_(download_whitelist_store), | 496 download_whitelist_store_(download_whitelist_store), |
| 495 extension_blacklist_store_(extension_blacklist_store), | 497 extension_blacklist_store_(extension_blacklist_store), |
| 496 side_effect_free_whitelist_store_(side_effect_free_whitelist_store), | 498 side_effect_free_whitelist_store_(side_effect_free_whitelist_store), |
| 497 ip_blacklist_store_(ip_blacklist_store), | 499 ip_blacklist_store_(ip_blacklist_store), |
| 498 unwanted_software_store_(unwanted_software_store), | 500 unwanted_software_store_(unwanted_software_store), |
| 499 corruption_detected_(false), | 501 corruption_detected_(false), |
| 500 change_detected_(false), | 502 change_detected_(false), |
| 501 reset_factory_(this) { | 503 reset_factory_(this) { |
| 502 DCHECK(browse_store_.get()); | 504 DCHECK(browse_store_.get()); |
| 503 } | 505 } |
| 504 | 506 |
| 505 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { | 507 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { |
| 506 // The DCHECK is disabled due to crbug.com/338486 . | 508 // The DCHECK is disabled due to crbug.com/338486 . |
| 507 // DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 509 // DCHECK(thread_checker_.CalledOnValidThread()); |
| 508 } | 510 } |
| 509 | 511 |
| 510 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { | 512 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { |
| 511 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 513 DCHECK(thread_checker_.CalledOnValidThread()); |
| 512 | 514 |
| 513 // This should not be run multiple times. | 515 // This should not be run multiple times. |
| 514 DCHECK(filename_base_.empty()); | 516 DCHECK(filename_base_.empty()); |
| 515 | 517 |
| 516 filename_base_ = filename_base; | 518 filename_base_ = filename_base; |
| 517 | 519 |
| 518 // TODO(shess): The various stores are really only necessary while doing | 520 // TODO(shess): The various stores are really only necessary while doing |
| 519 // updates (see |UpdateFinished()|) or when querying a store directly (see | 521 // updates (see |UpdateFinished()|) or when querying a store directly (see |
| 520 // |ContainsDownloadUrl()|). | 522 // |ContainsDownloadUrl()|). |
| 521 // The store variables are also tested to see if a list is enabled. Perhaps | 523 // The store variables are also tested to see if a list is enabled. Perhaps |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 std::vector<SBAddFullHash> full_hashes; | 640 std::vector<SBAddFullHash> full_hashes; |
| 639 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { | 641 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { |
| 640 LoadIpBlacklist(full_hashes); | 642 LoadIpBlacklist(full_hashes); |
| 641 } else { | 643 } else { |
| 642 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. | 644 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. |
| 643 } | 645 } |
| 644 } | 646 } |
| 645 } | 647 } |
| 646 | 648 |
| 647 bool SafeBrowsingDatabaseNew::ResetDatabase() { | 649 bool SafeBrowsingDatabaseNew::ResetDatabase() { |
| 648 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 650 DCHECK(thread_checker_.CalledOnValidThread()); |
| 649 | 651 |
| 650 // Delete files on disk. | 652 // Delete files on disk. |
| 651 // TODO(shess): Hard to see where one might want to delete without a | 653 // TODO(shess): Hard to see where one might want to delete without a |
| 652 // reset. Perhaps inline |Delete()|? | 654 // reset. Perhaps inline |Delete()|? |
| 653 if (!Delete()) | 655 if (!Delete()) |
| 654 return false; | 656 return false; |
| 655 | 657 |
| 656 // Reset objects in memory. | 658 // Reset objects in memory. |
| 657 { | 659 { |
| 658 base::AutoLock locked(lookup_lock_); | 660 base::AutoLock locked(lookup_lock_); |
| 659 prefix_gethash_cache_.clear(); | 661 prefix_gethash_cache_.clear(); |
| 660 browse_prefix_set_.reset(); | 662 browse_prefix_set_.reset(); |
| 661 side_effect_free_whitelist_prefix_set_.reset(); | 663 side_effect_free_whitelist_prefix_set_.reset(); |
| 662 ip_blacklist_.clear(); | 664 ip_blacklist_.clear(); |
| 663 unwanted_software_prefix_set_.reset(); | 665 unwanted_software_prefix_set_.reset(); |
| 664 } | 666 } |
| 665 // Wants to acquire the lock itself. | 667 // Wants to acquire the lock itself. |
| 666 WhitelistEverything(&csd_whitelist_); | 668 WhitelistEverything(&csd_whitelist_); |
| 667 WhitelistEverything(&download_whitelist_); | 669 WhitelistEverything(&download_whitelist_); |
| 668 return true; | 670 return true; |
| 669 } | 671 } |
| 670 | 672 |
| 671 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( | 673 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( |
| 672 const GURL& url, | 674 const GURL& url, |
| 673 std::vector<SBPrefix>* prefix_hits, | 675 std::vector<SBPrefix>* prefix_hits, |
| 674 std::vector<SBFullHashResult>* cache_hits) { | 676 std::vector<SBFullHashResult>* cache_hits) { |
| 677 // This method is theoretically thread-safe but document that it is currently | |
| 678 // only expected to be called on the IO thread. | |
| 679 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
|
mattm
2014/12/03 22:57:08
The comments in the header say it's safe to call t
gab
2014/12/04 19:57:27
Ah, right, in fact I just updated all of those com
| |
| 680 | |
| 675 return PrefixSetContainsUrl( | 681 return PrefixSetContainsUrl( |
| 676 url, &browse_prefix_set_, prefix_hits, cache_hits); | 682 url, &browse_prefix_set_, prefix_hits, cache_hits); |
| 677 } | 683 } |
| 678 | 684 |
| 679 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( | 685 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( |
| 680 const GURL& url, | 686 const GURL& url, |
| 681 std::vector<SBPrefix>* prefix_hits, | 687 std::vector<SBPrefix>* prefix_hits, |
| 682 std::vector<SBFullHashResult>* cache_hits) { | 688 std::vector<SBFullHashResult>* cache_hits) { |
| 689 // This method is theoretically thread-safe but document that it is currently | |
| 690 // only expected to be called on the IO thread. | |
| 691 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 692 | |
| 683 return PrefixSetContainsUrl( | 693 return PrefixSetContainsUrl( |
| 684 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); | 694 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); |
| 685 } | 695 } |
| 686 | 696 |
| 687 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( | 697 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( |
| 688 const GURL& url, | 698 const GURL& url, |
| 689 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, | 699 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, |
| 690 std::vector<SBPrefix>* prefix_hits, | 700 std::vector<SBPrefix>* prefix_hits, |
| 691 std::vector<SBFullHashResult>* cache_hits) { | 701 std::vector<SBFullHashResult>* cache_hits) { |
| 702 // This method is theoretically thread-safe but document that it is currently | |
| 703 // only expected to be called on the IO thread. | |
| 704 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 705 | |
| 692 // Clear the results first. | 706 // Clear the results first. |
| 693 prefix_hits->clear(); | 707 prefix_hits->clear(); |
| 694 cache_hits->clear(); | 708 cache_hits->clear(); |
| 695 | 709 |
| 696 std::vector<SBFullHash> full_hashes; | 710 std::vector<SBFullHash> full_hashes; |
| 697 UrlToFullHashes(url, false, &full_hashes); | 711 UrlToFullHashes(url, false, &full_hashes); |
| 698 if (full_hashes.empty()) | 712 if (full_hashes.empty()) |
| 699 return false; | 713 return false; |
| 700 | 714 |
| 701 return PrefixSetContainsUrlHashes( | 715 return PrefixSetContainsUrlHashes( |
| 702 full_hashes, prefix_set_getter, prefix_hits, cache_hits); | 716 full_hashes, prefix_set_getter, prefix_hits, cache_hits); |
| 703 } | 717 } |
| 704 | 718 |
| 705 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( | 719 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( |
| 706 const std::vector<SBFullHash>& full_hashes, | 720 const std::vector<SBFullHash>& full_hashes, |
| 707 std::vector<SBPrefix>* prefix_hits, | 721 std::vector<SBPrefix>* prefix_hits, |
| 708 std::vector<SBFullHashResult>* cache_hits) { | 722 std::vector<SBFullHashResult>* cache_hits) { |
| 709 return PrefixSetContainsUrlHashes( | 723 return PrefixSetContainsUrlHashes( |
| 710 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); | 724 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); |
| 711 } | 725 } |
| 712 | 726 |
| 713 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( | 727 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( |
| 714 const std::vector<SBFullHash>& full_hashes, | 728 const std::vector<SBFullHash>& full_hashes, |
| 715 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, | 729 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, |
| 716 std::vector<SBPrefix>* prefix_hits, | 730 std::vector<SBPrefix>* prefix_hits, |
| 717 std::vector<SBFullHashResult>* cache_hits) { | 731 std::vector<SBFullHashResult>* cache_hits) { |
| 732 // This method is theoretically thread-safe but document that it is currently | |
| 733 // only expected to be called on the IO thread. | |
| 734 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 735 | |
| 718 // Used to determine cache expiration. | 736 // Used to determine cache expiration. |
| 719 const base::Time now = base::Time::Now(); | 737 const base::Time now = base::Time::Now(); |
| 720 | 738 |
| 721 // This function is called on the I/O thread, prevent changes to | |
| 722 // filter and caches. | |
| 723 base::AutoLock locked(lookup_lock_); | 739 base::AutoLock locked(lookup_lock_); |
| 724 | 740 |
| 725 // |prefix_set| is empty until it is either read from disk, or the first | 741 // |prefix_set| is empty until it is either read from disk, or the first |
| 726 // update populates it. Bail out without a hit if not yet available. | 742 // update populates it. Bail out without a hit if not yet available. |
| 727 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence | 743 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence |
| 728 // why it is passed as a parameter rather than passing the |prefix_set| | 744 // why it is passed as a parameter rather than passing the |prefix_set| |
| 729 // directly. | 745 // directly. |
| 730 safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); | 746 safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); |
| 731 if (!prefix_set) | 747 if (!prefix_set) |
| 732 return false; | 748 return false; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 744 std::sort(prefix_hits->begin(), prefix_hits->end()); | 760 std::sort(prefix_hits->begin(), prefix_hits->end()); |
| 745 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), | 761 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), |
| 746 prefix_hits->end()); | 762 prefix_hits->end()); |
| 747 | 763 |
| 748 return !prefix_hits->empty() || !cache_hits->empty(); | 764 return !prefix_hits->empty() || !cache_hits->empty(); |
| 749 } | 765 } |
| 750 | 766 |
| 751 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( | 767 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( |
| 752 const std::vector<GURL>& urls, | 768 const std::vector<GURL>& urls, |
| 753 std::vector<SBPrefix>* prefix_hits) { | 769 std::vector<SBPrefix>* prefix_hits) { |
| 754 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 770 DCHECK(thread_checker_.CalledOnValidThread()); |
| 755 | 771 |
| 756 // Ignore this check when download checking is not enabled. | 772 // Ignore this check when download checking is not enabled. |
| 757 if (!download_store_.get()) | 773 if (!download_store_.get()) |
| 758 return false; | 774 return false; |
| 759 | 775 |
| 760 std::vector<SBPrefix> prefixes; | 776 std::vector<SBPrefix> prefixes; |
| 761 GetDownloadUrlPrefixes(urls, &prefixes); | 777 GetDownloadUrlPrefixes(urls, &prefixes); |
| 762 return MatchAddPrefixes(download_store_.get(), | 778 return MatchAddPrefixes(download_store_.get(), |
| 763 safe_browsing_util::BINURL % 2, | 779 safe_browsing_util::BINURL % 2, |
| 764 prefixes, | 780 prefixes, |
| 765 prefix_hits); | 781 prefix_hits); |
| 766 } | 782 } |
| 767 | 783 |
| 768 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { | 784 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { |
| 769 // This method is theoretically thread-safe but we expect all calls to | 785 // This method is theoretically thread-safe but document that it is currently |
| 770 // originate from the IO thread. | 786 // only expected to be called on the IO thread. |
| 771 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 787 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 788 | |
| 772 std::vector<SBFullHash> full_hashes; | 789 std::vector<SBFullHash> full_hashes; |
| 773 UrlToFullHashes(url, true, &full_hashes); | 790 UrlToFullHashes(url, true, &full_hashes); |
| 774 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 791 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
| 775 } | 792 } |
| 776 | 793 |
| 777 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { | 794 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { |
| 778 std::vector<SBFullHash> full_hashes; | 795 std::vector<SBFullHash> full_hashes; |
| 779 UrlToFullHashes(url, true, &full_hashes); | 796 UrlToFullHashes(url, true, &full_hashes); |
| 780 return ContainsWhitelistedHashes(download_whitelist_, full_hashes); | 797 return ContainsWhitelistedHashes(download_whitelist_, full_hashes); |
| 781 } | 798 } |
| 782 | 799 |
| 783 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( | 800 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( |
| 784 const std::vector<SBPrefix>& prefixes, | 801 const std::vector<SBPrefix>& prefixes, |
| 785 std::vector<SBPrefix>* prefix_hits) { | 802 std::vector<SBPrefix>* prefix_hits) { |
| 786 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 803 DCHECK(thread_checker_.CalledOnValidThread()); |
| 787 if (!extension_blacklist_store_) | 804 if (!extension_blacklist_store_) |
| 788 return false; | 805 return false; |
| 789 | 806 |
| 790 return MatchAddPrefixes(extension_blacklist_store_.get(), | 807 return MatchAddPrefixes(extension_blacklist_store_.get(), |
| 791 safe_browsing_util::EXTENSIONBLACKLIST % 2, | 808 safe_browsing_util::EXTENSIONBLACKLIST % 2, |
| 792 prefixes, | 809 prefixes, |
| 793 prefix_hits); | 810 prefix_hits); |
| 794 } | 811 } |
| 795 | 812 |
| 796 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( | 813 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( |
| 797 const GURL& url) { | 814 const GURL& url) { |
| 815 // This method is theoretically thread-safe but document that it is currently | |
| 816 // only expected to be called on the UI thread. | |
| 817 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 818 | |
| 798 std::string host; | 819 std::string host; |
| 799 std::string path; | 820 std::string path; |
| 800 std::string query; | 821 std::string query; |
| 801 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query); | 822 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query); |
| 802 std::string url_to_check = host + path; | 823 std::string url_to_check = host + path; |
| 803 if (!query.empty()) | 824 if (!query.empty()) |
| 804 url_to_check += "?" + query; | 825 url_to_check += "?" + query; |
| 805 SBFullHash full_hash = SBFullHashForString(url_to_check); | 826 SBFullHash full_hash = SBFullHashForString(url_to_check); |
| 806 | 827 |
| 807 // This function can be called on any thread, so lock against any changes | |
| 808 base::AutoLock locked(lookup_lock_); | 828 base::AutoLock locked(lookup_lock_); |
| 809 | 829 |
| 810 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read | 830 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read |
| 811 // from disk, or the first update populates it. Bail out without a hit if | 831 // from disk, or the first update populates it. Bail out without a hit if |
| 812 // not yet available. | 832 // not yet available. |
| 813 if (!side_effect_free_whitelist_prefix_set_.get()) | 833 if (!side_effect_free_whitelist_prefix_set_.get()) |
| 814 return false; | 834 return false; |
| 815 | 835 |
| 816 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); | 836 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); |
| 817 } | 837 } |
| 818 | 838 |
| 819 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { | 839 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { |
| 840 // This method is theoretically thread-safe but document that it is currently | |
| 841 // only expected to be called on the IO thread. | |
| 842 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 843 | |
| 820 net::IPAddressNumber ip_number; | 844 net::IPAddressNumber ip_number; |
| 821 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) | 845 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) |
| 822 return false; | 846 return false; |
| 823 if (ip_number.size() == net::kIPv4AddressSize) | 847 if (ip_number.size() == net::kIPv4AddressSize) |
| 824 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); | 848 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); |
| 825 if (ip_number.size() != net::kIPv6AddressSize) | 849 if (ip_number.size() != net::kIPv6AddressSize) |
| 826 return false; // better safe than sorry. | 850 return false; // better safe than sorry. |
| 827 | 851 |
| 828 // This function can be called from any thread. | |
| 829 base::AutoLock locked(lookup_lock_); | 852 base::AutoLock locked(lookup_lock_); |
| 830 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); | 853 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); |
| 831 it != ip_blacklist_.end(); | 854 it != ip_blacklist_.end(); |
| 832 ++it) { | 855 ++it) { |
| 833 const std::string& mask = it->first; | 856 const std::string& mask = it->first; |
| 834 DCHECK_EQ(mask.size(), ip_number.size()); | 857 DCHECK_EQ(mask.size(), ip_number.size()); |
| 835 std::string subnet(net::kIPv6AddressSize, '\0'); | 858 std::string subnet(net::kIPv6AddressSize, '\0'); |
| 836 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { | 859 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { |
| 837 subnet[i] = ip_number[i] & mask[i]; | 860 subnet[i] = ip_number[i] & mask[i]; |
| 838 } | 861 } |
| 839 const std::string hash = base::SHA1HashString(subnet); | 862 const std::string hash = base::SHA1HashString(subnet); |
| 840 DVLOG(2) << "Lookup Malware IP: " | 863 DVLOG(2) << "Lookup Malware IP: " |
| 841 << " ip:" << ip_address | 864 << " ip:" << ip_address |
| 842 << " mask:" << base::HexEncode(mask.data(), mask.size()) | 865 << " mask:" << base::HexEncode(mask.data(), mask.size()) |
| 843 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) | 866 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) |
| 844 << " hash:" << base::HexEncode(hash.data(), hash.size()); | 867 << " hash:" << base::HexEncode(hash.data(), hash.size()); |
| 845 if (it->second.count(hash) > 0) { | 868 if (it->second.count(hash) > 0) { |
| 846 return true; | 869 return true; |
| 847 } | 870 } |
| 848 } | 871 } |
| 849 return false; | 872 return false; |
| 850 } | 873 } |
| 851 | 874 |
| 852 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( | 875 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( |
| 853 const std::string& str) { | 876 const std::string& str) { |
| 877 // This method is theoretically thread-safe but document that it is currently | |
| 878 // only expected to be called on the IO thread. | |
| 879 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 880 | |
| 854 std::vector<SBFullHash> hashes; | 881 std::vector<SBFullHash> hashes; |
| 855 hashes.push_back(SBFullHashForString(str)); | 882 hashes.push_back(SBFullHashForString(str)); |
| 856 return ContainsWhitelistedHashes(download_whitelist_, hashes); | 883 return ContainsWhitelistedHashes(download_whitelist_, hashes); |
| 857 } | 884 } |
| 858 | 885 |
| 859 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes( | 886 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes( |
| 860 const SBWhitelist& whitelist, | 887 const SBWhitelist& whitelist, |
| 861 const std::vector<SBFullHash>& hashes) { | 888 const std::vector<SBFullHash>& hashes) { |
| 889 // This method is theoretically thread-safe but document that it is currently | |
| 890 // only expected to be called on the IO thread. | |
| 891 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 892 | |
| 862 base::AutoLock l(lookup_lock_); | 893 base::AutoLock l(lookup_lock_); |
| 863 if (whitelist.second) | 894 if (whitelist.second) |
| 864 return true; | 895 return true; |
| 865 for (std::vector<SBFullHash>::const_iterator it = hashes.begin(); | 896 for (std::vector<SBFullHash>::const_iterator it = hashes.begin(); |
| 866 it != hashes.end(); ++it) { | 897 it != hashes.end(); ++it) { |
| 867 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), | 898 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), |
| 868 *it, SBFullHashLess)) { | 899 *it, SBFullHashLess)) { |
| 869 return true; | 900 return true; |
| 870 } | 901 } |
| 871 } | 902 } |
| 872 return false; | 903 return false; |
| 873 } | 904 } |
| 874 | 905 |
| 875 // Helper to insert add-chunk entries. | 906 // Helper to insert add-chunk entries. |
| 876 void SafeBrowsingDatabaseNew::InsertAddChunk( | 907 void SafeBrowsingDatabaseNew::InsertAddChunk( |
| 877 SafeBrowsingStore* store, | 908 SafeBrowsingStore* store, |
| 878 const safe_browsing_util::ListType list_id, | 909 const safe_browsing_util::ListType list_id, |
| 879 const SBChunkData& chunk_data) { | 910 const SBChunkData& chunk_data) { |
| 880 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 911 DCHECK(thread_checker_.CalledOnValidThread()); |
| 881 DCHECK(store); | 912 DCHECK(store); |
| 882 | 913 |
| 883 // The server can give us a chunk that we already have because | 914 // The server can give us a chunk that we already have because |
| 884 // it's part of a range. Don't add it again. | 915 // it's part of a range. Don't add it again. |
| 885 const int chunk_id = chunk_data.ChunkNumber(); | 916 const int chunk_id = chunk_data.ChunkNumber(); |
| 886 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); | 917 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); |
| 887 if (store->CheckAddChunk(encoded_chunk_id)) | 918 if (store->CheckAddChunk(encoded_chunk_id)) |
| 888 return; | 919 return; |
| 889 | 920 |
| 890 store->SetAddChunk(encoded_chunk_id); | 921 store->SetAddChunk(encoded_chunk_id); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 901 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i)); | 932 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i)); |
| 902 } | 933 } |
| 903 } | 934 } |
| 904 } | 935 } |
| 905 | 936 |
| 906 // Helper to insert sub-chunk entries. | 937 // Helper to insert sub-chunk entries. |
| 907 void SafeBrowsingDatabaseNew::InsertSubChunk( | 938 void SafeBrowsingDatabaseNew::InsertSubChunk( |
| 908 SafeBrowsingStore* store, | 939 SafeBrowsingStore* store, |
| 909 const safe_browsing_util::ListType list_id, | 940 const safe_browsing_util::ListType list_id, |
| 910 const SBChunkData& chunk_data) { | 941 const SBChunkData& chunk_data) { |
| 911 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 942 DCHECK(thread_checker_.CalledOnValidThread()); |
| 912 DCHECK(store); | 943 DCHECK(store); |
| 913 | 944 |
| 914 // The server can give us a chunk that we already have because | 945 // The server can give us a chunk that we already have because |
| 915 // it's part of a range. Don't add it again. | 946 // it's part of a range. Don't add it again. |
| 916 const int chunk_id = chunk_data.ChunkNumber(); | 947 const int chunk_id = chunk_data.ChunkNumber(); |
| 917 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); | 948 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); |
| 918 if (store->CheckSubChunk(encoded_chunk_id)) | 949 if (store->CheckSubChunk(encoded_chunk_id)) |
| 919 return; | 950 return; |
| 920 | 951 |
| 921 store->SetSubChunk(encoded_chunk_id); | 952 store->SetSubChunk(encoded_chunk_id); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 936 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id); | 967 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id); |
| 937 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id, | 968 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id, |
| 938 chunk_data.FullHashAt(i)); | 969 chunk_data.FullHashAt(i)); |
| 939 } | 970 } |
| 940 } | 971 } |
| 941 } | 972 } |
| 942 | 973 |
| 943 void SafeBrowsingDatabaseNew::InsertChunks( | 974 void SafeBrowsingDatabaseNew::InsertChunks( |
| 944 const std::string& list_name, | 975 const std::string& list_name, |
| 945 const std::vector<SBChunkData*>& chunks) { | 976 const std::vector<SBChunkData*>& chunks) { |
| 946 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 977 DCHECK(thread_checker_.CalledOnValidThread()); |
| 947 | 978 |
| 948 if (corruption_detected_ || chunks.empty()) | 979 if (corruption_detected_ || chunks.empty()) |
| 949 return; | 980 return; |
| 950 | 981 |
| 951 const base::TimeTicks before = base::TimeTicks::Now(); | 982 const base::TimeTicks before = base::TimeTicks::Now(); |
| 952 | 983 |
| 953 // TODO(shess): The caller should just pass list_id. | 984 // TODO(shess): The caller should just pass list_id. |
| 954 const safe_browsing_util::ListType list_id = | 985 const safe_browsing_util::ListType list_id = |
| 955 safe_browsing_util::GetListId(list_name); | 986 safe_browsing_util::GetListId(list_name); |
| 956 | 987 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 971 NOTREACHED(); | 1002 NOTREACHED(); |
| 972 } | 1003 } |
| 973 } | 1004 } |
| 974 store->FinishChunk(); | 1005 store->FinishChunk(); |
| 975 | 1006 |
| 976 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before); | 1007 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before); |
| 977 } | 1008 } |
| 978 | 1009 |
| 979 void SafeBrowsingDatabaseNew::DeleteChunks( | 1010 void SafeBrowsingDatabaseNew::DeleteChunks( |
| 980 const std::vector<SBChunkDelete>& chunk_deletes) { | 1011 const std::vector<SBChunkDelete>& chunk_deletes) { |
| 981 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1012 DCHECK(thread_checker_.CalledOnValidThread()); |
| 982 | 1013 |
| 983 if (corruption_detected_ || chunk_deletes.empty()) | 1014 if (corruption_detected_ || chunk_deletes.empty()) |
| 984 return; | 1015 return; |
| 985 | 1016 |
| 986 const std::string& list_name = chunk_deletes.front().list_name; | 1017 const std::string& list_name = chunk_deletes.front().list_name; |
| 987 const safe_browsing_util::ListType list_id = | 1018 const safe_browsing_util::ListType list_id = |
| 988 safe_browsing_util::GetListId(list_name); | 1019 safe_browsing_util::GetListId(list_name); |
| 989 | 1020 |
| 990 SafeBrowsingStore* store = GetStore(list_id); | 1021 SafeBrowsingStore* store = GetStore(list_id); |
| 991 if (!store) return; | 1022 if (!store) return; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1002 else | 1033 else |
| 1003 store->DeleteAddChunk(encoded_chunk_id); | 1034 store->DeleteAddChunk(encoded_chunk_id); |
| 1004 } | 1035 } |
| 1005 } | 1036 } |
| 1006 } | 1037 } |
| 1007 | 1038 |
| 1008 void SafeBrowsingDatabaseNew::CacheHashResults( | 1039 void SafeBrowsingDatabaseNew::CacheHashResults( |
| 1009 const std::vector<SBPrefix>& prefixes, | 1040 const std::vector<SBPrefix>& prefixes, |
| 1010 const std::vector<SBFullHashResult>& full_hits, | 1041 const std::vector<SBFullHashResult>& full_hits, |
| 1011 const base::TimeDelta& cache_lifetime) { | 1042 const base::TimeDelta& cache_lifetime) { |
| 1043 // This method is theoretically thread-safe but document that it is currently | |
| 1044 // only expected to be called on the IO thread. | |
| 1045 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1046 | |
| 1012 const base::Time expire_after = base::Time::Now() + cache_lifetime; | 1047 const base::Time expire_after = base::Time::Now() + cache_lifetime; |
| 1013 | 1048 |
| 1014 // This is called on the I/O thread, lock against updates. | |
| 1015 base::AutoLock locked(lookup_lock_); | 1049 base::AutoLock locked(lookup_lock_); |
| 1016 | 1050 |
| 1017 // Create or reset all cached results for these prefixes. | 1051 // Create or reset all cached results for these prefixes. |
| 1018 for (size_t i = 0; i < prefixes.size(); ++i) { | 1052 for (size_t i = 0; i < prefixes.size(); ++i) { |
| 1019 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after); | 1053 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after); |
| 1020 } | 1054 } |
| 1021 | 1055 |
| 1022 // Insert any fullhash hits. Note that there may be one, multiple, or no | 1056 // Insert any fullhash hits. Note that there may be one, multiple, or no |
| 1023 // fullhashes for any given entry in |prefixes|. | 1057 // fullhashes for any given entry in |prefixes|. |
| 1024 for (size_t i = 0; i < full_hits.size(); ++i) { | 1058 for (size_t i = 0; i < full_hits.size(); ++i) { |
| 1025 const SBPrefix prefix = full_hits[i].hash.prefix; | 1059 const SBPrefix prefix = full_hits[i].hash.prefix; |
| 1026 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]); | 1060 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]); |
| 1027 } | 1061 } |
| 1028 } | 1062 } |
| 1029 | 1063 |
| 1030 bool SafeBrowsingDatabaseNew::UpdateStarted( | 1064 bool SafeBrowsingDatabaseNew::UpdateStarted( |
| 1031 std::vector<SBListChunkRanges>* lists) { | 1065 std::vector<SBListChunkRanges>* lists) { |
| 1032 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1066 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1033 DCHECK(lists); | 1067 DCHECK(lists); |
| 1034 | 1068 |
| 1035 // If |BeginUpdate()| fails, reset the database. | 1069 // If |BeginUpdate()| fails, reset the database. |
| 1036 if (!browse_store_->BeginUpdate()) { | 1070 if (!browse_store_->BeginUpdate()) { |
| 1037 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); | 1071 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); |
| 1038 HandleCorruptDatabase(); | 1072 HandleCorruptDatabase(); |
| 1039 return false; | 1073 return false; |
| 1040 } | 1074 } |
| 1041 | 1075 |
| 1042 if (download_store_.get() && !download_store_->BeginUpdate()) { | 1076 if (download_store_.get() && !download_store_->BeginUpdate()) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 UpdateChunkRangesForList(unwanted_software_store_.get(), | 1155 UpdateChunkRangesForList(unwanted_software_store_.get(), |
| 1122 safe_browsing_util::kUnwantedUrlList, | 1156 safe_browsing_util::kUnwantedUrlList, |
| 1123 lists); | 1157 lists); |
| 1124 | 1158 |
| 1125 corruption_detected_ = false; | 1159 corruption_detected_ = false; |
| 1126 change_detected_ = false; | 1160 change_detected_ = false; |
| 1127 return true; | 1161 return true; |
| 1128 } | 1162 } |
| 1129 | 1163 |
| 1130 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { | 1164 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { |
| 1131 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1165 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1132 | 1166 |
| 1133 // The update may have failed due to corrupt storage (for instance, | 1167 // The update may have failed due to corrupt storage (for instance, |
| 1134 // an excessive number of invalid add_chunks and sub_chunks). | 1168 // an excessive number of invalid add_chunks and sub_chunks). |
| 1135 // Double-check that the databases are valid. | 1169 // Double-check that the databases are valid. |
| 1136 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk | 1170 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk |
| 1137 // sections would allow throwing a corruption error in | 1171 // sections would allow throwing a corruption error in |
| 1138 // UpdateStarted(). | 1172 // UpdateStarted(). |
| 1139 if (!update_succeeded) { | 1173 if (!update_succeeded) { |
| 1140 if (!browse_store_->CheckValidity()) | 1174 if (!browse_store_->CheckValidity()) |
| 1141 DLOG(ERROR) << "Safe-browsing browse database corrupt."; | 1175 DLOG(ERROR) << "Safe-browsing browse database corrupt."; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1243 &unwanted_software_prefix_set_, | 1277 &unwanted_software_prefix_set_, |
| 1244 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, | 1278 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, |
| 1245 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE); | 1279 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE); |
| 1246 } | 1280 } |
| 1247 } | 1281 } |
| 1248 | 1282 |
| 1249 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( | 1283 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( |
| 1250 const base::FilePath& store_filename, | 1284 const base::FilePath& store_filename, |
| 1251 SafeBrowsingStore* store, | 1285 SafeBrowsingStore* store, |
| 1252 SBWhitelist* whitelist) { | 1286 SBWhitelist* whitelist) { |
| 1287 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1288 | |
| 1253 if (!store) | 1289 if (!store) |
| 1254 return; | 1290 return; |
| 1255 | 1291 |
| 1256 // Note: |builder| will not be empty. The current data store implementation | 1292 // Note: |builder| will not be empty. The current data store implementation |
| 1257 // stores all full-length hashes as both full and prefix hashes. | 1293 // stores all full-length hashes as both full and prefix hashes. |
| 1258 safe_browsing::PrefixSetBuilder builder; | 1294 safe_browsing::PrefixSetBuilder builder; |
| 1259 std::vector<SBAddFullHash> full_hashes; | 1295 std::vector<SBAddFullHash> full_hashes; |
| 1260 if (!store->FinishUpdate(&builder, &full_hashes)) { | 1296 if (!store->FinishUpdate(&builder, &full_hashes)) { |
| 1261 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); | 1297 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); |
| 1262 WhitelistEverything(whitelist); | 1298 WhitelistEverything(whitelist); |
| 1263 return; | 1299 return; |
| 1264 } | 1300 } |
| 1265 | 1301 |
| 1266 #if defined(OS_MACOSX) | 1302 #if defined(OS_MACOSX) |
| 1267 base::mac::SetFileBackupExclusion(store_filename); | 1303 base::mac::SetFileBackupExclusion(store_filename); |
| 1268 #endif | 1304 #endif |
| 1269 | 1305 |
| 1270 LoadWhitelist(full_hashes, whitelist); | 1306 LoadWhitelist(full_hashes, whitelist); |
| 1271 } | 1307 } |
| 1272 | 1308 |
| 1273 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( | 1309 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( |
| 1274 const base::FilePath& store_filename, | 1310 const base::FilePath& store_filename, |
| 1275 SafeBrowsingStore* store, | 1311 SafeBrowsingStore* store, |
| 1276 FailureType failure_type) { | 1312 FailureType failure_type) { |
| 1313 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1314 | |
| 1277 // These results are not used after this call. Simply ignore the | 1315 // These results are not used after this call. Simply ignore the |
| 1278 // returned value after FinishUpdate(...). | 1316 // returned value after FinishUpdate(...). |
| 1279 safe_browsing::PrefixSetBuilder builder; | 1317 safe_browsing::PrefixSetBuilder builder; |
| 1280 std::vector<SBAddFullHash> add_full_hashes_result; | 1318 std::vector<SBAddFullHash> add_full_hashes_result; |
| 1281 | 1319 |
| 1282 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) | 1320 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) |
| 1283 RecordFailure(failure_type); | 1321 RecordFailure(failure_type); |
| 1284 | 1322 |
| 1285 #if defined(OS_MACOSX) | 1323 #if defined(OS_MACOSX) |
| 1286 base::mac::SetFileBackupExclusion(store_filename); | 1324 base::mac::SetFileBackupExclusion(store_filename); |
| 1287 #endif | 1325 #endif |
| 1288 | 1326 |
| 1289 return GetFileSizeOrZero(store_filename); | 1327 return GetFileSizeOrZero(store_filename); |
| 1290 } | 1328 } |
| 1291 | 1329 |
| 1292 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( | 1330 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( |
| 1293 const base::FilePath& db_filename, | 1331 const base::FilePath& db_filename, |
| 1294 SafeBrowsingStore* url_store, | 1332 SafeBrowsingStore* url_store, |
| 1295 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, | 1333 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, |
| 1296 FailureType finish_failure_type, | 1334 FailureType finish_failure_type, |
| 1297 FailureType write_failure_type) { | 1335 FailureType write_failure_type) { |
| 1336 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1337 | |
| 1298 // Measure the amount of IO during the filter build. | 1338 // Measure the amount of IO during the filter build. |
| 1299 base::IoCounters io_before, io_after; | 1339 base::IoCounters io_before, io_after; |
| 1300 base::ProcessHandle handle = base::GetCurrentProcessHandle(); | 1340 base::ProcessHandle handle = base::GetCurrentProcessHandle(); |
| 1301 scoped_ptr<base::ProcessMetrics> metric( | 1341 scoped_ptr<base::ProcessMetrics> metric( |
| 1302 #if !defined(OS_MACOSX) | 1342 #if !defined(OS_MACOSX) |
| 1303 base::ProcessMetrics::CreateProcessMetrics(handle) | 1343 base::ProcessMetrics::CreateProcessMetrics(handle) |
| 1304 #else | 1344 #else |
| 1305 // Getting stats only for the current process is enough, so NULL is fine. | 1345 // Getting stats only for the current process is enough, so NULL is fine. |
| 1306 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) | 1346 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) |
| 1307 #endif | 1347 #endif |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1365 const int64 file_size = GetFileSizeOrZero(db_filename); | 1405 const int64 file_size = GetFileSizeOrZero(db_filename); |
| 1366 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", | 1406 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", |
| 1367 static_cast<int>(file_size / 1024)); | 1407 static_cast<int>(file_size / 1024)); |
| 1368 | 1408 |
| 1369 #if defined(OS_MACOSX) | 1409 #if defined(OS_MACOSX) |
| 1370 base::mac::SetFileBackupExclusion(db_filename); | 1410 base::mac::SetFileBackupExclusion(db_filename); |
| 1371 #endif | 1411 #endif |
| 1372 } | 1412 } |
| 1373 | 1413 |
| 1374 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { | 1414 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { |
| 1415 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1416 | |
| 1375 safe_browsing::PrefixSetBuilder builder; | 1417 safe_browsing::PrefixSetBuilder builder; |
| 1376 std::vector<SBAddFullHash> add_full_hashes_result; | 1418 std::vector<SBAddFullHash> add_full_hashes_result; |
| 1377 | 1419 |
| 1378 if (!side_effect_free_whitelist_store_->FinishUpdate( | 1420 if (!side_effect_free_whitelist_store_->FinishUpdate( |
| 1379 &builder, &add_full_hashes_result)) { | 1421 &builder, &add_full_hashes_result)) { |
| 1380 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); | 1422 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); |
| 1381 return; | 1423 return; |
| 1382 } | 1424 } |
| 1383 scoped_ptr<safe_browsing::PrefixSet> | 1425 scoped_ptr<safe_browsing::PrefixSet> |
| 1384 prefix_set(builder.GetPrefixSetNoHashes()); | 1426 prefix_set(builder.GetPrefixSetNoHashes()); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1412 static_cast<int>(file_size / 1024)); | 1454 static_cast<int>(file_size / 1024)); |
| 1413 | 1455 |
| 1414 #if defined(OS_MACOSX) | 1456 #if defined(OS_MACOSX) |
| 1415 base::mac::SetFileBackupExclusion(side_effect_free_whitelist_filename); | 1457 base::mac::SetFileBackupExclusion(side_effect_free_whitelist_filename); |
| 1416 base::mac::SetFileBackupExclusion( | 1458 base::mac::SetFileBackupExclusion( |
| 1417 side_effect_free_whitelist_prefix_set_filename); | 1459 side_effect_free_whitelist_prefix_set_filename); |
| 1418 #endif | 1460 #endif |
| 1419 } | 1461 } |
| 1420 | 1462 |
| 1421 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { | 1463 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { |
| 1464 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1465 | |
| 1422 // Note: prefixes will not be empty. The current data store implementation | 1466 // Note: prefixes will not be empty. The current data store implementation |
| 1423 // stores all full-length hashes as both full and prefix hashes. | 1467 // stores all full-length hashes as both full and prefix hashes. |
| 1424 safe_browsing::PrefixSetBuilder builder; | 1468 safe_browsing::PrefixSetBuilder builder; |
| 1425 std::vector<SBAddFullHash> full_hashes; | 1469 std::vector<SBAddFullHash> full_hashes; |
| 1426 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { | 1470 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { |
| 1427 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); | 1471 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); |
| 1428 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. | 1472 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. |
| 1429 return; | 1473 return; |
| 1430 } | 1474 } |
| 1431 | 1475 |
| 1432 #if defined(OS_MACOSX) | 1476 #if defined(OS_MACOSX) |
| 1433 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_)); | 1477 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_)); |
| 1434 #endif | 1478 #endif |
| 1435 | 1479 |
| 1436 LoadIpBlacklist(full_hashes); | 1480 LoadIpBlacklist(full_hashes); |
| 1437 } | 1481 } |
| 1438 | 1482 |
| 1439 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { | 1483 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { |
| 1484 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1485 | |
| 1440 // Reset the database after the current task has unwound (but only | 1486 // Reset the database after the current task has unwound (but only |
| 1441 // reset once within the scope of a given task). | 1487 // reset once within the scope of a given task). |
| 1442 if (!reset_factory_.HasWeakPtrs()) { | 1488 if (!reset_factory_.HasWeakPtrs()) { |
| 1443 RecordFailure(FAILURE_DATABASE_CORRUPT); | 1489 RecordFailure(FAILURE_DATABASE_CORRUPT); |
| 1444 base::MessageLoop::current()->PostTask(FROM_HERE, | 1490 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 1445 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, | 1491 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, |
| 1446 reset_factory_.GetWeakPtr())); | 1492 reset_factory_.GetWeakPtr())); |
| 1447 } | 1493 } |
| 1448 } | 1494 } |
| 1449 | 1495 |
| 1450 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { | 1496 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { |
| 1497 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1498 | |
| 1451 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); | 1499 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); |
| 1452 corruption_detected_ = true; // Stop updating the database. | 1500 corruption_detected_ = true; // Stop updating the database. |
| 1453 ResetDatabase(); | 1501 ResetDatabase(); |
| 1454 | 1502 |
| 1455 // NOTE(shess): ResetDatabase() should remove the corruption, so this should | 1503 // NOTE(shess): ResetDatabase() should remove the corruption, so this should |
| 1456 // only happen once. If you are here because you are hitting this after a | 1504 // only happen once. If you are here because you are hitting this after a |
| 1457 // restart, then I would be very interested in working with you to figure out | 1505 // restart, then I would be very interested in working with you to figure out |
| 1458 // what is happening, since it may affect real users. | 1506 // what is happening, since it may affect real users. |
| 1459 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; | 1507 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; |
| 1460 } | 1508 } |
| 1461 | 1509 |
| 1462 // TODO(shess): I'm not clear why this code doesn't have any | 1510 // TODO(shess): I'm not clear why this code doesn't have any |
| 1463 // real error-handling. | 1511 // real error-handling. |
| 1464 void SafeBrowsingDatabaseNew::LoadPrefixSet( | 1512 void SafeBrowsingDatabaseNew::LoadPrefixSet( |
| 1465 const base::FilePath& db_filename, | 1513 const base::FilePath& db_filename, |
| 1466 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, | 1514 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, |
| 1467 FailureType read_failure_type) { | 1515 FailureType read_failure_type) { |
| 1516 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1517 | |
| 1468 if (!prefix_set) | 1518 if (!prefix_set) |
| 1469 return; | 1519 return; |
| 1470 | 1520 |
| 1471 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | |
| 1472 DCHECK(!filename_base_.empty()); | 1521 DCHECK(!filename_base_.empty()); |
| 1473 | 1522 |
| 1474 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); | 1523 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); |
| 1475 | 1524 |
| 1476 // Only use the prefix set if database is present and non-empty. | 1525 // Only use the prefix set if database is present and non-empty. |
| 1477 if (!GetFileSizeOrZero(db_filename)) | 1526 if (!GetFileSizeOrZero(db_filename)) |
| 1478 return; | 1527 return; |
| 1479 | 1528 |
| 1480 // Cleanup any stale bloom filter (no longer used). | 1529 // Cleanup any stale bloom filter (no longer used). |
| 1481 // TODO(shess): Track existence to drive removal of this code? | 1530 // TODO(shess): Track existence to drive removal of this code? |
| 1482 const base::FilePath bloom_filter_filename = | 1531 const base::FilePath bloom_filter_filename = |
| 1483 BloomFilterForFilename(db_filename); | 1532 BloomFilterForFilename(db_filename); |
| 1484 base::DeleteFile(bloom_filter_filename, false); | 1533 base::DeleteFile(bloom_filter_filename, false); |
| 1485 | 1534 |
| 1486 const base::TimeTicks before = base::TimeTicks::Now(); | 1535 const base::TimeTicks before = base::TimeTicks::Now(); |
| 1487 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename); | 1536 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename); |
| 1488 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); | 1537 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); |
| 1489 | 1538 |
| 1490 if (!prefix_set->get()) | 1539 if (!prefix_set->get()) |
| 1491 RecordFailure(read_failure_type); | 1540 RecordFailure(read_failure_type); |
| 1492 } | 1541 } |
| 1493 | 1542 |
| 1494 bool SafeBrowsingDatabaseNew::Delete() { | 1543 bool SafeBrowsingDatabaseNew::Delete() { |
| 1495 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1544 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1496 DCHECK(!filename_base_.empty()); | 1545 DCHECK(!filename_base_.empty()); |
| 1497 | 1546 |
| 1498 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the | 1547 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the |
| 1499 // store before calling DeleteStore(). DeleteStore() deletes transient files | 1548 // store before calling DeleteStore(). DeleteStore() deletes transient files |
| 1500 // in addition to the main file. Probably all of these should be converted to | 1549 // in addition to the main file. Probably all of these should be converted to |
| 1501 // a helper which calls Delete() if the store exists, else DeleteStore() on | 1550 // a helper which calls Delete() if the store exists, else DeleteStore() on |
| 1502 // the generated filename. | 1551 // the generated filename. |
| 1503 | 1552 |
| 1504 // TODO(shess): Determine if the histograms are useful in any way. I cannot | 1553 // TODO(shess): Determine if the histograms are useful in any way. I cannot |
| 1505 // recall any action taken as a result of their values, in which case it might | 1554 // recall any action taken as a result of their values, in which case it might |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1568 if (!r11) | 1617 if (!r11) |
| 1569 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); | 1618 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); |
| 1570 | 1619 |
| 1571 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; | 1620 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; |
| 1572 } | 1621 } |
| 1573 | 1622 |
| 1574 void SafeBrowsingDatabaseNew::WritePrefixSet( | 1623 void SafeBrowsingDatabaseNew::WritePrefixSet( |
| 1575 const base::FilePath& db_filename, | 1624 const base::FilePath& db_filename, |
| 1576 safe_browsing::PrefixSet* prefix_set, | 1625 safe_browsing::PrefixSet* prefix_set, |
| 1577 FailureType write_failure_type) { | 1626 FailureType write_failure_type) { |
| 1578 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1627 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1579 | 1628 |
| 1580 if (!prefix_set) | 1629 if (!prefix_set) |
| 1581 return; | 1630 return; |
| 1582 | 1631 |
| 1583 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); | 1632 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); |
| 1584 | 1633 |
| 1585 const base::TimeTicks before = base::TimeTicks::Now(); | 1634 const base::TimeTicks before = base::TimeTicks::Now(); |
| 1586 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); | 1635 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); |
| 1587 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); | 1636 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); |
| 1588 | 1637 |
| 1589 const int64 file_size = GetFileSizeOrZero(prefix_set_filename); | 1638 const int64 file_size = GetFileSizeOrZero(prefix_set_filename); |
| 1590 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes", | 1639 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes", |
| 1591 static_cast<int>(file_size / 1024)); | 1640 static_cast<int>(file_size / 1024)); |
| 1592 | 1641 |
| 1593 if (!write_ok) | 1642 if (!write_ok) |
| 1594 RecordFailure(write_failure_type); | 1643 RecordFailure(write_failure_type); |
| 1595 | 1644 |
| 1596 #if defined(OS_MACOSX) | 1645 #if defined(OS_MACOSX) |
| 1597 base::mac::SetFileBackupExclusion(prefix_set_filename); | 1646 base::mac::SetFileBackupExclusion(prefix_set_filename); |
| 1598 #endif | 1647 #endif |
| 1599 } | 1648 } |
| 1600 | 1649 |
| 1601 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { | 1650 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { |
| 1651 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1602 base::AutoLock locked(lookup_lock_); | 1652 base::AutoLock locked(lookup_lock_); |
| 1603 whitelist->second = true; | 1653 whitelist->second = true; |
| 1604 whitelist->first.clear(); | 1654 whitelist->first.clear(); |
| 1605 } | 1655 } |
| 1606 | 1656 |
| 1607 void SafeBrowsingDatabaseNew::LoadWhitelist( | 1657 void SafeBrowsingDatabaseNew::LoadWhitelist( |
| 1608 const std::vector<SBAddFullHash>& full_hashes, | 1658 const std::vector<SBAddFullHash>& full_hashes, |
| 1609 SBWhitelist* whitelist) { | 1659 SBWhitelist* whitelist) { |
| 1610 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1660 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1661 | |
| 1611 if (full_hashes.size() > kMaxWhitelistSize) { | 1662 if (full_hashes.size() > kMaxWhitelistSize) { |
| 1612 WhitelistEverything(whitelist); | 1663 WhitelistEverything(whitelist); |
| 1613 return; | 1664 return; |
| 1614 } | 1665 } |
| 1615 | 1666 |
| 1616 std::vector<SBFullHash> new_whitelist; | 1667 std::vector<SBFullHash> new_whitelist; |
| 1617 new_whitelist.reserve(full_hashes.size()); | 1668 new_whitelist.reserve(full_hashes.size()); |
| 1618 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); | 1669 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); |
| 1619 it != full_hashes.end(); ++it) { | 1670 it != full_hashes.end(); ++it) { |
| 1620 new_whitelist.push_back(it->full_hash); | 1671 new_whitelist.push_back(it->full_hash); |
| 1621 } | 1672 } |
| 1622 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess); | 1673 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess); |
| 1623 | 1674 |
| 1624 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl); | 1675 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl); |
| 1625 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), | 1676 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), |
| 1626 kill_switch, SBFullHashLess)) { | 1677 kill_switch, SBFullHashLess)) { |
| 1627 // The kill switch is whitelisted hence we whitelist all URLs. | 1678 // The kill switch is whitelisted hence we whitelist all URLs. |
| 1628 WhitelistEverything(whitelist); | 1679 WhitelistEverything(whitelist); |
| 1629 } else { | 1680 } else { |
| 1630 base::AutoLock locked(lookup_lock_); | 1681 base::AutoLock locked(lookup_lock_); |
| 1631 whitelist->second = false; | 1682 whitelist->second = false; |
| 1632 whitelist->first.swap(new_whitelist); | 1683 whitelist->first.swap(new_whitelist); |
| 1633 } | 1684 } |
| 1634 } | 1685 } |
| 1635 | 1686 |
| 1636 void SafeBrowsingDatabaseNew::LoadIpBlacklist( | 1687 void SafeBrowsingDatabaseNew::LoadIpBlacklist( |
| 1637 const std::vector<SBAddFullHash>& full_hashes) { | 1688 const std::vector<SBAddFullHash>& full_hashes) { |
| 1638 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1689 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1690 | |
| 1639 IPBlacklist new_blacklist; | 1691 IPBlacklist new_blacklist; |
| 1640 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); | 1692 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); |
| 1641 it != full_hashes.end(); | 1693 it != full_hashes.end(); |
| 1642 ++it) { | 1694 ++it) { |
| 1643 const char* full_hash = it->full_hash.full_hash; | 1695 const char* full_hash = it->full_hash.full_hash; |
| 1644 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); | 1696 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); |
| 1645 // The format of the IP blacklist is: | 1697 // The format of the IP blacklist is: |
| 1646 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. | 1698 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. |
| 1647 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); | 1699 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); |
| 1648 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); | 1700 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1667 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), | 1719 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), |
| 1668 hashed_ip_prefix.size()); | 1720 hashed_ip_prefix.size()); |
| 1669 new_blacklist[mask].insert(hashed_ip_prefix); | 1721 new_blacklist[mask].insert(hashed_ip_prefix); |
| 1670 } | 1722 } |
| 1671 | 1723 |
| 1672 base::AutoLock locked(lookup_lock_); | 1724 base::AutoLock locked(lookup_lock_); |
| 1673 ip_blacklist_.swap(new_blacklist); | 1725 ip_blacklist_.swap(new_blacklist); |
| 1674 } | 1726 } |
| 1675 | 1727 |
| 1676 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { | 1728 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
| 1729 // This method is theoretically thread-safe but document that it is currently | |
| 1730 // only expected to be called on the IO thread. | |
| 1731 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1732 | |
| 1677 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1733 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
| 1678 std::vector<SBFullHash> full_hashes; | 1734 std::vector<SBFullHash> full_hashes; |
| 1679 full_hashes.push_back(malware_kill_switch); | 1735 full_hashes.push_back(malware_kill_switch); |
| 1680 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1736 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
| 1681 } | 1737 } |
| 1682 | 1738 |
| 1683 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { | 1739 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { |
| 1740 // This method is theoretically thread-safe but document that it is currently | |
| 1741 // only expected to be called on the IO thread. | |
| 1742 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
|
mattm
2014/12/03 22:57:08
Actually this function does not look safe. It shou
gab
2014/12/04 19:57:27
Ah ah, indeed, this is exactly why I want to alter
| |
| 1743 | |
| 1684 return csd_whitelist_.second; | 1744 return csd_whitelist_.second; |
| 1685 } | 1745 } |
| OLD | NEW |