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

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

Issue 744183002: More explicit thread checking in SafeBrowsingDatabase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a3_deadcode
Patch Set: Created 6 years 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
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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698