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

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

Issue 794273002: Introduce SafeBrowsingDatabase::ThreadSafeStateManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a6_dedup_sideeffectfreeWLcode
Patch Set: inline even more transactions Created 5 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 12 matching lines...) Expand all
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "crypto/sha2.h" 24 #include "crypto/sha2.h"
25 #include "net/base/net_util.h" 25 #include "net/base/net_util.h"
26 #include "url/gurl.h" 26 #include "url/gurl.h"
27 27
28 #if defined(OS_MACOSX) 28 #if defined(OS_MACOSX)
29 #include "base/mac/mac_util.h" 29 #include "base/mac/mac_util.h"
30 #endif 30 #endif
31 31
32 using content::BrowserThread; 32 using content::BrowserThread;
33 using safe_browsing::PrefixSet;
34 using safe_browsing::PrefixSetBuilder;
33 35
34 namespace { 36 namespace {
35 37
36 // Filename suffix for the bloom filter. 38 // Filename suffix for the bloom filter.
37 const base::FilePath::CharType kBloomFilterFile[] = 39 const base::FilePath::CharType kBloomFilterFile[] =
38 FILE_PATH_LITERAL(" Filter 2"); 40 FILE_PATH_LITERAL(" Filter 2");
39 // Filename suffix for the prefix set. 41 // Filename suffix for the prefix set.
40 const base::FilePath::CharType kPrefixSetFile[] = 42 const base::FilePath::CharType kPrefixSetFile[] =
41 FILE_PATH_LITERAL(" Prefix Set"); 43 FILE_PATH_LITERAL(" Prefix Set");
42 // Filename suffix for download store. 44 // Filename suffix for download store.
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 457 }
456 return NULL; 458 return NULL;
457 } 459 }
458 460
459 // static 461 // static
460 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) { 462 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) {
461 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type, 463 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type,
462 FAILURE_DATABASE_MAX); 464 FAILURE_DATABASE_MAX);
463 } 465 }
464 466
467 class SafeBrowsingDatabaseNew::ThreadSafeStateManager::ReadTransaction {
468 public:
469 const SBWhitelist* GetSBWhitelist(SBWhitelistId id) {
470 switch (id) {
471 case SBWhitelistId::CSD:
472 return &outer_->csd_whitelist_;
473 case SBWhitelistId::DOWNLOAD:
474 return &outer_->download_whitelist_;
475 }
476 NOTREACHED();
477 return nullptr;
478 }
479
480 const IPBlacklist* ip_blacklist() { return &outer_->ip_blacklist_; }
481
482 const PrefixSet* GetPrefixSet(PrefixSetId id) {
483 switch (id) {
484 case PrefixSetId::BROWSE:
485 return outer_->browse_prefix_set_.get();
486 case PrefixSetId::SIDE_EFFECT_FREE_WHITELIST:
487 return outer_->side_effect_free_whitelist_prefix_set_.get();
488 case PrefixSetId::UNWANTED_SOFTWARE:
489 return outer_->unwanted_software_prefix_set_.get();
490 }
491 NOTREACHED();
492 return nullptr;
493 }
494
495 PrefixGetHashCache* prefix_gethash_cache() {
496 // The cache is special: it is read/write on all threads. Access to it
497 // therefore requires a LOCK'ed transaction (i.e. it can't benefit from
498 // DONT_LOCK_ON_MAIN_THREAD).
499 DCHECK(transaction_lock_);
500 return &outer_->prefix_gethash_cache_;
501 }
502
503 private:
504 // Only ThreadSafeStateManager is allowed to build a ReadTransaction.
505 friend class ThreadSafeStateManager;
506
507 enum class AutoLockRequirement {
508 LOCK,
509 // SBWhitelist's, IPBlacklist's, and PrefixSet's (not caches) are only
510 // ever written to on the main thread (as enforced by
511 // ThreadSafeStateManager) and can therefore be read on the main thread
512 // without first acquiring |lock_|.
513 DONT_LOCK_ON_MAIN_THREAD
514 };
515
516 ReadTransaction(const ThreadSafeStateManager* outer,
517 AutoLockRequirement auto_lock_requirement)
518 : outer_(outer) {
519 DCHECK(outer_);
520 if (auto_lock_requirement == AutoLockRequirement::LOCK)
521 transaction_lock_.reset(new base::AutoLock(outer_->lock_));
522 else
523 DCHECK(outer_->thread_checker_.CalledOnValidThread());
524 }
525
526 const ThreadSafeStateManager* outer_;
527 scoped_ptr<base::AutoLock> transaction_lock_;
528
529 DISALLOW_COPY_AND_ASSIGN(ReadTransaction);
530 };
531
532 class SafeBrowsingDatabaseNew::ThreadSafeStateManager::WriteTransaction {
533 public:
534 // Call this method if an error occured with the given whitelist. This will
535 // result in all lookups to the whitelist to return true.
536 void WhitelistEverything(SBWhitelistId id) {
537 SBWhitelist* whitelist = SBWhitelistForId(id);
538 whitelist->second = true;
539 whitelist->first.clear();
540 }
541
542 void SwapSBWhitelist(SBWhitelistId id,
543 scoped_ptr<std::vector<SBFullHash>> new_whitelist) {
mattm 2014/12/24 00:29:54 why not just pass "std::vector<SBFullHash>* new_wh
gab 2014/12/24 01:28:58 Because I try to always have methods that take own
544 SBWhitelist* whitelist = SBWhitelistForId(id);
545 whitelist->second = false;
546 whitelist->first.swap(*new_whitelist.release());
mattm 2014/12/24 00:29:53 This is a leak isn't it?
gab 2014/12/24 01:28:58 Done.
547 }
548
549 void clear_ip_blacklist() { outer_->ip_blacklist_.clear(); }
550
551 void swap_ip_blacklist(scoped_ptr<IPBlacklist> new_blacklist) {
552 outer_->ip_blacklist_.swap(*new_blacklist.release());
mattm 2014/12/24 00:29:54 same as above
gab 2014/12/24 01:28:58 Done.
553 }
554
555 void SwapPrefixSet(PrefixSetId id,
556 scoped_ptr<const PrefixSet> new_prefix_set) {
557 switch (id) {
558 case PrefixSetId::BROWSE:
559 outer_->browse_prefix_set_.swap(new_prefix_set);
560 break;
561 case PrefixSetId::SIDE_EFFECT_FREE_WHITELIST:
562 outer_->side_effect_free_whitelist_prefix_set_.swap(new_prefix_set);
563 break;
564 case PrefixSetId::UNWANTED_SOFTWARE:
565 outer_->unwanted_software_prefix_set_.swap(new_prefix_set);
566 break;
567 }
568 }
569
570 void clear_prefix_gethash_cache() { outer_->prefix_gethash_cache_.clear(); }
571
572 private:
573 // Only ThreadSafeStateManager is allowed to build a WriteTransaction.
574 friend class ThreadSafeStateManager;
575
576 explicit WriteTransaction(ThreadSafeStateManager* outer)
577 : outer_(outer), transaction_lock_(outer_->lock_) {
578 DCHECK(outer_);
579 DCHECK(outer_->thread_checker_.CalledOnValidThread());
580 }
581
582 SBWhitelist* SBWhitelistForId(SBWhitelistId id) {
583 switch (id) {
584 case SBWhitelistId::CSD:
585 return &outer_->csd_whitelist_;
586 case SBWhitelistId::DOWNLOAD:
587 return &outer_->download_whitelist_;
588 }
589 NOTREACHED();
590 return nullptr;
591 }
592
593 ThreadSafeStateManager* outer_;
594 base::AutoLock transaction_lock_;
595
596 DISALLOW_COPY_AND_ASSIGN(WriteTransaction);
597 };
598
599 SafeBrowsingDatabaseNew::ThreadSafeStateManager::ThreadSafeStateManager(
600 const base::ThreadChecker& thread_checker)
601 : thread_checker_(thread_checker) {
602 }
603
604 SafeBrowsingDatabaseNew::ThreadSafeStateManager::~ThreadSafeStateManager() {
605 }
606
607 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction>
608 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginReadTransaction() {
609 return make_scoped_ptr(
610 new ReadTransaction(this, ReadTransaction::AutoLockRequirement::LOCK));
611 }
612
613 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction> SafeBrowsingDatabaseNew::
614 ThreadSafeStateManager::BeginReadTransactionNoLockOnMainThread() {
615 return make_scoped_ptr(new ReadTransaction(
616 this, ReadTransaction::AutoLockRequirement::DONT_LOCK_ON_MAIN_THREAD));
617 }
618
619 scoped_ptr<SafeBrowsingDatabaseNew::WriteTransaction>
620 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginWriteTransaction() {
621 return make_scoped_ptr(new WriteTransaction(this));
622 }
623
465 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew() 624 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
466 : SafeBrowsingDatabaseNew(new SafeBrowsingStoreFile, 625 : SafeBrowsingDatabaseNew(new SafeBrowsingStoreFile,
467 NULL, 626 NULL,
468 NULL, 627 NULL,
469 NULL, 628 NULL,
470 NULL, 629 NULL,
471 NULL, 630 NULL,
472 NULL, 631 NULL,
473 NULL) { 632 NULL) {
474 DCHECK(browse_store_.get()); 633 DCHECK(browse_store_.get());
475 DCHECK(!download_store_.get()); 634 DCHECK(!download_store_.get());
476 DCHECK(!csd_whitelist_store_.get()); 635 DCHECK(!csd_whitelist_store_.get());
477 DCHECK(!download_whitelist_store_.get()); 636 DCHECK(!download_whitelist_store_.get());
478 DCHECK(!extension_blacklist_store_.get()); 637 DCHECK(!extension_blacklist_store_.get());
479 DCHECK(!side_effect_free_whitelist_store_.get()); 638 DCHECK(!side_effect_free_whitelist_store_.get());
480 DCHECK(!ip_blacklist_store_.get()); 639 DCHECK(!ip_blacklist_store_.get());
481 DCHECK(!unwanted_software_store_.get()); 640 DCHECK(!unwanted_software_store_.get());
482 } 641 }
483 642
484 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( 643 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew(
485 SafeBrowsingStore* browse_store, 644 SafeBrowsingStore* browse_store,
486 SafeBrowsingStore* download_store, 645 SafeBrowsingStore* download_store,
487 SafeBrowsingStore* csd_whitelist_store, 646 SafeBrowsingStore* csd_whitelist_store,
488 SafeBrowsingStore* download_whitelist_store, 647 SafeBrowsingStore* download_whitelist_store,
489 SafeBrowsingStore* extension_blacklist_store, 648 SafeBrowsingStore* extension_blacklist_store,
490 SafeBrowsingStore* side_effect_free_whitelist_store, 649 SafeBrowsingStore* side_effect_free_whitelist_store,
491 SafeBrowsingStore* ip_blacklist_store, 650 SafeBrowsingStore* ip_blacklist_store,
492 SafeBrowsingStore* unwanted_software_store) 651 SafeBrowsingStore* unwanted_software_store)
493 : browse_store_(browse_store), 652 : state_manager_(thread_checker_),
653 browse_store_(browse_store),
494 download_store_(download_store), 654 download_store_(download_store),
495 csd_whitelist_store_(csd_whitelist_store), 655 csd_whitelist_store_(csd_whitelist_store),
496 download_whitelist_store_(download_whitelist_store), 656 download_whitelist_store_(download_whitelist_store),
497 extension_blacklist_store_(extension_blacklist_store), 657 extension_blacklist_store_(extension_blacklist_store),
498 side_effect_free_whitelist_store_(side_effect_free_whitelist_store), 658 side_effect_free_whitelist_store_(side_effect_free_whitelist_store),
499 ip_blacklist_store_(ip_blacklist_store), 659 ip_blacklist_store_(ip_blacklist_store),
500 unwanted_software_store_(unwanted_software_store), 660 unwanted_software_store_(unwanted_software_store),
501 corruption_detected_(false), 661 corruption_detected_(false),
502 change_detected_(false), 662 change_detected_(false),
503 reset_factory_(this) { 663 reset_factory_(this) {
(...skipping 14 matching lines...) Expand all
518 filename_base_ = filename_base; 678 filename_base_ = filename_base;
519 679
520 // TODO(shess): The various stores are really only necessary while doing 680 // TODO(shess): The various stores are really only necessary while doing
521 // updates (see |UpdateFinished()|) or when querying a store directly (see 681 // updates (see |UpdateFinished()|) or when querying a store directly (see
522 // |ContainsDownloadUrl()|). 682 // |ContainsDownloadUrl()|).
523 // The store variables are also tested to see if a list is enabled. Perhaps 683 // The store variables are also tested to see if a list is enabled. Perhaps
524 // the stores could be refactored into an update object so that they are only 684 // the stores could be refactored into an update object so that they are only
525 // live in memory while being actively used. The sense of enabled probably 685 // live in memory while being actively used. The sense of enabled probably
526 // belongs in protocol_manager or database_manager. 686 // belongs in protocol_manager or database_manager.
527 687
528 browse_store_->Init( 688 {
529 BrowseDBFilename(filename_base_), 689 // NOTE: A transaction here is overkill as there are no pointers to this
530 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 690 // class on other threads until this function returns, but it's also
531 base::Unretained(this))); 691 // harmless as that also means there is no possibility of contention on the
692 // lock.
693 scoped_ptr<WriteTransaction> txn = state_manager_.BeginWriteTransaction();
532 694
533 if (unwanted_software_store_.get()) { 695 txn->clear_prefix_gethash_cache();
534 unwanted_software_store_->Init( 696
535 UnwantedSoftwareDBFilename(filename_base_), 697 browse_store_->Init(
698 BrowseDBFilename(filename_base_),
536 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 699 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
537 base::Unretained(this))); 700 base::Unretained(this)));
538 }
539 701
540 {
541 // NOTE: There is no need to grab the lock in this function, since
542 // until it returns, there are no pointers to this class on other
543 // threads. Then again, that means there is no possibility of
544 // contention on the lock...
545 base::AutoLock locked(lookup_lock_);
546 prefix_gethash_cache_.clear();
547 LoadPrefixSet(BrowseDBFilename(filename_base_),
548 &browse_prefix_set_,
549 FAILURE_BROWSE_PREFIX_SET_READ);
550 if (unwanted_software_store_.get()) { 702 if (unwanted_software_store_.get()) {
551 LoadPrefixSet(UnwantedSoftwareDBFilename(filename_base_), 703 unwanted_software_store_->Init(
552 &unwanted_software_prefix_set_, 704 UnwantedSoftwareDBFilename(filename_base_),
705 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
706 base::Unretained(this)));
707 }
708 LoadPrefixSet(BrowseDBFilename(filename_base_), txn.get(),
709 PrefixSetId::BROWSE, FAILURE_BROWSE_PREFIX_SET_READ);
710 if (unwanted_software_store_.get()) {
711 LoadPrefixSet(UnwantedSoftwareDBFilename(filename_base_), txn.get(),
712 PrefixSetId::UNWANTED_SOFTWARE,
553 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_READ); 713 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_READ);
554 } 714 }
715
716 if (side_effect_free_whitelist_store_.get()) {
717 const base::FilePath side_effect_free_whitelist_filename =
718 SideEffectFreeWhitelistDBFilename(filename_base_);
719 side_effect_free_whitelist_store_->Init(
720 side_effect_free_whitelist_filename,
721 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
722 base::Unretained(this)));
723
724 LoadPrefixSet(side_effect_free_whitelist_filename, txn.get(),
725 PrefixSetId::SIDE_EFFECT_FREE_WHITELIST,
726 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ);
727 } else {
728 // Delete any files of the side-effect free sidelist that may be around
729 // from when it was previously enabled.
730 SafeBrowsingStoreFile::DeleteStore(
731 SideEffectFreeWhitelistDBFilename(filename_base_));
732 base::DeleteFile(PrefixSetForFilename(
733 SideEffectFreeWhitelistDBFilename(filename_base_)),
734 false);
735 }
555 } 736 }
737 // Note: End the transaction early because LoadWhiteList() and
738 // WhitelistEverything() manage their own transactions.
556 739
557 if (download_store_.get()) { 740 if (download_store_.get()) {
558 download_store_->Init( 741 download_store_->Init(
559 DownloadDBFilename(filename_base_), 742 DownloadDBFilename(filename_base_),
560 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 743 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
561 base::Unretained(this))); 744 base::Unretained(this)));
562 } 745 }
563 746
564 if (csd_whitelist_store_.get()) { 747 if (csd_whitelist_store_.get()) {
565 csd_whitelist_store_->Init( 748 csd_whitelist_store_->Init(
566 CsdWhitelistDBFilename(filename_base_), 749 CsdWhitelistDBFilename(filename_base_),
567 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 750 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
568 base::Unretained(this))); 751 base::Unretained(this)));
569 752
570 std::vector<SBAddFullHash> full_hashes; 753 std::vector<SBAddFullHash> full_hashes;
571 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { 754 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) {
572 LoadWhitelist(full_hashes, &csd_whitelist_); 755 LoadWhitelist(full_hashes, SBWhitelistId::CSD);
573 } else { 756 } else {
574 WhitelistEverything(&csd_whitelist_); 757 state_manager_.BeginWriteTransaction()->WhitelistEverything(
758 SBWhitelistId::CSD);
575 } 759 }
576 } else { 760 } else {
577 WhitelistEverything(&csd_whitelist_); // Just to be safe. 761 state_manager_.BeginWriteTransaction()->WhitelistEverything(
762 SBWhitelistId::CSD); // Just to be safe.
578 } 763 }
579 764
580 if (download_whitelist_store_.get()) { 765 if (download_whitelist_store_.get()) {
581 download_whitelist_store_->Init( 766 download_whitelist_store_->Init(
582 DownloadWhitelistDBFilename(filename_base_), 767 DownloadWhitelistDBFilename(filename_base_),
583 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 768 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
584 base::Unretained(this))); 769 base::Unretained(this)));
585 770
586 std::vector<SBAddFullHash> full_hashes; 771 std::vector<SBAddFullHash> full_hashes;
587 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) { 772 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) {
588 LoadWhitelist(full_hashes, &download_whitelist_); 773 LoadWhitelist(full_hashes, SBWhitelistId::DOWNLOAD);
589 } else { 774 } else {
590 WhitelistEverything(&download_whitelist_); 775 state_manager_.BeginWriteTransaction()->WhitelistEverything(
776 SBWhitelistId::DOWNLOAD);
591 } 777 }
592 } else { 778 } else {
593 WhitelistEverything(&download_whitelist_); // Just to be safe. 779 state_manager_.BeginWriteTransaction()->WhitelistEverything(
780 SBWhitelistId::DOWNLOAD); // Just to be safe.
594 } 781 }
595 782
596 if (extension_blacklist_store_.get()) { 783 if (extension_blacklist_store_.get()) {
597 extension_blacklist_store_->Init( 784 extension_blacklist_store_->Init(
598 ExtensionBlacklistDBFilename(filename_base_), 785 ExtensionBlacklistDBFilename(filename_base_),
599 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 786 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
600 base::Unretained(this))); 787 base::Unretained(this)));
601 } 788 }
602 789
603 if (side_effect_free_whitelist_store_.get()) {
604 const base::FilePath side_effect_free_whitelist_filename =
605 SideEffectFreeWhitelistDBFilename(filename_base_);
606 side_effect_free_whitelist_store_->Init(
607 side_effect_free_whitelist_filename,
608 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
609 base::Unretained(this)));
610
611 LoadPrefixSet(side_effect_free_whitelist_filename,
612 &side_effect_free_whitelist_prefix_set_,
613 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ);
614 } else {
615 // Delete any files of the side-effect free sidelist that may be around
616 // from when it was previously enabled.
617 SafeBrowsingStoreFile::DeleteStore(
618 SideEffectFreeWhitelistDBFilename(filename_base_));
619 base::DeleteFile(
620 PrefixSetForFilename(SideEffectFreeWhitelistDBFilename(filename_base_)),
621 false);
622 }
623
624 if (ip_blacklist_store_.get()) { 790 if (ip_blacklist_store_.get()) {
625 ip_blacklist_store_->Init( 791 ip_blacklist_store_->Init(
626 IpBlacklistDBFilename(filename_base_), 792 IpBlacklistDBFilename(filename_base_),
627 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 793 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
628 base::Unretained(this))); 794 base::Unretained(this)));
629 795
630 std::vector<SBAddFullHash> full_hashes; 796 std::vector<SBAddFullHash> full_hashes;
631 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { 797 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) {
632 LoadIpBlacklist(full_hashes); 798 LoadIpBlacklist(full_hashes);
633 } else { 799 } else {
634 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 800 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
635 } 801 }
636 } 802 }
637 } 803 }
638 804
639 bool SafeBrowsingDatabaseNew::ResetDatabase() { 805 bool SafeBrowsingDatabaseNew::ResetDatabase() {
640 DCHECK(thread_checker_.CalledOnValidThread()); 806 DCHECK(thread_checker_.CalledOnValidThread());
641 807
642 // Delete files on disk. 808 // Delete files on disk.
643 // TODO(shess): Hard to see where one might want to delete without a 809 // TODO(shess): Hard to see where one might want to delete without a
644 // reset. Perhaps inline |Delete()|? 810 // reset. Perhaps inline |Delete()|?
645 if (!Delete()) 811 if (!Delete())
646 return false; 812 return false;
647 813
648 // Reset objects in memory. 814 // Reset objects in memory.
649 { 815 scoped_ptr<WriteTransaction> txn = state_manager_.BeginWriteTransaction();
650 base::AutoLock locked(lookup_lock_); 816 txn->clear_prefix_gethash_cache();
651 prefix_gethash_cache_.clear(); 817 txn->SwapPrefixSet(PrefixSetId::BROWSE, nullptr);
652 browse_prefix_set_.reset(); 818 txn->SwapPrefixSet(PrefixSetId::SIDE_EFFECT_FREE_WHITELIST, nullptr);
653 side_effect_free_whitelist_prefix_set_.reset(); 819 txn->SwapPrefixSet(PrefixSetId::UNWANTED_SOFTWARE, nullptr);
654 ip_blacklist_.clear(); 820 txn->clear_ip_blacklist();
655 unwanted_software_prefix_set_.reset(); 821 txn->WhitelistEverything(SBWhitelistId::CSD);
656 } 822 txn->WhitelistEverything(SBWhitelistId::DOWNLOAD);
657 // Wants to acquire the lock itself.
658 WhitelistEverything(&csd_whitelist_);
659 WhitelistEverything(&download_whitelist_);
660 return true; 823 return true;
661 } 824 }
662 825
663 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( 826 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl(
664 const GURL& url, 827 const GURL& url,
665 std::vector<SBPrefix>* prefix_hits, 828 std::vector<SBPrefix>* prefix_hits,
666 std::vector<SBFullHashResult>* cache_hits) { 829 std::vector<SBFullHashResult>* cache_hits) {
667 return PrefixSetContainsUrl( 830 return PrefixSetContainsUrl(url, PrefixSetId::BROWSE, prefix_hits,
668 url, &browse_prefix_set_, prefix_hits, cache_hits); 831 cache_hits);
669 } 832 }
670 833
671 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( 834 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl(
672 const GURL& url, 835 const GURL& url,
673 std::vector<SBPrefix>* prefix_hits, 836 std::vector<SBPrefix>* prefix_hits,
674 std::vector<SBFullHashResult>* cache_hits) { 837 std::vector<SBFullHashResult>* cache_hits) {
675 return PrefixSetContainsUrl( 838 return PrefixSetContainsUrl(url, PrefixSetId::UNWANTED_SOFTWARE, prefix_hits,
676 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); 839 cache_hits);
677 } 840 }
678 841
679 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( 842 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl(
680 const GURL& url, 843 const GURL& url,
681 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 844 PrefixSetId prefix_set_id,
682 std::vector<SBPrefix>* prefix_hits, 845 std::vector<SBPrefix>* prefix_hits,
683 std::vector<SBFullHashResult>* cache_hits) { 846 std::vector<SBFullHashResult>* cache_hits) {
684 // Clear the results first. 847 // Clear the results first.
685 prefix_hits->clear(); 848 prefix_hits->clear();
686 cache_hits->clear(); 849 cache_hits->clear();
687 850
688 std::vector<SBFullHash> full_hashes; 851 std::vector<SBFullHash> full_hashes;
689 UrlToFullHashes(url, false, &full_hashes); 852 UrlToFullHashes(url, false, &full_hashes);
690 if (full_hashes.empty()) 853 if (full_hashes.empty())
691 return false; 854 return false;
692 855
693 return PrefixSetContainsUrlHashes( 856 return PrefixSetContainsUrlHashes(full_hashes, prefix_set_id, prefix_hits,
694 full_hashes, prefix_set_getter, prefix_hits, cache_hits); 857 cache_hits);
695 } 858 }
696 859
697 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( 860 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting(
698 const std::vector<SBFullHash>& full_hashes, 861 const std::vector<SBFullHash>& full_hashes,
699 std::vector<SBPrefix>* prefix_hits, 862 std::vector<SBPrefix>* prefix_hits,
700 std::vector<SBFullHashResult>* cache_hits) { 863 std::vector<SBFullHashResult>* cache_hits) {
701 return PrefixSetContainsUrlHashes( 864 return PrefixSetContainsUrlHashes(full_hashes, PrefixSetId::BROWSE,
702 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); 865 prefix_hits, cache_hits);
703 } 866 }
704 867
705 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( 868 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes(
706 const std::vector<SBFullHash>& full_hashes, 869 const std::vector<SBFullHash>& full_hashes,
707 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 870 PrefixSetId prefix_set_id,
708 std::vector<SBPrefix>* prefix_hits, 871 std::vector<SBPrefix>* prefix_hits,
709 std::vector<SBFullHashResult>* cache_hits) { 872 std::vector<SBFullHashResult>* cache_hits) {
710 // Used to determine cache expiration. 873 // Used to determine cache expiration.
711 const base::Time now = base::Time::Now(); 874 const base::Time now = base::Time::Now();
712 875
713 // This function can be called on any thread, so lock against any changes 876 {
714 base::AutoLock locked(lookup_lock_); 877 scoped_ptr<ReadTransaction> txn = state_manager_.BeginReadTransaction();
715 878
716 // |prefix_set| is empty until it is either read from disk, or the first 879 // |prefix_set| is empty until it is either read from disk, or the first
717 // update populates it. Bail out without a hit if not yet available. 880 // update populates it. Bail out without a hit if not yet available.
718 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence 881 const PrefixSet* prefix_set = txn->GetPrefixSet(prefix_set_id);
719 // why it is passed as a parameter rather than passing the |prefix_set| 882 if (!prefix_set)
720 // directly. 883 return false;
721 const safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get();
722 if (!prefix_set)
723 return false;
724 884
725 for (size_t i = 0; i < full_hashes.size(); ++i) { 885 for (size_t i = 0; i < full_hashes.size(); ++i) {
726 if (!GetCachedFullHash( 886 if (!GetCachedFullHash(txn->prefix_gethash_cache(), full_hashes[i], now,
727 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) { 887 cache_hits)) {
728 // No valid cached result, check the database. 888 // No valid cached result, check the database.
729 if (prefix_set->Exists(full_hashes[i])) 889 if (prefix_set->Exists(full_hashes[i]))
730 prefix_hits->push_back(full_hashes[i].prefix); 890 prefix_hits->push_back(full_hashes[i].prefix);
891 }
731 } 892 }
732 } 893 }
733 894
734 // Multiple full hashes could share prefix, remove duplicates. 895 // Multiple full hashes could share prefix, remove duplicates.
735 std::sort(prefix_hits->begin(), prefix_hits->end()); 896 std::sort(prefix_hits->begin(), prefix_hits->end());
736 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), 897 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()),
737 prefix_hits->end()); 898 prefix_hits->end());
738 899
739 return !prefix_hits->empty() || !cache_hits->empty(); 900 return !prefix_hits->empty() || !cache_hits->empty();
740 } 901 }
(...skipping 11 matching lines...) Expand all
752 GetDownloadUrlPrefixes(urls, &prefixes); 913 GetDownloadUrlPrefixes(urls, &prefixes);
753 return MatchAddPrefixes(download_store_.get(), 914 return MatchAddPrefixes(download_store_.get(),
754 safe_browsing_util::BINURL % 2, 915 safe_browsing_util::BINURL % 2,
755 prefixes, 916 prefixes,
756 prefix_hits); 917 prefix_hits);
757 } 918 }
758 919
759 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { 920 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) {
760 std::vector<SBFullHash> full_hashes; 921 std::vector<SBFullHash> full_hashes;
761 UrlToFullHashes(url, true, &full_hashes); 922 UrlToFullHashes(url, true, &full_hashes);
762 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 923 return ContainsWhitelistedHashes(SBWhitelistId::CSD, full_hashes);
763 } 924 }
764 925
765 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { 926 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) {
766 std::vector<SBFullHash> full_hashes; 927 std::vector<SBFullHash> full_hashes;
767 UrlToFullHashes(url, true, &full_hashes); 928 UrlToFullHashes(url, true, &full_hashes);
768 return ContainsWhitelistedHashes(download_whitelist_, full_hashes); 929 return ContainsWhitelistedHashes(SBWhitelistId::DOWNLOAD, full_hashes);
769 } 930 }
770 931
771 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( 932 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes(
772 const std::vector<SBPrefix>& prefixes, 933 const std::vector<SBPrefix>& prefixes,
773 std::vector<SBPrefix>* prefix_hits) { 934 std::vector<SBPrefix>* prefix_hits) {
774 DCHECK(thread_checker_.CalledOnValidThread()); 935 DCHECK(thread_checker_.CalledOnValidThread());
775 936
776 if (!extension_blacklist_store_) 937 if (!extension_blacklist_store_)
777 return false; 938 return false;
778 939
779 return MatchAddPrefixes(extension_blacklist_store_.get(), 940 return MatchAddPrefixes(extension_blacklist_store_.get(),
780 safe_browsing_util::EXTENSIONBLACKLIST % 2, 941 safe_browsing_util::EXTENSIONBLACKLIST % 2,
781 prefixes, 942 prefixes,
782 prefix_hits); 943 prefix_hits);
783 } 944 }
784 945
785 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( 946 bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl(
786 const GURL& url) { 947 const GURL& url) {
787 std::string host; 948 std::string host;
788 std::string path; 949 std::string path;
789 std::string query; 950 std::string query;
790 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query); 951 safe_browsing_util::CanonicalizeUrl(url, &host, &path, &query);
791 std::string url_to_check = host + path; 952 std::string url_to_check = host + path;
792 if (!query.empty()) 953 if (!query.empty())
793 url_to_check += "?" + query; 954 url_to_check += "?" + query;
794 SBFullHash full_hash = SBFullHashForString(url_to_check); 955 SBFullHash full_hash = SBFullHashForString(url_to_check);
795 956
796 // This function can be called on any thread, so lock against any changes 957 scoped_ptr<ReadTransaction> txn = state_manager_.BeginReadTransaction();
797 base::AutoLock locked(lookup_lock_); 958
959 const PrefixSet* side_effect_free_whitelist_prefix_set =
960 txn->GetPrefixSet(PrefixSetId::SIDE_EFFECT_FREE_WHITELIST);
798 961
799 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read 962 // |side_effect_free_whitelist_prefix_set_| is empty until it is either read
800 // from disk, or the first update populates it. Bail out without a hit if 963 // from disk, or the first update populates it. Bail out without a hit if
801 // not yet available. 964 // not yet available.
802 if (!side_effect_free_whitelist_prefix_set_.get()) 965 if (!side_effect_free_whitelist_prefix_set)
803 return false; 966 return false;
804 967
805 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); 968 return side_effect_free_whitelist_prefix_set->Exists(full_hash);
806 } 969 }
807 970
808 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { 971 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) {
809 net::IPAddressNumber ip_number; 972 net::IPAddressNumber ip_number;
810 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) 973 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number))
811 return false; 974 return false;
812 if (ip_number.size() == net::kIPv4AddressSize) 975 if (ip_number.size() == net::kIPv4AddressSize)
813 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); 976 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number);
814 if (ip_number.size() != net::kIPv6AddressSize) 977 if (ip_number.size() != net::kIPv6AddressSize)
815 return false; // better safe than sorry. 978 return false; // better safe than sorry.
816 979
817 // This function can be called on any thread, so lock against any changes 980 scoped_ptr<ReadTransaction> txn = state_manager_.BeginReadTransaction();
818 base::AutoLock locked(lookup_lock_); 981 const IPBlacklist* ip_blacklist = txn->ip_blacklist();
819 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); 982 for (IPBlacklist::const_iterator it = ip_blacklist->begin();
820 it != ip_blacklist_.end(); 983 it != ip_blacklist->end(); ++it) {
821 ++it) {
822 const std::string& mask = it->first; 984 const std::string& mask = it->first;
823 DCHECK_EQ(mask.size(), ip_number.size()); 985 DCHECK_EQ(mask.size(), ip_number.size());
824 std::string subnet(net::kIPv6AddressSize, '\0'); 986 std::string subnet(net::kIPv6AddressSize, '\0');
825 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { 987 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) {
826 subnet[i] = ip_number[i] & mask[i]; 988 subnet[i] = ip_number[i] & mask[i];
827 } 989 }
828 const std::string hash = base::SHA1HashString(subnet); 990 const std::string hash = base::SHA1HashString(subnet);
829 DVLOG(2) << "Lookup Malware IP: " 991 DVLOG(2) << "Lookup Malware IP: "
830 << " ip:" << ip_address 992 << " ip:" << ip_address
831 << " mask:" << base::HexEncode(mask.data(), mask.size()) 993 << " mask:" << base::HexEncode(mask.data(), mask.size())
832 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) 994 << " subnet:" << base::HexEncode(subnet.data(), subnet.size())
833 << " hash:" << base::HexEncode(hash.data(), hash.size()); 995 << " hash:" << base::HexEncode(hash.data(), hash.size());
834 if (it->second.count(hash) > 0) { 996 if (it->second.count(hash) > 0) {
835 return true; 997 return true;
836 } 998 }
837 } 999 }
838 return false; 1000 return false;
839 } 1001 }
840 1002
841 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( 1003 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString(
842 const std::string& str) { 1004 const std::string& str) {
843 std::vector<SBFullHash> hashes; 1005 std::vector<SBFullHash> hashes;
844 hashes.push_back(SBFullHashForString(str)); 1006 hashes.push_back(SBFullHashForString(str));
845 return ContainsWhitelistedHashes(download_whitelist_, hashes); 1007 return ContainsWhitelistedHashes(SBWhitelistId::DOWNLOAD, hashes);
846 } 1008 }
847 1009
848 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes( 1010 bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes(
849 const SBWhitelist& whitelist, 1011 SBWhitelistId whitelist_id,
850 const std::vector<SBFullHash>& hashes) { 1012 const std::vector<SBFullHash>& hashes) {
851 base::AutoLock l(lookup_lock_); 1013 scoped_ptr<ReadTransaction> txn = state_manager_.BeginReadTransaction();
852 if (whitelist.second) 1014 const SBWhitelist* whitelist = txn->GetSBWhitelist(whitelist_id);
1015 if (whitelist->second)
853 return true; 1016 return true;
854 for (std::vector<SBFullHash>::const_iterator it = hashes.begin(); 1017 for (std::vector<SBFullHash>::const_iterator it = hashes.begin();
855 it != hashes.end(); ++it) { 1018 it != hashes.end(); ++it) {
856 if (std::binary_search(whitelist.first.begin(), whitelist.first.end(), 1019 if (std::binary_search(whitelist->first.begin(), whitelist->first.end(),
857 *it, SBFullHashLess)) { 1020 *it, SBFullHashLess)) {
858 return true; 1021 return true;
859 } 1022 }
860 } 1023 }
861 return false; 1024 return false;
862 } 1025 }
863 1026
864 // Helper to insert add-chunk entries. 1027 // Helper to insert add-chunk entries.
865 void SafeBrowsingDatabaseNew::InsertAddChunk( 1028 void SafeBrowsingDatabaseNew::InsertAddChunk(
866 SafeBrowsingStore* store, 1029 SafeBrowsingStore* store,
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 } 1156 }
994 } 1157 }
995 } 1158 }
996 1159
997 void SafeBrowsingDatabaseNew::CacheHashResults( 1160 void SafeBrowsingDatabaseNew::CacheHashResults(
998 const std::vector<SBPrefix>& prefixes, 1161 const std::vector<SBPrefix>& prefixes,
999 const std::vector<SBFullHashResult>& full_hits, 1162 const std::vector<SBFullHashResult>& full_hits,
1000 const base::TimeDelta& cache_lifetime) { 1163 const base::TimeDelta& cache_lifetime) {
1001 const base::Time expire_after = base::Time::Now() + cache_lifetime; 1164 const base::Time expire_after = base::Time::Now() + cache_lifetime;
1002 1165
1003 // This function can be called on any thread, so lock against any changes 1166 scoped_ptr<ReadTransaction> txn = state_manager_.BeginReadTransaction();
1004 base::AutoLock locked(lookup_lock_); 1167 PrefixGetHashCache* prefix_gethash_cache = txn->prefix_gethash_cache();
1005 1168
1006 // Create or reset all cached results for these prefixes. 1169 // Create or reset all cached results for these prefixes.
1007 for (size_t i = 0; i < prefixes.size(); ++i) { 1170 for (size_t i = 0; i < prefixes.size(); ++i) {
1008 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after); 1171 (*prefix_gethash_cache)[prefixes[i]] = SBCachedFullHashResult(expire_after);
1009 } 1172 }
1010 1173
1011 // Insert any fullhash hits. Note that there may be one, multiple, or no 1174 // Insert any fullhash hits. Note that there may be one, multiple, or no
1012 // fullhashes for any given entry in |prefixes|. 1175 // fullhashes for any given entry in |prefixes|.
1013 for (size_t i = 0; i < full_hits.size(); ++i) { 1176 for (size_t i = 0; i < full_hits.size(); ++i) {
1014 const SBPrefix prefix = full_hits[i].hash.prefix; 1177 const SBPrefix prefix = full_hits[i].hash.prefix;
1015 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]); 1178 (*prefix_gethash_cache)[prefix].full_hashes.push_back(full_hits[i]);
1016 } 1179 }
1017 } 1180 }
1018 1181
1019 bool SafeBrowsingDatabaseNew::UpdateStarted( 1182 bool SafeBrowsingDatabaseNew::UpdateStarted(
1020 std::vector<SBListChunkRanges>* lists) { 1183 std::vector<SBListChunkRanges>* lists) {
1021 DCHECK(thread_checker_.CalledOnValidThread()); 1184 DCHECK(thread_checker_.CalledOnValidThread());
1022 DCHECK(lists); 1185 DCHECK(lists);
1023 1186
1024 // If |BeginUpdate()| fails, reset the database. 1187 // If |BeginUpdate()| fails, reset the database.
1025 if (!browse_store_->BeginUpdate()) { 1188 if (!browse_store_->BeginUpdate()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 HandleCorruptDatabase(); 1229 HandleCorruptDatabase();
1067 return false; 1230 return false;
1068 } 1231 }
1069 1232
1070 if (unwanted_software_store_ && !unwanted_software_store_->BeginUpdate()) { 1233 if (unwanted_software_store_ && !unwanted_software_store_->BeginUpdate()) {
1071 RecordFailure(FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_BEGIN); 1234 RecordFailure(FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_BEGIN);
1072 HandleCorruptDatabase(); 1235 HandleCorruptDatabase();
1073 return false; 1236 return false;
1074 } 1237 }
1075 1238
1076 { 1239 // Cached fullhash results must be cleared on every database update (whether
1077 base::AutoLock locked(lookup_lock_); 1240 // successful or not).
1078 // Cached fullhash results must be cleared on every database update (whether 1241 state_manager_.BeginWriteTransaction()->clear_prefix_gethash_cache();
1079 // successful or not.)
1080 prefix_gethash_cache_.clear();
1081 }
1082 1242
1083 UpdateChunkRangesForLists(browse_store_.get(), 1243 UpdateChunkRangesForLists(browse_store_.get(),
1084 safe_browsing_util::kMalwareList, 1244 safe_browsing_util::kMalwareList,
1085 safe_browsing_util::kPhishingList, 1245 safe_browsing_util::kPhishingList,
1086 lists); 1246 lists);
1087 1247
1088 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been 1248 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been
1089 // deprecated. Code to delete the list from the store shows ~15k hits/day as 1249 // deprecated. Code to delete the list from the store shows ~15k hits/day as
1090 // of Feb 2014, so it has been removed. Everything _should_ be resilient to 1250 // of Feb 2014, so it has been removed. Everything _should_ be resilient to
1091 // extra data of that sort. 1251 // extra data of that sort.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 int64 size_bytes = UpdateHashPrefixStore( 1353 int64 size_bytes = UpdateHashPrefixStore(
1194 DownloadDBFilename(filename_base_), 1354 DownloadDBFilename(filename_base_),
1195 download_store_.get(), 1355 download_store_.get(),
1196 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); 1356 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH);
1197 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes", 1357 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes",
1198 static_cast<int>(size_bytes / 1024)); 1358 static_cast<int>(size_bytes / 1024));
1199 } 1359 }
1200 1360
1201 UpdatePrefixSetUrlStore(BrowseDBFilename(filename_base_), 1361 UpdatePrefixSetUrlStore(BrowseDBFilename(filename_base_),
1202 browse_store_.get(), 1362 browse_store_.get(),
1203 &browse_prefix_set_, 1363 PrefixSetId::BROWSE,
1204 FAILURE_BROWSE_DATABASE_UPDATE_FINISH, 1364 FAILURE_BROWSE_DATABASE_UPDATE_FINISH,
1205 FAILURE_BROWSE_PREFIX_SET_WRITE, 1365 FAILURE_BROWSE_PREFIX_SET_WRITE,
1206 true); 1366 true);
1207 1367
1208 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_), 1368 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_),
1209 csd_whitelist_store_.get(), 1369 csd_whitelist_store_.get(),
1210 &csd_whitelist_); 1370 SBWhitelistId::CSD);
1211 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_), 1371 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_),
1212 download_whitelist_store_.get(), 1372 download_whitelist_store_.get(),
1213 &download_whitelist_); 1373 SBWhitelistId::DOWNLOAD);
1214 1374
1215 if (extension_blacklist_store_) { 1375 if (extension_blacklist_store_) {
1216 int64 size_bytes = UpdateHashPrefixStore( 1376 int64 size_bytes = UpdateHashPrefixStore(
1217 ExtensionBlacklistDBFilename(filename_base_), 1377 ExtensionBlacklistDBFilename(filename_base_),
1218 extension_blacklist_store_.get(), 1378 extension_blacklist_store_.get(),
1219 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH); 1379 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH);
1220 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes", 1380 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes",
1221 static_cast<int>(size_bytes / 1024)); 1381 static_cast<int>(size_bytes / 1024));
1222 } 1382 }
1223 1383
1224 if (side_effect_free_whitelist_store_) { 1384 if (side_effect_free_whitelist_store_) {
1225 UpdatePrefixSetUrlStore(SideEffectFreeWhitelistDBFilename(filename_base_), 1385 UpdatePrefixSetUrlStore(SideEffectFreeWhitelistDBFilename(filename_base_),
1226 side_effect_free_whitelist_store_.get(), 1386 side_effect_free_whitelist_store_.get(),
1227 &side_effect_free_whitelist_prefix_set_, 1387 PrefixSetId::SIDE_EFFECT_FREE_WHITELIST,
1228 FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH, 1388 FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH,
1229 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE, 1389 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE,
1230 false); 1390 false);
1231 } 1391 }
1232 1392
1233 if (ip_blacklist_store_) 1393 if (ip_blacklist_store_)
1234 UpdateIpBlacklistStore(); 1394 UpdateIpBlacklistStore();
1235 1395
1236 if (unwanted_software_store_) { 1396 if (unwanted_software_store_) {
1237 UpdatePrefixSetUrlStore(UnwantedSoftwareDBFilename(filename_base_), 1397 UpdatePrefixSetUrlStore(UnwantedSoftwareDBFilename(filename_base_),
1238 unwanted_software_store_.get(), 1398 unwanted_software_store_.get(),
1239 &unwanted_software_prefix_set_, 1399 PrefixSetId::UNWANTED_SOFTWARE,
1240 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, 1400 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH,
1241 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE, 1401 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE,
1242 true); 1402 true);
1243 } 1403 }
1244 } 1404 }
1245 1405
1246 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( 1406 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1247 const base::FilePath& store_filename, 1407 const base::FilePath& store_filename,
1248 SafeBrowsingStore* store, 1408 SafeBrowsingStore* store,
1249 SBWhitelist* whitelist) { 1409 SBWhitelistId whitelist_id) {
1250 DCHECK(thread_checker_.CalledOnValidThread()); 1410 DCHECK(thread_checker_.CalledOnValidThread());
1251 1411
1252 if (!store) 1412 if (!store)
1253 return; 1413 return;
1254 1414
1255 // Note: |builder| will not be empty. The current data store implementation 1415 // Note: |builder| will not be empty. The current data store implementation
1256 // stores all full-length hashes as both full and prefix hashes. 1416 // stores all full-length hashes as both full and prefix hashes.
1257 safe_browsing::PrefixSetBuilder builder; 1417 PrefixSetBuilder builder;
1258 std::vector<SBAddFullHash> full_hashes; 1418 std::vector<SBAddFullHash> full_hashes;
1259 if (!store->FinishUpdate(&builder, &full_hashes)) { 1419 if (!store->FinishUpdate(&builder, &full_hashes)) {
1260 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); 1420 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1261 WhitelistEverything(whitelist); 1421 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1262 return; 1422 return;
1263 } 1423 }
1264 1424
1265 #if defined(OS_MACOSX) 1425 #if defined(OS_MACOSX)
1266 base::mac::SetFileBackupExclusion(store_filename); 1426 base::mac::SetFileBackupExclusion(store_filename);
1267 #endif 1427 #endif
1268 1428
1269 LoadWhitelist(full_hashes, whitelist); 1429 LoadWhitelist(full_hashes, whitelist_id);
1270 } 1430 }
1271 1431
1272 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( 1432 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore(
1273 const base::FilePath& store_filename, 1433 const base::FilePath& store_filename,
1274 SafeBrowsingStore* store, 1434 SafeBrowsingStore* store,
1275 FailureType failure_type) { 1435 FailureType failure_type) {
1276 DCHECK(thread_checker_.CalledOnValidThread()); 1436 DCHECK(thread_checker_.CalledOnValidThread());
1277 1437
1278 // These results are not used after this call. Simply ignore the 1438 // These results are not used after this call. Simply ignore the
1279 // returned value after FinishUpdate(...). 1439 // returned value after FinishUpdate(...).
1280 safe_browsing::PrefixSetBuilder builder; 1440 PrefixSetBuilder builder;
1281 std::vector<SBAddFullHash> add_full_hashes_result; 1441 std::vector<SBAddFullHash> add_full_hashes_result;
1282 1442
1283 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) 1443 if (!store->FinishUpdate(&builder, &add_full_hashes_result))
1284 RecordFailure(failure_type); 1444 RecordFailure(failure_type);
1285 1445
1286 #if defined(OS_MACOSX) 1446 #if defined(OS_MACOSX)
1287 base::mac::SetFileBackupExclusion(store_filename); 1447 base::mac::SetFileBackupExclusion(store_filename);
1288 #endif 1448 #endif
1289 1449
1290 return GetFileSizeOrZero(store_filename); 1450 return GetFileSizeOrZero(store_filename);
1291 } 1451 }
1292 1452
1293 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( 1453 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore(
1294 const base::FilePath& db_filename, 1454 const base::FilePath& db_filename,
1295 SafeBrowsingStore* url_store, 1455 SafeBrowsingStore* url_store,
1296 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 1456 PrefixSetId prefix_set_id,
1297 FailureType finish_failure_type, 1457 FailureType finish_failure_type,
1298 FailureType write_failure_type, 1458 FailureType write_failure_type,
1299 bool store_full_hashes_in_prefix_set) { 1459 bool store_full_hashes_in_prefix_set) {
1300 DCHECK(thread_checker_.CalledOnValidThread()); 1460 DCHECK(thread_checker_.CalledOnValidThread());
1301 DCHECK(url_store); 1461 DCHECK(url_store);
1302 DCHECK(prefix_set);
1303 1462
1304 // Measure the amount of IO during the filter build. 1463 // Measure the amount of IO during the filter build.
1305 base::IoCounters io_before, io_after; 1464 base::IoCounters io_before, io_after;
1306 base::ProcessHandle handle = base::GetCurrentProcessHandle(); 1465 base::ProcessHandle handle = base::GetCurrentProcessHandle();
1307 scoped_ptr<base::ProcessMetrics> metric( 1466 scoped_ptr<base::ProcessMetrics> metric(
1308 #if !defined(OS_MACOSX) 1467 #if !defined(OS_MACOSX)
1309 base::ProcessMetrics::CreateProcessMetrics(handle) 1468 base::ProcessMetrics::CreateProcessMetrics(handle)
1310 #else 1469 #else
1311 // Getting stats only for the current process is enough, so NULL is fine. 1470 // Getting stats only for the current process is enough, so NULL is fine.
1312 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) 1471 base::ProcessMetrics::CreateProcessMetrics(handle, NULL)
1313 #endif 1472 #endif
1314 ); 1473 );
1315 1474
1316 // IoCounters are currently not supported on Mac, and may not be 1475 // IoCounters are currently not supported on Mac, and may not be
1317 // available for Linux, so we check the result and only show IO 1476 // available for Linux, so we check the result and only show IO
1318 // stats if they are available. 1477 // stats if they are available.
1319 const bool got_counters = metric->GetIOCounters(&io_before); 1478 const bool got_counters = metric->GetIOCounters(&io_before);
1320 1479
1321 const base::TimeTicks before = base::TimeTicks::Now(); 1480 const base::TimeTicks before = base::TimeTicks::Now();
1322 1481
1323 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the 1482 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the
1324 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use 1483 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use
1325 // the SBFullHash portion. It would need an accessor on PrefixSet. 1484 // the SBFullHash portion. It would need an accessor on PrefixSet.
1326 safe_browsing::PrefixSetBuilder builder; 1485 PrefixSetBuilder builder;
1327 std::vector<SBAddFullHash> add_full_hashes; 1486 std::vector<SBAddFullHash> add_full_hashes;
1328 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { 1487 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) {
1329 RecordFailure(finish_failure_type); 1488 RecordFailure(finish_failure_type);
1330 return; 1489 return;
1331 } 1490 }
1332 1491
1333 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set; 1492 scoped_ptr<const PrefixSet> new_prefix_set;
1334 if (store_full_hashes_in_prefix_set) { 1493 if (store_full_hashes_in_prefix_set) {
1335 std::vector<SBFullHash> full_hash_results; 1494 std::vector<SBFullHash> full_hash_results;
1336 for (size_t i = 0; i < add_full_hashes.size(); ++i) { 1495 for (size_t i = 0; i < add_full_hashes.size(); ++i) {
1337 full_hash_results.push_back(add_full_hashes[i].full_hash); 1496 full_hash_results.push_back(add_full_hashes[i].full_hash);
1338 } 1497 }
1339 1498
1340 new_prefix_set = builder.GetPrefixSet(full_hash_results); 1499 new_prefix_set = builder.GetPrefixSet(full_hash_results);
1341 } else { 1500 } else {
1342 // TODO(gab): Ensure that stores which do not want full hashes just don't 1501 // TODO(gab): Ensure that stores which do not want full hashes just don't
1343 // have full hashes in the first place and remove 1502 // have full hashes in the first place and remove
1344 // |store_full_hashes_in_prefix_set| and the code specialization incurred 1503 // |store_full_hashes_in_prefix_set| and the code specialization incurred
1345 // here. 1504 // here.
1346 new_prefix_set = builder.GetPrefixSetNoHashes(); 1505 new_prefix_set = builder.GetPrefixSetNoHashes();
1347 } 1506 }
1348 1507
1349 // Swap in the newly built filter. 1508 // Swap in the newly built filter.
1350 { 1509 state_manager_.BeginWriteTransaction()->SwapPrefixSet(prefix_set_id,
1351 base::AutoLock locked(lookup_lock_); 1510 new_prefix_set.Pass());
1352 prefix_set->swap(new_prefix_set);
1353 }
1354 1511
1355 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); 1512 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before);
1356 1513
1357 // Persist the prefix set to disk. Note: there is no need to lock since the 1514 {
1358 // only write to |*prefix_set| is on this thread (in the swap() above). 1515 // Persist the prefix set to disk. Do not grab the lock to avoid contention
1359 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); 1516 // while writing to disk. This is safe as only this thread can ever modify
1517 // |state_manager_|'s prefix sets anyways.
1518 scoped_ptr<ReadTransaction> txn =
1519 state_manager_.BeginReadTransactionNoLockOnMainThread();
1520 WritePrefixSet(db_filename, txn->GetPrefixSet(prefix_set_id),
1521 write_failure_type);
1522 }
1360 1523
1361 // Gather statistics. 1524 // Gather statistics.
1362 if (got_counters && metric->GetIOCounters(&io_after)) { 1525 if (got_counters && metric->GetIOCounters(&io_after)) {
1363 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", 1526 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes",
1364 static_cast<int>(io_after.ReadTransferCount - 1527 static_cast<int>(io_after.ReadTransferCount -
1365 io_before.ReadTransferCount) / 1024); 1528 io_before.ReadTransferCount) / 1024);
1366 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", 1529 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes",
1367 static_cast<int>(io_after.WriteTransferCount - 1530 static_cast<int>(io_after.WriteTransferCount -
1368 io_before.WriteTransferCount) / 1024); 1531 io_before.WriteTransferCount) / 1024);
1369 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations", 1532 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations",
(...skipping 11 matching lines...) Expand all
1381 #if defined(OS_MACOSX) 1544 #if defined(OS_MACOSX)
1382 base::mac::SetFileBackupExclusion(db_filename); 1545 base::mac::SetFileBackupExclusion(db_filename);
1383 #endif 1546 #endif
1384 } 1547 }
1385 1548
1386 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { 1549 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() {
1387 DCHECK(thread_checker_.CalledOnValidThread()); 1550 DCHECK(thread_checker_.CalledOnValidThread());
1388 1551
1389 // Note: prefixes will not be empty. The current data store implementation 1552 // Note: prefixes will not be empty. The current data store implementation
1390 // stores all full-length hashes as both full and prefix hashes. 1553 // stores all full-length hashes as both full and prefix hashes.
1391 safe_browsing::PrefixSetBuilder builder; 1554 PrefixSetBuilder builder;
1392 std::vector<SBAddFullHash> full_hashes; 1555 std::vector<SBAddFullHash> full_hashes;
1393 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { 1556 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) {
1394 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); 1557 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH);
1395 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 1558 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
1396 return; 1559 return;
1397 } 1560 }
1398 1561
1399 #if defined(OS_MACOSX) 1562 #if defined(OS_MACOSX)
1400 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_)); 1563 base::mac::SetFileBackupExclusion(IpBlacklistDBFilename(filename_base_));
1401 #endif 1564 #endif
(...skipping 23 matching lines...) Expand all
1425 1588
1426 // NOTE(shess): ResetDatabase() should remove the corruption, so this should 1589 // NOTE(shess): ResetDatabase() should remove the corruption, so this should
1427 // only happen once. If you are here because you are hitting this after a 1590 // only happen once. If you are here because you are hitting this after a
1428 // restart, then I would be very interested in working with you to figure out 1591 // restart, then I would be very interested in working with you to figure out
1429 // what is happening, since it may affect real users. 1592 // what is happening, since it may affect real users.
1430 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; 1593 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset";
1431 } 1594 }
1432 1595
1433 // TODO(shess): I'm not clear why this code doesn't have any 1596 // TODO(shess): I'm not clear why this code doesn't have any
1434 // real error-handling. 1597 // real error-handling.
1435 void SafeBrowsingDatabaseNew::LoadPrefixSet( 1598 void SafeBrowsingDatabaseNew::LoadPrefixSet(const base::FilePath& db_filename,
1436 const base::FilePath& db_filename, 1599 WriteTransaction* txn,
1437 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 1600 PrefixSetId prefix_set_id,
1438 FailureType read_failure_type) { 1601 FailureType read_failure_type) {
1439 DCHECK(thread_checker_.CalledOnValidThread()); 1602 DCHECK(thread_checker_.CalledOnValidThread());
1440 1603 DCHECK(txn);
1441 if (!prefix_set)
1442 return;
1443
1444 DCHECK(!filename_base_.empty()); 1604 DCHECK(!filename_base_.empty());
1445 1605
1446 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1447
1448 // Only use the prefix set if database is present and non-empty. 1606 // Only use the prefix set if database is present and non-empty.
1449 if (!GetFileSizeOrZero(db_filename)) 1607 if (!GetFileSizeOrZero(db_filename))
1450 return; 1608 return;
1451 1609
1452 // Cleanup any stale bloom filter (no longer used). 1610 // Cleanup any stale bloom filter (no longer used).
1453 // TODO(shess): Track existence to drive removal of this code? 1611 // TODO(shess): Track existence to drive removal of this code?
1454 const base::FilePath bloom_filter_filename = 1612 const base::FilePath bloom_filter_filename =
1455 BloomFilterForFilename(db_filename); 1613 BloomFilterForFilename(db_filename);
1456 base::DeleteFile(bloom_filter_filename, false); 1614 base::DeleteFile(bloom_filter_filename, false);
1457 1615
1458 const base::TimeTicks before = base::TimeTicks::Now(); 1616 const base::TimeTicks before = base::TimeTicks::Now();
1459 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename); 1617 scoped_ptr<const PrefixSet> new_prefix_set =
1618 PrefixSet::LoadFile(PrefixSetForFilename(db_filename));
1619 if (!new_prefix_set.get())
1620 RecordFailure(read_failure_type);
1621 txn->SwapPrefixSet(prefix_set_id, new_prefix_set.Pass());
1460 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); 1622 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before);
1461
1462 if (!prefix_set->get())
1463 RecordFailure(read_failure_type);
1464 } 1623 }
1465 1624
1466 bool SafeBrowsingDatabaseNew::Delete() { 1625 bool SafeBrowsingDatabaseNew::Delete() {
1467 DCHECK(thread_checker_.CalledOnValidThread()); 1626 DCHECK(thread_checker_.CalledOnValidThread());
1468 DCHECK(!filename_base_.empty()); 1627 DCHECK(!filename_base_.empty());
1469 1628
1470 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the 1629 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the
1471 // store before calling DeleteStore(). DeleteStore() deletes transient files 1630 // store before calling DeleteStore(). DeleteStore() deletes transient files
1472 // in addition to the main file. Probably all of these should be converted to 1631 // in addition to the main file. Probably all of these should be converted to
1473 // a helper which calls Delete() if the store exists, else DeleteStore() on 1632 // a helper which calls Delete() if the store exists, else DeleteStore() on
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 RecordFailure(FAILURE_IP_BLACKLIST_DELETE); 1695 RecordFailure(FAILURE_IP_BLACKLIST_DELETE);
1537 1696
1538 const bool r11 = 1697 const bool r11 =
1539 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false); 1698 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false);
1540 if (!r11) 1699 if (!r11)
1541 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); 1700 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE);
1542 1701
1543 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; 1702 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11;
1544 } 1703 }
1545 1704
1546 void SafeBrowsingDatabaseNew::WritePrefixSet( 1705 void SafeBrowsingDatabaseNew::WritePrefixSet(const base::FilePath& db_filename,
1547 const base::FilePath& db_filename, 1706 const PrefixSet* prefix_set,
1548 const safe_browsing::PrefixSet* prefix_set, 1707 FailureType write_failure_type) {
1549 FailureType write_failure_type) {
1550 DCHECK(thread_checker_.CalledOnValidThread()); 1708 DCHECK(thread_checker_.CalledOnValidThread());
1551 1709
1552 if (!prefix_set) 1710 if (!prefix_set)
1553 return; 1711 return;
1554 1712
1555 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); 1713 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1556 1714
1557 const base::TimeTicks before = base::TimeTicks::Now(); 1715 const base::TimeTicks before = base::TimeTicks::Now();
1558 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); 1716 const bool write_ok = prefix_set->WriteFile(prefix_set_filename);
1559 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); 1717 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before);
1560 1718
1561 const int64 file_size = GetFileSizeOrZero(prefix_set_filename); 1719 const int64 file_size = GetFileSizeOrZero(prefix_set_filename);
1562 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes", 1720 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes",
1563 static_cast<int>(file_size / 1024)); 1721 static_cast<int>(file_size / 1024));
1564 1722
1565 if (!write_ok) 1723 if (!write_ok)
1566 RecordFailure(write_failure_type); 1724 RecordFailure(write_failure_type);
1567 1725
1568 #if defined(OS_MACOSX) 1726 #if defined(OS_MACOSX)
1569 base::mac::SetFileBackupExclusion(prefix_set_filename); 1727 base::mac::SetFileBackupExclusion(prefix_set_filename);
1570 #endif 1728 #endif
1571 } 1729 }
1572 1730
1573 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1574 DCHECK(thread_checker_.CalledOnValidThread());
1575 base::AutoLock locked(lookup_lock_);
1576 whitelist->second = true;
1577 whitelist->first.clear();
1578 }
1579
1580 void SafeBrowsingDatabaseNew::LoadWhitelist( 1731 void SafeBrowsingDatabaseNew::LoadWhitelist(
1581 const std::vector<SBAddFullHash>& full_hashes, 1732 const std::vector<SBAddFullHash>& full_hashes,
1582 SBWhitelist* whitelist) { 1733 SBWhitelistId whitelist_id) {
1583 DCHECK(thread_checker_.CalledOnValidThread()); 1734 DCHECK(thread_checker_.CalledOnValidThread());
1584 1735
1585 if (full_hashes.size() > kMaxWhitelistSize) { 1736 if (full_hashes.size() > kMaxWhitelistSize) {
1586 WhitelistEverything(whitelist); 1737 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1587 return; 1738 return;
1588 } 1739 }
1589 1740
1590 std::vector<SBFullHash> new_whitelist; 1741 scoped_ptr<std::vector<SBFullHash>> new_whitelist(
1591 new_whitelist.reserve(full_hashes.size()); 1742 new std::vector<SBFullHash>);
1743 new_whitelist->reserve(full_hashes.size());
1592 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1744 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1593 it != full_hashes.end(); ++it) { 1745 it != full_hashes.end(); ++it) {
1594 new_whitelist.push_back(it->full_hash); 1746 new_whitelist->push_back(it->full_hash);
1595 } 1747 }
1596 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess); 1748 std::sort(new_whitelist->begin(), new_whitelist->end(), SBFullHashLess);
1597 1749
1598 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl); 1750 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl);
1599 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), 1751 if (std::binary_search(new_whitelist->begin(), new_whitelist->end(),
1600 kill_switch, SBFullHashLess)) { 1752 kill_switch, SBFullHashLess)) {
1601 // The kill switch is whitelisted hence we whitelist all URLs. 1753 // The kill switch is whitelisted hence we whitelist all URLs.
1602 WhitelistEverything(whitelist); 1754 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1603 } else { 1755 } else {
1604 base::AutoLock locked(lookup_lock_); 1756 state_manager_.BeginWriteTransaction()->SwapSBWhitelist(
1605 whitelist->second = false; 1757 whitelist_id, new_whitelist.Pass());
1606 whitelist->first.swap(new_whitelist);
1607 } 1758 }
1608 } 1759 }
1609 1760
1610 void SafeBrowsingDatabaseNew::LoadIpBlacklist( 1761 void SafeBrowsingDatabaseNew::LoadIpBlacklist(
1611 const std::vector<SBAddFullHash>& full_hashes) { 1762 const std::vector<SBAddFullHash>& full_hashes) {
1612 DCHECK(thread_checker_.CalledOnValidThread()); 1763 DCHECK(thread_checker_.CalledOnValidThread());
1613 1764
1614 IPBlacklist new_blacklist; 1765 scoped_ptr<IPBlacklist> new_blacklist(new IPBlacklist);
1615 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1766 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1616 it != full_hashes.end(); 1767 it != full_hashes.end();
1617 ++it) { 1768 ++it) {
1618 const char* full_hash = it->full_hash.full_hash; 1769 const char* full_hash = it->full_hash.full_hash;
1619 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); 1770 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash));
1620 // The format of the IP blacklist is: 1771 // The format of the IP blacklist is:
1621 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. 1772 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes.
1622 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); 1773 std::string hashed_ip_prefix(full_hash, base::kSHA1Length);
1623 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); 1774 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]);
1624 if (prefix_size > kMaxIpPrefixSize || prefix_size < kMinIpPrefixSize) { 1775 if (prefix_size > kMaxIpPrefixSize || prefix_size < kMinIpPrefixSize) {
1625 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_INVALID); 1776 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_INVALID);
1626 new_blacklist.clear(); // Load empty blacklist. 1777 new_blacklist->clear(); // Load empty blacklist.
1627 break; 1778 break;
1628 } 1779 }
1629 1780
1630 // We precompute the mask for the given subnet size to speed up lookups. 1781 // We precompute the mask for the given subnet size to speed up lookups.
1631 // Basically we need to create a 16B long string which has the highest 1782 // Basically we need to create a 16B long string which has the highest
1632 // |size| bits sets to one. 1783 // |size| bits sets to one.
1633 std::string mask(net::kIPv6AddressSize, '\0'); 1784 std::string mask(net::kIPv6AddressSize, '\0');
1634 mask.replace(0, prefix_size / 8, prefix_size / 8, '\xFF'); 1785 mask.replace(0, prefix_size / 8, prefix_size / 8, '\xFF');
1635 if ((prefix_size % 8) != 0) { 1786 if ((prefix_size % 8) != 0) {
1636 mask[prefix_size / 8] = 0xFF << (8 - (prefix_size % 8)); 1787 mask[prefix_size / 8] = 0xFF << (8 - (prefix_size % 8));
1637 } 1788 }
1638 DVLOG(2) << "Inserting malicious IP: " 1789 DVLOG(2) << "Inserting malicious IP: "
1639 << " raw:" << base::HexEncode(full_hash, crypto::kSHA256Length) 1790 << " raw:" << base::HexEncode(full_hash, crypto::kSHA256Length)
1640 << " mask:" << base::HexEncode(mask.data(), mask.size()) 1791 << " mask:" << base::HexEncode(mask.data(), mask.size())
1641 << " prefix_size:" << prefix_size 1792 << " prefix_size:" << prefix_size
1642 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), 1793 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(),
1643 hashed_ip_prefix.size()); 1794 hashed_ip_prefix.size());
1644 new_blacklist[mask].insert(hashed_ip_prefix); 1795 (*new_blacklist)[mask].insert(hashed_ip_prefix);
1645 } 1796 }
1646 1797
1647 base::AutoLock locked(lookup_lock_); 1798 state_manager_.BeginWriteTransaction()->swap_ip_blacklist(
1648 ip_blacklist_.swap(new_blacklist); 1799 new_blacklist.Pass());
1649 } 1800 }
1650 1801
1651 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { 1802 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() {
1652 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); 1803 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl);
1653 std::vector<SBFullHash> full_hashes; 1804 std::vector<SBFullHash> full_hashes;
1654 full_hashes.push_back(malware_kill_switch); 1805 full_hashes.push_back(malware_kill_switch);
1655 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 1806 return ContainsWhitelistedHashes(SBWhitelistId::CSD, full_hashes);
1656 } 1807 }
1657 1808
1658 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { 1809 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() {
1659 base::AutoLock locked(lookup_lock_); 1810 return state_manager_.BeginReadTransaction()
1660 return csd_whitelist_.second; 1811 ->GetSBWhitelist(SBWhitelistId::CSD)
1812 ->second;
1661 } 1813 }
1814
1815 SafeBrowsingDatabaseNew::PrefixGetHashCache*
1816 SafeBrowsingDatabaseNew::GetUnsynchronizedPrefixGetHashCacheForTesting() {
1817 return state_manager_.BeginReadTransaction()->prefix_gethash_cache();
1818 }
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