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

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: crbug.com/338486 forces thread-checks to be disabled in ~SafeBrowsingStoreFile() 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 std::vector<SBAddFullHash> full_hashes; 630 std::vector<SBAddFullHash> full_hashes;
629 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { 631 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) {
630 LoadIpBlacklist(full_hashes); 632 LoadIpBlacklist(full_hashes);
631 } else { 633 } else {
632 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 634 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
633 } 635 }
634 } 636 }
635 } 637 }
636 638
637 bool SafeBrowsingDatabaseNew::ResetDatabase() { 639 bool SafeBrowsingDatabaseNew::ResetDatabase() {
638 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 640 DCHECK(thread_checker_.CalledOnValidThread());
639 641
640 // Delete files on disk. 642 // Delete files on disk.
641 // TODO(shess): Hard to see where one might want to delete without a 643 // TODO(shess): Hard to see where one might want to delete without a
642 // reset. Perhaps inline |Delete()|? 644 // reset. Perhaps inline |Delete()|?
643 if (!Delete()) 645 if (!Delete())
644 return false; 646 return false;
645 647
646 // Reset objects in memory. 648 // Reset objects in memory.
647 { 649 {
648 base::AutoLock locked(lookup_lock_); 650 base::AutoLock locked(lookup_lock_);
649 prefix_gethash_cache_.clear(); 651 prefix_gethash_cache_.clear();
650 browse_prefix_set_.reset(); 652 browse_prefix_set_.reset();
651 side_effect_free_whitelist_prefix_set_.reset(); 653 side_effect_free_whitelist_prefix_set_.reset();
652 ip_blacklist_.clear(); 654 ip_blacklist_.clear();
653 unwanted_software_prefix_set_.reset(); 655 unwanted_software_prefix_set_.reset();
654 } 656 }
655 // Wants to acquire the lock itself. 657 // Wants to acquire the lock itself.
656 WhitelistEverything(&csd_whitelist_); 658 WhitelistEverything(&csd_whitelist_);
657 WhitelistEverything(&download_whitelist_); 659 WhitelistEverything(&download_whitelist_);
658 return true; 660 return true;
659 } 661 }
660 662
661 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( 663 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl(
662 const GURL& url, 664 const GURL& url,
663 std::vector<SBPrefix>* prefix_hits, 665 std::vector<SBPrefix>* prefix_hits,
664 std::vector<SBFullHashResult>* cache_hits) { 666 std::vector<SBFullHashResult>* cache_hits) {
667 // This method is theoretically thread-safe but document that it is currently
668 // only expected to be called on the IO thread.
669 DCHECK_CURRENTLY_ON(BrowserThread::IO);
mattm 2014/12/12 23:50:44 Think I still don't see the benefit of these docum
gab 2014/12/15 22:05:37 Ok, agreed, they mostly helped me understanding ho
670
665 return PrefixSetContainsUrl( 671 return PrefixSetContainsUrl(
666 url, &browse_prefix_set_, prefix_hits, cache_hits); 672 url, &browse_prefix_set_, prefix_hits, cache_hits);
667 } 673 }
668 674
669 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( 675 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl(
670 const GURL& url, 676 const GURL& url,
671 std::vector<SBPrefix>* prefix_hits, 677 std::vector<SBPrefix>* prefix_hits,
672 std::vector<SBFullHashResult>* cache_hits) { 678 std::vector<SBFullHashResult>* cache_hits) {
679 // This method is theoretically thread-safe but document that it is currently
680 // only expected to be called on the IO thread.
681 DCHECK_CURRENTLY_ON(BrowserThread::IO);
682
673 return PrefixSetContainsUrl( 683 return PrefixSetContainsUrl(
674 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); 684 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits);
675 } 685 }
676 686
677 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( 687 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl(
678 const GURL& url, 688 const GURL& url,
679 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 689 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter,
680 std::vector<SBPrefix>* prefix_hits, 690 std::vector<SBPrefix>* prefix_hits,
681 std::vector<SBFullHashResult>* cache_hits) { 691 std::vector<SBFullHashResult>* cache_hits) {
692 // This method is theoretically thread-safe but document that it is currently
693 // only expected to be called on the IO thread.
694 DCHECK_CURRENTLY_ON(BrowserThread::IO);
695
682 // Clear the results first. 696 // Clear the results first.
683 prefix_hits->clear(); 697 prefix_hits->clear();
684 cache_hits->clear(); 698 cache_hits->clear();
685 699
686 std::vector<SBFullHash> full_hashes; 700 std::vector<SBFullHash> full_hashes;
687 UrlToFullHashes(url, false, &full_hashes); 701 UrlToFullHashes(url, false, &full_hashes);
688 if (full_hashes.empty()) 702 if (full_hashes.empty())
689 return false; 703 return false;
690 704
691 return PrefixSetContainsUrlHashes( 705 return PrefixSetContainsUrlHashes(
692 full_hashes, prefix_set_getter, prefix_hits, cache_hits); 706 full_hashes, prefix_set_getter, prefix_hits, cache_hits);
693 } 707 }
694 708
695 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( 709 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting(
696 const std::vector<SBFullHash>& full_hashes, 710 const std::vector<SBFullHash>& full_hashes,
697 std::vector<SBPrefix>* prefix_hits, 711 std::vector<SBPrefix>* prefix_hits,
698 std::vector<SBFullHashResult>* cache_hits) { 712 std::vector<SBFullHashResult>* cache_hits) {
699 return PrefixSetContainsUrlHashes( 713 return PrefixSetContainsUrlHashes(
700 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); 714 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits);
701 } 715 }
702 716
703 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( 717 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes(
704 const std::vector<SBFullHash>& full_hashes, 718 const std::vector<SBFullHash>& full_hashes,
705 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 719 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter,
706 std::vector<SBPrefix>* prefix_hits, 720 std::vector<SBPrefix>* prefix_hits,
707 std::vector<SBFullHashResult>* cache_hits) { 721 std::vector<SBFullHashResult>* cache_hits) {
722 // This method is theoretically thread-safe but document that it is currently
723 // only expected to be called on the IO thread.
724 DCHECK_CURRENTLY_ON(BrowserThread::IO);
725
708 // Used to determine cache expiration. 726 // Used to determine cache expiration.
709 const base::Time now = base::Time::Now(); 727 const base::Time now = base::Time::Now();
710 728
711 // This function is called on the I/O thread, prevent changes to
712 // filter and caches.
713 base::AutoLock locked(lookup_lock_); 729 base::AutoLock locked(lookup_lock_);
714 730
715 // |prefix_set| is empty until it is either read from disk, or the first 731 // |prefix_set| is empty until it is either read from disk, or the first
716 // update populates it. Bail out without a hit if not yet available. 732 // update populates it. Bail out without a hit if not yet available.
717 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence 733 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence
718 // why it is passed as a parameter rather than passing the |prefix_set| 734 // why it is passed as a parameter rather than passing the |prefix_set|
719 // directly. 735 // directly.
720 const safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); 736 const safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get();
721 if (!prefix_set) 737 if (!prefix_set)
722 return false; 738 return false;
(...skipping 11 matching lines...) Expand all
734 std::sort(prefix_hits->begin(), prefix_hits->end()); 750 std::sort(prefix_hits->begin(), prefix_hits->end());
735 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), 751 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()),
736 prefix_hits->end()); 752 prefix_hits->end());
737 753
738 return !prefix_hits->empty() || !cache_hits->empty(); 754 return !prefix_hits->empty() || !cache_hits->empty();
739 } 755 }
740 756
741 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( 757 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl(
742 const std::vector<GURL>& urls, 758 const std::vector<GURL>& urls,
743 std::vector<SBPrefix>* prefix_hits) { 759 std::vector<SBPrefix>* prefix_hits) {
744 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 760 DCHECK(thread_checker_.CalledOnValidThread());
745 761
746 // Ignore this check when download checking is not enabled. 762 // Ignore this check when download checking is not enabled.
747 if (!download_store_.get()) 763 if (!download_store_.get())
748 return false; 764 return false;
749 765
750 std::vector<SBPrefix> prefixes; 766 std::vector<SBPrefix> prefixes;
751 GetDownloadUrlPrefixes(urls, &prefixes); 767 GetDownloadUrlPrefixes(urls, &prefixes);
752 return MatchAddPrefixes(download_store_.get(), 768 return MatchAddPrefixes(download_store_.get(),
753 safe_browsing_util::BINURL % 2, 769 safe_browsing_util::BINURL % 2,
754 prefixes, 770 prefixes,
755 prefix_hits); 771 prefix_hits);
756 } 772 }
757 773
758 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { 774 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) {
759 // This method is theoretically thread-safe but we expect all calls to 775 // This method is theoretically thread-safe but document that it is currently
760 // originate from the IO thread. 776 // only expected to be called on the IO thread.
761 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 777 DCHECK_CURRENTLY_ON(BrowserThread::IO);
778
762 std::vector<SBFullHash> full_hashes; 779 std::vector<SBFullHash> full_hashes;
763 UrlToFullHashes(url, true, &full_hashes); 780 UrlToFullHashes(url, true, &full_hashes);
764 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 781 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
765 } 782 }
766 783
767 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { 784 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) {
768 std::vector<SBFullHash> full_hashes; 785 std::vector<SBFullHash> full_hashes;
769 UrlToFullHashes(url, true, &full_hashes); 786 UrlToFullHashes(url, true, &full_hashes);
770 return ContainsWhitelistedHashes(download_whitelist_, full_hashes); 787 return ContainsWhitelistedHashes(download_whitelist_, full_hashes);
771 } 788 }
772 789
773 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( 790 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes(
774 const std::vector<SBPrefix>& prefixes, 791 const std::vector<SBPrefix>& prefixes,
775 std::vector<SBPrefix>* prefix_hits) { 792 std::vector<SBPrefix>* prefix_hits) {
776 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 793 DCHECK(thread_checker_.CalledOnValidThread());
794
777 if (!extension_blacklist_store_) 795 if (!extension_blacklist_store_)
778 return false; 796 return false;
779 797
780 return MatchAddPrefixes(extension_blacklist_store_.get(), 798 return MatchAddPrefixes(extension_blacklist_store_.get(),
781 safe_browsing_util::EXTENSIONBLACKLIST % 2, 799 safe_browsing_util::EXTENSIONBLACKLIST % 2,
782 prefixes, 800 prefixes,
783 prefix_hits); 801 prefix_hits);
784 } 802 }
785 803
786 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( 804 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl(
787 const GURL& url) { 805 const GURL& url) {
806 // This method is theoretically thread-safe but document that it is currently
807 // only expected to be called on the UI thread.
808 DCHECK_CURRENTLY_ON(BrowserThread::UI);
809
788 std::string host; 810 std::string host;
789 std::string path; 811 std::string path;
790 std::string query; 812 std::string query;
791 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query); 813 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query);
792 std::string url_to_check = host + path; 814 std::string url_to_check = host + path;
793 if (!query.empty()) 815 if (!query.empty())
794 url_to_check += "?" + query; 816 url_to_check += "?" + query;
795 SBFullHash full_hash = SBFullHashForString(url_to_check); 817 SBFullHash full_hash = SBFullHashForString(url_to_check);
796 818
797 // This function can be called on any thread, so lock against any changes
798 base::AutoLock locked(lookup_lock_); 819 base::AutoLock locked(lookup_lock_);
799 820
800 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read 821 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read
801 // from disk, or the first update populates it. Bail out without a hit if 822 // from disk, or the first update populates it. Bail out without a hit if
802 // not yet available. 823 // not yet available.
803 if (!side_effect_free_whitelist_prefix_set_.get()) 824 if (!side_effect_free_whitelist_prefix_set_.get())
804 return false; 825 return false;
805 826
806 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); 827 return side_effect_free_whitelist_prefix_set_->Exists(full_hash);
807 } 828 }
808 829
809 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { 830 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) {
831 // This method is theoretically thread-safe but document that it is currently
832 // only expected to be called on the IO thread.
833 DCHECK_CURRENTLY_ON(BrowserThread::IO);
834
810 net::IPAddressNumber ip_number; 835 net::IPAddressNumber ip_number;
811 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) 836 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number))
812 return false; 837 return false;
813 if (ip_number.size() == net::kIPv4AddressSize) 838 if (ip_number.size() == net::kIPv4AddressSize)
814 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); 839 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number);
815 if (ip_number.size() != net::kIPv6AddressSize) 840 if (ip_number.size() != net::kIPv6AddressSize)
816 return false; // better safe than sorry. 841 return false; // better safe than sorry.
817 842
818 // This function can be called from any thread.
819 base::AutoLock locked(lookup_lock_); 843 base::AutoLock locked(lookup_lock_);
820 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); 844 for (IPBlacklist::const_iterator it = ip_blacklist_.begin();
821 it != ip_blacklist_.end(); 845 it != ip_blacklist_.end();
822 ++it) { 846 ++it) {
823 const std::string& mask = it->first; 847 const std::string& mask = it->first;
824 DCHECK_EQ(mask.size(), ip_number.size()); 848 DCHECK_EQ(mask.size(), ip_number.size());
825 std::string subnet(net::kIPv6AddressSize, '\0'); 849 std::string subnet(net::kIPv6AddressSize, '\0');
826 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { 850 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) {
827 subnet[i] = ip_number[i] & mask[i]; 851 subnet[i] = ip_number[i] & mask[i];
828 } 852 }
829 const std::string hash = base::SHA1HashString(subnet); 853 const std::string hash = base::SHA1HashString(subnet);
830 DVLOG(2) << "Lookup Malware IP: " 854 DVLOG(2) << "Lookup Malware IP: "
831 << " ip:" << ip_address 855 << " ip:" << ip_address
832 << " mask:" << base::HexEncode(mask.data(), mask.size()) 856 << " mask:" << base::HexEncode(mask.data(), mask.size())
833 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) 857 << " subnet:" << base::HexEncode(subnet.data(), subnet.size())
834 << " hash:" << base::HexEncode(hash.data(), hash.size()); 858 << " hash:" << base::HexEncode(hash.data(), hash.size());
835 if (it->second.count(hash) > 0) { 859 if (it->second.count(hash) > 0) {
836 return true; 860 return true;
837 } 861 }
838 } 862 }
839 return false; 863 return false;
840 } 864 }
841 865
842 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( 866 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString(
843 const std::string& str) { 867 const std::string& str) {
868 // This method is theoretically thread-safe but document that it is currently
869 // only expected to be called on the IO thread.
870 DCHECK_CURRENTLY_ON(BrowserThread::IO);
871
844 std::vector<SBFullHash> hashes; 872 std::vector<SBFullHash> hashes;
845 hashes.push_back(SBFullHashForString(str)); 873 hashes.push_back(SBFullHashForString(str));
846 return ContainsWhitelistedHashes(download_whitelist_, hashes); 874 return ContainsWhitelistedHashes(download_whitelist_, hashes);
847 } 875 }
848 876
849 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes( 877 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes(
850 const SBWhitelist& whitelist, 878 const SBWhitelist& whitelist,
851 const std::vector<SBFullHash>& hashes) { 879 const std::vector<SBFullHash>& hashes) {
880 // This method is theoretically thread-safe but document that it is currently
881 // only expected to be called on the IO thread.
882 DCHECK_CURRENTLY_ON(BrowserThread::IO);
883
852 base::AutoLock l(lookup_lock_); 884 base::AutoLock l(lookup_lock_);
853 if (whitelist.second) 885 if (whitelist.second)
854 return true; 886 return true;
855 for (std::vector<SBFullHash>::const_iterator it = hashes.begin(); 887 for (std::vector<SBFullHash>::const_iterator it = hashes.begin();
856 it != hashes.end(); ++it) { 888 it != hashes.end(); ++it) {
857 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), 889 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(),
858 *it, SBFullHashLess)) { 890 *it, SBFullHashLess)) {
859 return true; 891 return true;
860 } 892 }
861 } 893 }
862 return false; 894 return false;
863 } 895 }
864 896
865 // Helper to insert add-chunk entries. 897 // Helper to insert add-chunk entries.
866 void SafeBrowsingDatabaseNew::InsertAddChunk( 898 void SafeBrowsingDatabaseNew::InsertAddChunk(
867 SafeBrowsingStore* store, 899 SafeBrowsingStore* store,
868 const safe_browsing_util::ListType list_id, 900 const safe_browsing_util::ListType list_id,
869 const SBChunkData& chunk_data) { 901 const SBChunkData& chunk_data) {
870 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 902 DCHECK(thread_checker_.CalledOnValidThread());
871 DCHECK(store); 903 DCHECK(store);
872 904
873 // The server can give us a chunk that we already have because 905 // The server can give us a chunk that we already have because
874 // it's part of a range. Don't add it again. 906 // it's part of a range. Don't add it again.
875 const int chunk_id = chunk_data.ChunkNumber(); 907 const int chunk_id = chunk_data.ChunkNumber();
876 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); 908 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id);
877 if (store->CheckAddChunk(encoded_chunk_id)) 909 if (store->CheckAddChunk(encoded_chunk_id))
878 return; 910 return;
879 911
880 store->SetAddChunk(encoded_chunk_id); 912 store->SetAddChunk(encoded_chunk_id);
(...skipping 10 matching lines...) Expand all
891 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i)); 923 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i));
892 } 924 }
893 } 925 }
894 } 926 }
895 927
896 // Helper to insert sub-chunk entries. 928 // Helper to insert sub-chunk entries.
897 void SafeBrowsingDatabaseNew::InsertSubChunk( 929 void SafeBrowsingDatabaseNew::InsertSubChunk(
898 SafeBrowsingStore* store, 930 SafeBrowsingStore* store,
899 const safe_browsing_util::ListType list_id, 931 const safe_browsing_util::ListType list_id,
900 const SBChunkData& chunk_data) { 932 const SBChunkData& chunk_data) {
901 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 933 DCHECK(thread_checker_.CalledOnValidThread());
902 DCHECK(store); 934 DCHECK(store);
903 935
904 // The server can give us a chunk that we already have because 936 // The server can give us a chunk that we already have because
905 // it's part of a range. Don't add it again. 937 // it's part of a range. Don't add it again.
906 const int chunk_id = chunk_data.ChunkNumber(); 938 const int chunk_id = chunk_data.ChunkNumber();
907 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); 939 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id);
908 if (store->CheckSubChunk(encoded_chunk_id)) 940 if (store->CheckSubChunk(encoded_chunk_id))
909 return; 941 return;
910 942
911 store->SetSubChunk(encoded_chunk_id); 943 store->SetSubChunk(encoded_chunk_id);
(...skipping 14 matching lines...) Expand all
926 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id); 958 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id);
927 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id, 959 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id,
928 chunk_data.FullHashAt(i)); 960 chunk_data.FullHashAt(i));
929 } 961 }
930 } 962 }
931 } 963 }
932 964
933 void SafeBrowsingDatabaseNew::InsertChunks( 965 void SafeBrowsingDatabaseNew::InsertChunks(
934 const std::string& list_name, 966 const std::string& list_name,
935 const std::vector<SBChunkData*>& chunks) { 967 const std::vector<SBChunkData*>& chunks) {
936 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 968 DCHECK(thread_checker_.CalledOnValidThread());
937 969
938 if (corruption_detected_ || chunks.empty()) 970 if (corruption_detected_ || chunks.empty())
939 return; 971 return;
940 972
941 const base::TimeTicks before = base::TimeTicks::Now(); 973 const base::TimeTicks before = base::TimeTicks::Now();
942 974
943 // TODO(shess): The caller should just pass list_id. 975 // TODO(shess): The caller should just pass list_id.
944 const safe_browsing_util::ListType list_id = 976 const safe_browsing_util::ListType list_id =
945 safe_browsing_util::GetListId(list_name); 977 safe_browsing_util::GetListId(list_name);
946 978
(...skipping 14 matching lines...) Expand all
961 NOTREACHED(); 993 NOTREACHED();
962 } 994 }
963 } 995 }
964 store->FinishChunk(); 996 store->FinishChunk();
965 997
966 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before); 998 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before);
967 } 999 }
968 1000
969 void SafeBrowsingDatabaseNew::DeleteChunks( 1001 void SafeBrowsingDatabaseNew::DeleteChunks(
970 const std::vector<SBChunkDelete>& chunk_deletes) { 1002 const std::vector<SBChunkDelete>& chunk_deletes) {
971 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1003 DCHECK(thread_checker_.CalledOnValidThread());
972 1004
973 if (corruption_detected_ || chunk_deletes.empty()) 1005 if (corruption_detected_ || chunk_deletes.empty())
974 return; 1006 return;
975 1007
976 const std::string& list_name = chunk_deletes.front().list_name; 1008 const std::string& list_name = chunk_deletes.front().list_name;
977 const safe_browsing_util::ListType list_id = 1009 const safe_browsing_util::ListType list_id =
978 safe_browsing_util::GetListId(list_name); 1010 safe_browsing_util::GetListId(list_name);
979 1011
980 SafeBrowsingStore* store = GetStore(list_id); 1012 SafeBrowsingStore* store = GetStore(list_id);
981 if (!store) return; 1013 if (!store) return;
(...skipping 10 matching lines...) Expand all
992 else 1024 else
993 store->DeleteAddChunk(encoded_chunk_id); 1025 store->DeleteAddChunk(encoded_chunk_id);
994 } 1026 }
995 } 1027 }
996 } 1028 }
997 1029
998 void SafeBrowsingDatabaseNew::CacheHashResults( 1030 void SafeBrowsingDatabaseNew::CacheHashResults(
999 const std::vector<SBPrefix>& prefixes, 1031 const std::vector<SBPrefix>& prefixes,
1000 const std::vector<SBFullHashResult>& full_hits, 1032 const std::vector<SBFullHashResult>& full_hits,
1001 const base::TimeDelta& cache_lifetime) { 1033 const base::TimeDelta& cache_lifetime) {
1034 // This method is theoretically thread-safe but document that it is currently
1035 // only expected to be called on the IO thread.
1036 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1037
1002 const base::Time expire_after = base::Time::Now() + cache_lifetime; 1038 const base::Time expire_after = base::Time::Now() + cache_lifetime;
1003 1039
1004 // This is called on the I/O thread, lock against updates.
1005 base::AutoLock locked(lookup_lock_); 1040 base::AutoLock locked(lookup_lock_);
1006 1041
1007 // Create or reset all cached results for these prefixes. 1042 // Create or reset all cached results for these prefixes.
1008 for (size_t i = 0; i < prefixes.size(); ++i) { 1043 for (size_t i = 0; i < prefixes.size(); ++i) {
1009 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after); 1044 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after);
1010 } 1045 }
1011 1046
1012 // Insert any fullhash hits. Note that there may be one, multiple, or no 1047 // Insert any fullhash hits. Note that there may be one, multiple, or no
1013 // fullhashes for any given entry in |prefixes|. 1048 // fullhashes for any given entry in |prefixes|.
1014 for (size_t i = 0; i < full_hits.size(); ++i) { 1049 for (size_t i = 0; i < full_hits.size(); ++i) {
1015 const SBPrefix prefix = full_hits[i].hash.prefix; 1050 const SBPrefix prefix = full_hits[i].hash.prefix;
1016 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]); 1051 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]);
1017 } 1052 }
1018 } 1053 }
1019 1054
1020 bool SafeBrowsingDatabaseNew::UpdateStarted( 1055 bool SafeBrowsingDatabaseNew::UpdateStarted(
1021 std::vector<SBListChunkRanges>* lists) { 1056 std::vector<SBListChunkRanges>* lists) {
1022 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1057 DCHECK(thread_checker_.CalledOnValidThread());
1023 DCHECK(lists); 1058 DCHECK(lists);
1024 1059
1025 // If |BeginUpdate()| fails, reset the database. 1060 // If |BeginUpdate()| fails, reset the database.
1026 if (!browse_store_->BeginUpdate()) { 1061 if (!browse_store_->BeginUpdate()) {
1027 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); 1062 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN);
1028 HandleCorruptDatabase(); 1063 HandleCorruptDatabase();
1029 return false; 1064 return false;
1030 } 1065 }
1031 1066
1032 if (download_store_.get() && !download_store_->BeginUpdate()) { 1067 if (download_store_.get() && !download_store_->BeginUpdate()) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 UpdateChunkRangesForList(unwanted_software_store_.get(), 1146 UpdateChunkRangesForList(unwanted_software_store_.get(),
1112 safe_browsing_util::kUnwantedUrlList, 1147 safe_browsing_util::kUnwantedUrlList,
1113 lists); 1148 lists);
1114 1149
1115 corruption_detected_ = false; 1150 corruption_detected_ = false;
1116 change_detected_ = false; 1151 change_detected_ = false;
1117 return true; 1152 return true;
1118 } 1153 }
1119 1154
1120 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { 1155 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) {
1121 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1156 DCHECK(thread_checker_.CalledOnValidThread());
1122 1157
1123 // The update may have failed due to corrupt storage (for instance, 1158 // The update may have failed due to corrupt storage (for instance,
1124 // an excessive number of invalid add_chunks and sub_chunks). 1159 // an excessive number of invalid add_chunks and sub_chunks).
1125 // Double-check that the databases are valid. 1160 // Double-check that the databases are valid.
1126 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk 1161 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk
1127 // sections would allow throwing a corruption error in 1162 // sections would allow throwing a corruption error in
1128 // UpdateStarted(). 1163 // UpdateStarted().
1129 if (!update_succeeded) { 1164 if (!update_succeeded) {
1130 if (!browse_store_->CheckValidity()) 1165 if (!browse_store_->CheckValidity())
1131 DLOG(ERROR) << "Safe-browsing browse database corrupt."; 1166 DLOG(ERROR) << "Safe-browsing browse database corrupt.";
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, 1276 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH,
1242 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE, 1277 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE,
1243 true); 1278 true);
1244 } 1279 }
1245 } 1280 }
1246 1281
1247 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( 1282 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1248 const base::FilePath& store_filename, 1283 const base::FilePath& store_filename,
1249 SafeBrowsingStore* store, 1284 SafeBrowsingStore* store,
1250 SBWhitelist* whitelist) { 1285 SBWhitelist* whitelist) {
1286 DCHECK(thread_checker_.CalledOnValidThread());
1287
1251 if (!store) 1288 if (!store)
1252 return; 1289 return;
1253 1290
1254 // Note: |builder| will not be empty. The current data store implementation 1291 // Note: |builder| will not be empty. The current data store implementation
1255 // stores all full-length hashes as both full and prefix hashes. 1292 // stores all full-length hashes as both full and prefix hashes.
1256 safe_browsing::PrefixSetBuilder builder; 1293 safe_browsing::PrefixSetBuilder builder;
1257 std::vector<SBAddFullHash> full_hashes; 1294 std::vector<SBAddFullHash> full_hashes;
1258 if (!store->FinishUpdate(&builder, &full_hashes)) { 1295 if (!store->FinishUpdate(&builder, &full_hashes)) {
1259 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); 1296 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1260 WhitelistEverything(whitelist); 1297 WhitelistEverything(whitelist);
1261 return; 1298 return;
1262 } 1299 }
1263 1300
1264 #if defined(OS_MACOSX) 1301 #if defined(OS_MACOSX)
1265 base::mac::SetFileBackupExclusion(store_filename); 1302 base::mac::SetFileBackupExclusion(store_filename);
1266 #endif 1303 #endif
1267 1304
1268 LoadWhitelist(full_hashes, whitelist); 1305 LoadWhitelist(full_hashes, whitelist);
1269 } 1306 }
1270 1307
1271 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( 1308 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore(
1272 const base::FilePath& store_filename, 1309 const base::FilePath& store_filename,
1273 SafeBrowsingStore* store, 1310 SafeBrowsingStore* store,
1274 FailureType failure_type) { 1311 FailureType failure_type) {
1312 DCHECK(thread_checker_.CalledOnValidThread());
1313
1275 // These results are not used after this call. Simply ignore the 1314 // These results are not used after this call. Simply ignore the
1276 // returned value after FinishUpdate(...). 1315 // returned value after FinishUpdate(...).
1277 safe_browsing::PrefixSetBuilder builder; 1316 safe_browsing::PrefixSetBuilder builder;
1278 std::vector<SBAddFullHash> add_full_hashes_result; 1317 std::vector<SBAddFullHash> add_full_hashes_result;
1279 1318
1280 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) 1319 if (!store->FinishUpdate(&builder, &add_full_hashes_result))
1281 RecordFailure(failure_type); 1320 RecordFailure(failure_type);
1282 1321
1283 #if defined(OS_MACOSX) 1322 #if defined(OS_MACOSX)
1284 base::mac::SetFileBackupExclusion(store_filename); 1323 base::mac::SetFileBackupExclusion(store_filename);
1285 #endif 1324 #endif
1286 1325
1287 return GetFileSizeOrZero(store_filename); 1326 return GetFileSizeOrZero(store_filename);
1288 } 1327 }
1289 1328
1290 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( 1329 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore(
1291 const base::FilePath& db_filename, 1330 const base::FilePath& db_filename,
1292 SafeBrowsingStore* url_store, 1331 SafeBrowsingStore* url_store,
1293 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 1332 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set,
1294 FailureType finish_failure_type, 1333 FailureType finish_failure_type,
1295 FailureType write_failure_type, 1334 FailureType write_failure_type,
1296 bool store_full_hashes_in_prefix_set) { 1335 bool store_full_hashes_in_prefix_set) {
1336 DCHECK(thread_checker_.CalledOnValidThread());
1297 DCHECK(url_store); 1337 DCHECK(url_store);
1298 DCHECK(prefix_set); 1338 DCHECK(prefix_set);
1299 1339
1300 // Measure the amount of IO during the filter build. 1340 // Measure the amount of IO during the filter build.
1301 base::IoCounters io_before, io_after; 1341 base::IoCounters io_before, io_after;
1302 base::ProcessHandle handle = base::GetCurrentProcessHandle(); 1342 base::ProcessHandle handle = base::GetCurrentProcessHandle();
1303 scoped_ptr<base::ProcessMetrics> metric( 1343 scoped_ptr<base::ProcessMetrics> metric(
1304 #if !defined(OS_MACOSX) 1344 #if !defined(OS_MACOSX)
1305 base::ProcessMetrics::CreateProcessMetrics(handle) 1345 base::ProcessMetrics::CreateProcessMetrics(handle)
1306 #else 1346 #else
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 const int64 file_size = GetFileSizeOrZero(db_filename); 1409 const int64 file_size = GetFileSizeOrZero(db_filename);
1370 UMA_HISTOGRAM_COUNTS("SB2.DatabaseKilobytes", 1410 UMA_HISTOGRAM_COUNTS("SB2.DatabaseKilobytes",
1371 static_cast<int>(file_size / 1024)); 1411 static_cast<int>(file_size / 1024));
1372 1412
1373 #if defined(OS_MACOSX) 1413 #if defined(OS_MACOSX)
1374 base::mac::SetFileBackupExclusion(db_filename); 1414 base::mac::SetFileBackupExclusion(db_filename);
1375 #endif 1415 #endif
1376 } 1416 }
1377 1417
1378 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { 1418 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() {
1419 DCHECK(thread_checker_.CalledOnValidThread());
1420
1379 // Note: prefixes will not be empty. The current data store implementation 1421 // Note: prefixes will not be empty. The current data store implementation
1380 // stores all full-length hashes as both full and prefix hashes. 1422 // stores all full-length hashes as both full and prefix hashes.
1381 safe_browsing::PrefixSetBuilder builder; 1423 safe_browsing::PrefixSetBuilder builder;
1382 std::vector<SBAddFullHash> full_hashes; 1424 std::vector<SBAddFullHash> full_hashes;
1383 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { 1425 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) {
1384 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); 1426 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH);
1385 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 1427 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
1386 return; 1428 return;
1387 } 1429 }
1388 1430
1389 #if defined(OS_MACOSX) 1431 #if defined(OS_MACOSX)
1390 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_)); 1432 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_));
1391 #endif 1433 #endif
1392 1434
1393 LoadIpBlacklist(full_hashes); 1435 LoadIpBlacklist(full_hashes);
1394 } 1436 }
1395 1437
1396 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { 1438 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() {
1439 DCHECK(thread_checker_.CalledOnValidThread());
1440
1397 // Reset the database after the current task has unwound (but only 1441 // Reset the database after the current task has unwound (but only
1398 // reset once within the scope of a given task). 1442 // reset once within the scope of a given task).
1399 if (!reset_factory_.HasWeakPtrs()) { 1443 if (!reset_factory_.HasWeakPtrs()) {
1400 RecordFailure(FAILURE_DATABASE_CORRUPT); 1444 RecordFailure(FAILURE_DATABASE_CORRUPT);
1401 base::MessageLoop::current()->PostTask(FROM_HERE, 1445 base::MessageLoop::current()->PostTask(FROM_HERE,
1402 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, 1446 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase,
1403 reset_factory_.GetWeakPtr())); 1447 reset_factory_.GetWeakPtr()));
1404 } 1448 }
1405 } 1449 }
1406 1450
1407 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { 1451 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() {
1452 DCHECK(thread_checker_.CalledOnValidThread());
1453
1408 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); 1454 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER);
1409 corruption_detected_ = true; // Stop updating the database. 1455 corruption_detected_ = true; // Stop updating the database.
1410 ResetDatabase(); 1456 ResetDatabase();
1411 1457
1412 // NOTE(shess): ResetDatabase() should remove the corruption, so this should 1458 // NOTE(shess): ResetDatabase() should remove the corruption, so this should
1413 // only happen once. If you are here because you are hitting this after a 1459 // only happen once. If you are here because you are hitting this after a
1414 // restart, then I would be very interested in working with you to figure out 1460 // restart, then I would be very interested in working with you to figure out
1415 // what is happening, since it may affect real users. 1461 // what is happening, since it may affect real users.
1416 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; 1462 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset";
1417 } 1463 }
1418 1464
1419 // TODO(shess): I'm not clear why this code doesn't have any 1465 // TODO(shess): I'm not clear why this code doesn't have any
1420 // real error-handling. 1466 // real error-handling.
1421 void SafeBrowsingDatabaseNew::LoadPrefixSet( 1467 void SafeBrowsingDatabaseNew::LoadPrefixSet(
1422 const base::FilePath& db_filename, 1468 const base::FilePath& db_filename,
1423 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 1469 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set,
1424 FailureType read_failure_type) { 1470 FailureType read_failure_type) {
1471 DCHECK(thread_checker_.CalledOnValidThread());
1472
1425 if (!prefix_set) 1473 if (!prefix_set)
1426 return; 1474 return;
1427 1475
1428 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
1429 DCHECK(!filename_base_.empty()); 1476 DCHECK(!filename_base_.empty());
1430 1477
1431 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); 1478 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1432 1479
1433 // Only use the prefix set if database is present and non-empty. 1480 // Only use the prefix set if database is present and non-empty.
1434 if (!GetFileSizeOrZero(db_filename)) 1481 if (!GetFileSizeOrZero(db_filename))
1435 return; 1482 return;
1436 1483
1437 // Cleanup any stale bloom filter (no longer used). 1484 // Cleanup any stale bloom filter (no longer used).
1438 // TODO(shess): Track existence to drive removal of this code? 1485 // TODO(shess): Track existence to drive removal of this code?
1439 const base::FilePath bloom_filter_filename = 1486 const base::FilePath bloom_filter_filename =
1440 BloomFilterForFilename(db_filename); 1487 BloomFilterForFilename(db_filename);
1441 base::DeleteFile(bloom_filter_filename, false); 1488 base::DeleteFile(bloom_filter_filename, false);
1442 1489
1443 const base::TimeTicks before = base::TimeTicks::Now(); 1490 const base::TimeTicks before = base::TimeTicks::Now();
1444 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename); 1491 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename);
1445 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); 1492 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before);
1446 1493
1447 if (!prefix_set->get()) 1494 if (!prefix_set->get())
1448 RecordFailure(read_failure_type); 1495 RecordFailure(read_failure_type);
1449 } 1496 }
1450 1497
1451 bool SafeBrowsingDatabaseNew::Delete() { 1498 bool SafeBrowsingDatabaseNew::Delete() {
1452 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1499 DCHECK(thread_checker_.CalledOnValidThread());
1453 DCHECK(!filename_base_.empty()); 1500 DCHECK(!filename_base_.empty());
1454 1501
1455 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the 1502 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the
1456 // store before calling DeleteStore(). DeleteStore() deletes transient files 1503 // store before calling DeleteStore(). DeleteStore() deletes transient files
1457 // in addition to the main file. Probably all of these should be converted to 1504 // in addition to the main file. Probably all of these should be converted to
1458 // a helper which calls Delete() if the store exists, else DeleteStore() on 1505 // a helper which calls Delete() if the store exists, else DeleteStore() on
1459 // the generated filename. 1506 // the generated filename.
1460 1507
1461 // TODO(shess): Determine if the histograms are useful in any way. I cannot 1508 // TODO(shess): Determine if the histograms are useful in any way. I cannot
1462 // recall any action taken as a result of their values, in which case it might 1509 // 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
1525 if (!r11) 1572 if (!r11)
1526 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); 1573 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE);
1527 1574
1528 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; 1575 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11;
1529 } 1576 }
1530 1577
1531 void SafeBrowsingDatabaseNew::WritePrefixSet( 1578 void SafeBrowsingDatabaseNew::WritePrefixSet(
1532 const base::FilePath& db_filename, 1579 const base::FilePath& db_filename,
1533 const safe_browsing::PrefixSet* prefix_set, 1580 const safe_browsing::PrefixSet* prefix_set,
1534 FailureType write_failure_type) { 1581 FailureType write_failure_type) {
1535 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1582 DCHECK(thread_checker_.CalledOnValidThread());
1536 1583
1537 if (!prefix_set) 1584 if (!prefix_set)
1538 return; 1585 return;
1539 1586
1540 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); 1587 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1541 1588
1542 const base::TimeTicks before = base::TimeTicks::Now(); 1589 const base::TimeTicks before = base::TimeTicks::Now();
1543 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); 1590 const bool write_ok = prefix_set->WriteFile(prefix_set_filename);
1544 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); 1591 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before);
1545 1592
1546 const int64 file_size = GetFileSizeOrZero(prefix_set_filename); 1593 const int64 file_size = GetFileSizeOrZero(prefix_set_filename);
1547 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes", 1594 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes",
1548 static_cast<int>(file_size / 1024)); 1595 static_cast<int>(file_size / 1024));
1549 1596
1550 if (!write_ok) 1597 if (!write_ok)
1551 RecordFailure(write_failure_type); 1598 RecordFailure(write_failure_type);
1552 1599
1553 #if defined(OS_MACOSX) 1600 #if defined(OS_MACOSX)
1554 base::mac::SetFileBackupExclusion(prefix_set_filename); 1601 base::mac::SetFileBackupExclusion(prefix_set_filename);
1555 #endif 1602 #endif
1556 } 1603 }
1557 1604
1558 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { 1605 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1606 DCHECK(thread_checker_.CalledOnValidThread());
1559 base::AutoLock locked(lookup_lock_); 1607 base::AutoLock locked(lookup_lock_);
1560 whitelist->second = true; 1608 whitelist->second = true;
1561 whitelist->first.clear(); 1609 whitelist->first.clear();
1562 } 1610 }
1563 1611
1564 void SafeBrowsingDatabaseNew::LoadWhitelist( 1612 void SafeBrowsingDatabaseNew::LoadWhitelist(
1565 const std::vector<SBAddFullHash>& full_hashes, 1613 const std::vector<SBAddFullHash>& full_hashes,
1566 SBWhitelist* whitelist) { 1614 SBWhitelist* whitelist) {
1567 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1615 DCHECK(thread_checker_.CalledOnValidThread());
1616
1568 if (full_hashes.size() > kMaxWhitelistSize) { 1617 if (full_hashes.size() > kMaxWhitelistSize) {
1569 WhitelistEverything(whitelist); 1618 WhitelistEverything(whitelist);
1570 return; 1619 return;
1571 } 1620 }
1572 1621
1573 std::vector<SBFullHash> new_whitelist; 1622 std::vector<SBFullHash> new_whitelist;
1574 new_whitelist.reserve(full_hashes.size()); 1623 new_whitelist.reserve(full_hashes.size());
1575 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1624 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1576 it != full_hashes.end(); ++it) { 1625 it != full_hashes.end(); ++it) {
1577 new_whitelist.push_back(it->full_hash); 1626 new_whitelist.push_back(it->full_hash);
1578 } 1627 }
1579 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess); 1628 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess);
1580 1629
1581 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl); 1630 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl);
1582 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), 1631 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1583 kill_switch, SBFullHashLess)) { 1632 kill_switch, SBFullHashLess)) {
1584 // The kill switch is whitelisted hence we whitelist all URLs. 1633 // The kill switch is whitelisted hence we whitelist all URLs.
1585 WhitelistEverything(whitelist); 1634 WhitelistEverything(whitelist);
1586 } else { 1635 } else {
1587 base::AutoLock locked(lookup_lock_); 1636 base::AutoLock locked(lookup_lock_);
1588 whitelist->second = false; 1637 whitelist->second = false;
1589 whitelist->first.swap(new_whitelist); 1638 whitelist->first.swap(new_whitelist);
1590 } 1639 }
1591 } 1640 }
1592 1641
1593 void SafeBrowsingDatabaseNew::LoadIpBlacklist( 1642 void SafeBrowsingDatabaseNew::LoadIpBlacklist(
1594 const std::vector<SBAddFullHash>& full_hashes) { 1643 const std::vector<SBAddFullHash>& full_hashes) {
1595 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1644 DCHECK(thread_checker_.CalledOnValidThread());
1645
1596 IPBlacklist new_blacklist; 1646 IPBlacklist new_blacklist;
1597 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1647 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1598 it != full_hashes.end(); 1648 it != full_hashes.end();
1599 ++it) { 1649 ++it) {
1600 const char* full_hash = it->full_hash.full_hash; 1650 const char* full_hash = it->full_hash.full_hash;
1601 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); 1651 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash));
1602 // The format of the IP blacklist is: 1652 // The format of the IP blacklist is:
1603 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. 1653 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes.
1604 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); 1654 std::string hashed_ip_prefix(full_hash, base::kSHA1Length);
1605 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); 1655 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]);
(...skipping 18 matching lines...) Expand all
1624 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), 1674 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(),
1625 hashed_ip_prefix.size()); 1675 hashed_ip_prefix.size());
1626 new_blacklist[mask].insert(hashed_ip_prefix); 1676 new_blacklist[mask].insert(hashed_ip_prefix);
1627 } 1677 }
1628 1678
1629 base::AutoLock locked(lookup_lock_); 1679 base::AutoLock locked(lookup_lock_);
1630 ip_blacklist_.swap(new_blacklist); 1680 ip_blacklist_.swap(new_blacklist);
1631 } 1681 }
1632 1682
1633 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { 1683 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() {
1684 // This method is theoretically thread-safe but document that it is currently
1685 // only expected to be called on the IO thread.
1686 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1687
1634 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); 1688 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl);
1635 std::vector<SBFullHash> full_hashes; 1689 std::vector<SBFullHash> full_hashes;
1636 full_hashes.push_back(malware_kill_switch); 1690 full_hashes.push_back(malware_kill_switch);
1637 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 1691 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
1638 } 1692 }
1639 1693
1640 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { 1694 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() {
1695 // This method is theoretically thread-safe but document that it is currently
1696 // only expected to be called on the IO thread.
1697 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1698
1699 base::AutoLock locked(lookup_lock_);
1641 return csd_whitelist_.second; 1700 return csd_whitelist_.second;
1642 } 1701 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_database.h ('k') | chrome/browser/safe_browsing/safe_browsing_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698