| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 FILE_PATH_LITERAL(" IP Blacklist"); | 59 FILE_PATH_LITERAL(" IP Blacklist"); |
| 60 | 60 |
| 61 // Filename suffix for browse store. | 61 // Filename suffix for browse store. |
| 62 // TODO(shess): "Safe Browsing Bloom Prefix Set" is full of win. | 62 // TODO(shess): "Safe Browsing Bloom Prefix Set" is full of win. |
| 63 // Unfortunately, to change the name implies lots of transition code | 63 // Unfortunately, to change the name implies lots of transition code |
| 64 // for little benefit. If/when file formats change (say to put all | 64 // for little benefit. If/when file formats change (say to put all |
| 65 // the data in one file), that would be a convenient point to rectify | 65 // the data in one file), that would be a convenient point to rectify |
| 66 // this. | 66 // this. |
| 67 const base::FilePath::CharType kBrowseDBFile[] = FILE_PATH_LITERAL(" Bloom"); | 67 const base::FilePath::CharType kBrowseDBFile[] = FILE_PATH_LITERAL(" Bloom"); |
| 68 | 68 |
| 69 // The maximum staleness for a cached entry. | |
| 70 const int kMaxStalenessMinutes = 45; | |
| 71 | |
| 72 // Maximum number of entries we allow in any of the whitelists. | 69 // Maximum number of entries we allow in any of the whitelists. |
| 73 // If a whitelist on disk contains more entries then all lookups to | 70 // If a whitelist on disk contains more entries then all lookups to |
| 74 // the whitelist will be considered a match. | 71 // the whitelist will be considered a match. |
| 75 const size_t kMaxWhitelistSize = 5000; | 72 const size_t kMaxWhitelistSize = 5000; |
| 76 | 73 |
| 77 // If the hash of this exact expression is on a whitelist then all | 74 // If the hash of this exact expression is on a whitelist then all |
| 78 // lookups to this whitelist will be considered a match. | 75 // lookups to this whitelist will be considered a match. |
| 79 const char kWhitelistKillSwitchUrl[] = | 76 const char kWhitelistKillSwitchUrl[] = |
| 80 "sb-ssl.google.com/safebrowsing/csd/killswitch"; // Don't change this! | 77 "sb-ssl.google.com/safebrowsing/csd/killswitch"; // Don't change this! |
| 81 | 78 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 if (prefix == iter->prefix && | 175 if (prefix == iter->prefix && |
| 179 GetListIdBit(iter->chunk_id) == list_bit) { | 176 GetListIdBit(iter->chunk_id) == list_bit) { |
| 180 prefix_hits->push_back(prefix); | 177 prefix_hits->push_back(prefix); |
| 181 found_match = true; | 178 found_match = true; |
| 182 } | 179 } |
| 183 } | 180 } |
| 184 } | 181 } |
| 185 return found_match; | 182 return found_match; |
| 186 } | 183 } |
| 187 | 184 |
| 188 // Find the entries in |full_hashes| with prefix in |prefix_hits|, and | |
| 189 // add them to |full_hits| if not expired. "Not expired" is when | |
| 190 // either |last_update| was recent enough, or the item has been | |
| 191 // received recently enough. Expired items are not deleted because a | |
| 192 // future update may make them acceptable again. | |
| 193 // | |
| 194 // For efficiency reasons the code walks |prefix_hits| and | |
| 195 // |full_hashes| in parallel, so they must be sorted by prefix. | |
| 196 void GetCachedFullHashesForBrowse(const std::vector<SBPrefix>& prefix_hits, | |
| 197 const std::vector<SBAddFullHash>& full_hashes, | |
| 198 std::vector<SBFullHashResult>* full_hits, | |
| 199 base::Time last_update) { | |
| 200 const base::Time expire_time = | |
| 201 base::Time::Now() - base::TimeDelta::FromMinutes(kMaxStalenessMinutes); | |
| 202 | |
| 203 std::vector<SBPrefix>::const_iterator piter = prefix_hits.begin(); | |
| 204 std::vector<SBAddFullHash>::const_iterator hiter = full_hashes.begin(); | |
| 205 | |
| 206 while (piter != prefix_hits.end() && hiter != full_hashes.end()) { | |
| 207 if (*piter < hiter->full_hash.prefix) { | |
| 208 ++piter; | |
| 209 } else if (hiter->full_hash.prefix < *piter) { | |
| 210 ++hiter; | |
| 211 } else { | |
| 212 if (expire_time < last_update || | |
| 213 expire_time.ToTimeT() < hiter->received) { | |
| 214 SBFullHashResult result; | |
| 215 const int list_bit = GetListIdBit(hiter->chunk_id); | |
| 216 DCHECK(list_bit == safe_browsing_util::MALWARE || | |
| 217 list_bit == safe_browsing_util::PHISH); | |
| 218 const safe_browsing_util::ListType list_id = | |
| 219 static_cast<safe_browsing_util::ListType>(list_bit); | |
| 220 if (!safe_browsing_util::GetListName(list_id, &result.list_name)) | |
| 221 continue; | |
| 222 result.add_chunk_id = DecodeChunkId(hiter->chunk_id); | |
| 223 result.hash = hiter->full_hash; | |
| 224 full_hits->push_back(result); | |
| 225 } | |
| 226 | |
| 227 // Only increment |hiter|, |piter| might have multiple hits. | |
| 228 ++hiter; | |
| 229 } | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 // This function generates a chunk range string for |chunks|. It | 185 // This function generates a chunk range string for |chunks|. It |
| 234 // outputs one chunk range string per list and writes it to the | 186 // outputs one chunk range string per list and writes it to the |
| 235 // |list_ranges| vector. We expect |list_ranges| to already be of the | 187 // |list_ranges| vector. We expect |list_ranges| to already be of the |
| 236 // right size. E.g., if |chunks| contains chunks with two different | 188 // right size. E.g., if |chunks| contains chunks with two different |
| 237 // list ids then |list_ranges| must contain two elements. | 189 // list ids then |list_ranges| must contain two elements. |
| 238 void GetChunkRanges(const std::vector<int>& chunks, | 190 void GetChunkRanges(const std::vector<int>& chunks, |
| 239 std::vector<std::string>* list_ranges) { | 191 std::vector<std::string>* list_ranges) { |
| 240 // Since there are 2 possible list ids, there must be exactly two | 192 // Since there are 2 possible list ids, there must be exactly two |
| 241 // list ranges. Even if the chunk data should only contain one | 193 // list ranges. Even if the chunk data should only contain one |
| 242 // line, this code has to somehow handle corruption. | 194 // line, this code has to somehow handle corruption. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 const std::string& listname, | 256 const std::string& listname, |
| 305 std::vector<SBListChunkRanges>* lists) { | 257 std::vector<SBListChunkRanges>* lists) { |
| 306 UpdateChunkRanges(store, std::vector<std::string>(1, listname), lists); | 258 UpdateChunkRanges(store, std::vector<std::string>(1, listname), lists); |
| 307 } | 259 } |
| 308 | 260 |
| 309 // Order |SBAddFullHash| on the prefix part. |SBAddPrefixLess()| from | 261 // Order |SBAddFullHash| on the prefix part. |SBAddPrefixLess()| from |
| 310 // safe_browsing_store.h orders on both chunk-id and prefix. | 262 // safe_browsing_store.h orders on both chunk-id and prefix. |
| 311 bool SBAddFullHashPrefixLess(const SBAddFullHash& a, const SBAddFullHash& b) { | 263 bool SBAddFullHashPrefixLess(const SBAddFullHash& a, const SBAddFullHash& b) { |
| 312 return a.full_hash.prefix < b.full_hash.prefix; | 264 return a.full_hash.prefix < b.full_hash.prefix; |
| 313 } | 265 } |
| 266 bool SBAddFullHashSBPrefixLess(const SBAddFullHash& a, SBPrefix b) { |
| 267 return a.full_hash.prefix < b; |
| 268 } |
| 314 | 269 |
| 315 // This code always checks for non-zero file size. This helper makes | 270 // This code always checks for non-zero file size. This helper makes |
| 316 // that less verbose. | 271 // that less verbose. |
| 317 int64 GetFileSizeOrZero(const base::FilePath& file_path) { | 272 int64 GetFileSizeOrZero(const base::FilePath& file_path) { |
| 318 int64 size_64; | 273 int64 size_64; |
| 319 if (!base::GetFileSize(file_path, &size_64)) | 274 if (!base::GetFileSize(file_path, &size_64)) |
| 320 return 0; | 275 return 0; |
| 321 return size_64; | 276 return size_64; |
| 322 } | 277 } |
| 323 | 278 |
| 324 // Used to order whitelist storage in memory. | |
| 325 bool SBFullHashLess(const SBFullHash& a, const SBFullHash& b) { | |
| 326 return memcmp(a.full_hash, b.full_hash, sizeof(a.full_hash)) < 0; | |
| 327 } | |
| 328 | |
| 329 } // namespace | 279 } // namespace |
| 330 | 280 |
| 331 // The default SafeBrowsingDatabaseFactory. | 281 // The default SafeBrowsingDatabaseFactory. |
| 332 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { | 282 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { |
| 333 public: | 283 public: |
| 334 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( | 284 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( |
| 335 bool enable_download_protection, | 285 bool enable_download_protection, |
| 336 bool enable_client_side_whitelist, | 286 bool enable_client_side_whitelist, |
| 337 bool enable_download_whitelist, | 287 bool enable_download_whitelist, |
| 338 bool enable_extension_blacklist, | 288 bool enable_extension_blacklist, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 base::Unretained(this))); | 474 base::Unretained(this))); |
| 525 DVLOG(1) << "Init browse store: " << browse_filename_.value(); | 475 DVLOG(1) << "Init browse store: " << browse_filename_.value(); |
| 526 | 476 |
| 527 { | 477 { |
| 528 // NOTE: There is no need to grab the lock in this function, since | 478 // NOTE: There is no need to grab the lock in this function, since |
| 529 // until it returns, there are no pointers to this class on other | 479 // until it returns, there are no pointers to this class on other |
| 530 // threads. Then again, that means there is no possibility of | 480 // threads. Then again, that means there is no possibility of |
| 531 // contention on the lock... | 481 // contention on the lock... |
| 532 base::AutoLock locked(lookup_lock_); | 482 base::AutoLock locked(lookup_lock_); |
| 533 full_browse_hashes_.clear(); | 483 full_browse_hashes_.clear(); |
| 534 pending_browse_hashes_.clear(); | 484 browse_gethash_cache_.clear(); |
| 535 LoadPrefixSet(); | 485 LoadPrefixSet(); |
| 536 } | 486 } |
| 537 | 487 |
| 538 if (download_store_.get()) { | 488 if (download_store_.get()) { |
| 539 download_filename_ = DownloadDBFilename(filename_base); | 489 download_filename_ = DownloadDBFilename(filename_base); |
| 540 download_store_->Init( | 490 download_store_->Init( |
| 541 download_filename_, | 491 download_filename_, |
| 542 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 492 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
| 543 base::Unretained(this))); | 493 base::Unretained(this))); |
| 544 DVLOG(1) << "Init download store: " << download_filename_.value(); | 494 DVLOG(1) << "Init download store: " << download_filename_.value(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 // Delete files on disk. | 598 // Delete files on disk. |
| 649 // TODO(shess): Hard to see where one might want to delete without a | 599 // TODO(shess): Hard to see where one might want to delete without a |
| 650 // reset. Perhaps inline |Delete()|? | 600 // reset. Perhaps inline |Delete()|? |
| 651 if (!Delete()) | 601 if (!Delete()) |
| 652 return false; | 602 return false; |
| 653 | 603 |
| 654 // Reset objects in memory. | 604 // Reset objects in memory. |
| 655 { | 605 { |
| 656 base::AutoLock locked(lookup_lock_); | 606 base::AutoLock locked(lookup_lock_); |
| 657 full_browse_hashes_.clear(); | 607 full_browse_hashes_.clear(); |
| 658 pending_browse_hashes_.clear(); | 608 browse_gethash_cache_.clear(); |
| 659 prefix_miss_cache_.clear(); | |
| 660 browse_prefix_set_.reset(); | 609 browse_prefix_set_.reset(); |
| 661 side_effect_free_whitelist_prefix_set_.reset(); | 610 side_effect_free_whitelist_prefix_set_.reset(); |
| 662 ip_blacklist_.clear(); | 611 ip_blacklist_.clear(); |
| 663 } | 612 } |
| 664 // Wants to acquire the lock itself. | 613 // Wants to acquire the lock itself. |
| 665 WhitelistEverything(&csd_whitelist_); | 614 WhitelistEverything(&csd_whitelist_); |
| 666 WhitelistEverything(&download_whitelist_); | 615 WhitelistEverything(&download_whitelist_); |
| 667 return true; | 616 return true; |
| 668 } | 617 } |
| 669 | 618 |
| 670 // TODO(lzheng): Remove matching_list, it is not used anywhere. | |
| 671 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( | 619 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( |
| 672 const GURL& url, | 620 const GURL& url, |
| 673 std::string* matching_list, | |
| 674 std::vector<SBPrefix>* prefix_hits, | 621 std::vector<SBPrefix>* prefix_hits, |
| 675 std::vector<SBFullHashResult>* full_hits, | 622 std::vector<SBFullHashResult>* cache_hits) { |
| 676 base::Time last_update) { | |
| 677 // Clear the results first. | 623 // Clear the results first. |
| 678 matching_list->clear(); | |
| 679 prefix_hits->clear(); | 624 prefix_hits->clear(); |
| 680 full_hits->clear(); | 625 cache_hits->clear(); |
| 681 | 626 |
| 682 std::vector<SBFullHash> full_hashes; | 627 std::vector<SBFullHash> full_hashes; |
| 683 BrowseFullHashesToCheck(url, false, &full_hashes); | 628 BrowseFullHashesToCheck(url, false, &full_hashes); |
| 684 if (full_hashes.empty()) | 629 if (full_hashes.empty()) |
| 685 return false; | 630 return false; |
| 686 | 631 |
| 632 std::sort(full_hashes.begin(), full_hashes.end(), SBFullHashLess); |
| 633 |
| 634 return ContainsBrowseUrlHashes(full_hashes, prefix_hits, cache_hits); |
| 635 } |
| 636 |
| 637 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashes( |
| 638 const std::vector<SBFullHash>& full_hashes, |
| 639 std::vector<SBPrefix>* prefix_hits, |
| 640 std::vector<SBFullHashResult>* cache_hits) { |
| 687 // This function is called on the I/O thread, prevent changes to | 641 // This function is called on the I/O thread, prevent changes to |
| 688 // filter and caches. | 642 // filter and caches. |
| 689 base::AutoLock locked(lookup_lock_); | 643 base::AutoLock locked(lookup_lock_); |
| 690 | 644 |
| 691 // |browse_prefix_set_| is empty until it is either read from disk, or the | 645 // |browse_prefix_set_| is empty until it is either read from disk, or the |
| 692 // first update populates it. Bail out without a hit if not yet | 646 // first update populates it. Bail out without a hit if not yet |
| 693 // available. | 647 // available. |
| 694 if (!browse_prefix_set_.get()) | 648 if (!browse_prefix_set_.get()) |
| 695 return false; | 649 return false; |
| 696 | 650 |
| 697 size_t miss_count = 0; | 651 const base::Time now = base::Time::Now(); |
| 652 |
| 698 for (size_t i = 0; i < full_hashes.size(); ++i) { | 653 for (size_t i = 0; i < full_hashes.size(); ++i) { |
| 699 const SBPrefix prefix = full_hashes[i].prefix; | 654 const SBPrefix prefix = full_hashes[i].prefix; |
| 655 |
| 656 // First check if there is a valid cached result for this prefix. |
| 657 std::map<SBPrefix, SBCachedFullHashResult>::iterator citer = |
| 658 browse_gethash_cache_.find(prefix); |
| 659 if (citer != browse_gethash_cache_.end()) { |
| 660 if (now <= citer->second.expire_after) { |
| 661 for (std::vector<SBFullHashResult>::const_iterator fiter = |
| 662 citer->second.full_hashes.begin(); |
| 663 fiter != citer->second.full_hashes.end(); |
| 664 ++fiter) { |
| 665 if (SBFullHashEqual(full_hashes[i], fiter->hash)) |
| 666 cache_hits->push_back(*fiter); |
| 667 } |
| 668 // If the prefix was in the cache, don't add the prefix to |
| 669 // prefix_hits. The result will be in cache_hits (if the fullhash |
| 670 // matched), or not (if it was a cached miss). |
| 671 continue; |
| 672 } |
| 673 |
| 674 // Remove expired entries. |
| 675 browse_gethash_cache_.erase(citer); |
| 676 } |
| 677 |
| 678 // There was no valid cached result for the prefix, so check the database. |
| 700 if (browse_prefix_set_->Exists(prefix)) { | 679 if (browse_prefix_set_->Exists(prefix)) { |
| 701 prefix_hits->push_back(prefix); | 680 if (prefix_hits->empty() || prefix_hits->back() != prefix) |
| 702 if (prefix_miss_cache_.count(prefix) > 0) | 681 prefix_hits->push_back(prefix); |
| 703 ++miss_count; | 682 continue; |
| 683 } |
| 684 |
| 685 // There was no prefix match, check for fullhash matches. |
| 686 std::vector<SBAddFullHash>::const_iterator db_fullhash_prefix_match = |
| 687 std::lower_bound(full_browse_hashes_.begin(), |
| 688 full_browse_hashes_.end(), |
| 689 prefix, |
| 690 SBAddFullHashSBPrefixLess); |
| 691 // If full_browse_hashes_ was sorted on the fullhash (not just the |
| 692 // prefix), could do binary_search here, but there are unlikely to be |
| 693 // enough prefix matches to matter. |
| 694 while (db_fullhash_prefix_match != full_browse_hashes_.end() && |
| 695 db_fullhash_prefix_match->full_hash.prefix == prefix) { |
| 696 if (SBFullHashEqual(db_fullhash_prefix_match->full_hash, |
| 697 full_hashes[i])) { |
| 698 if (prefix_hits->empty() || prefix_hits->back() != prefix) |
| 699 prefix_hits->push_back(prefix); |
| 700 break; |
| 701 } |
| 702 ++db_fullhash_prefix_match; |
| 704 } | 703 } |
| 705 } | 704 } |
| 706 | 705 |
| 707 // If all the prefixes are cached as 'misses', don't issue a GetHash. | 706 return !prefix_hits->empty() || !cache_hits->empty(); |
| 708 if (miss_count == prefix_hits->size()) | |
| 709 return false; | |
| 710 | |
| 711 // Find the matching full-hash results. |full_browse_hashes_| are from the | |
| 712 // database, |pending_browse_hashes_| are from GetHash requests between | |
| 713 // updates. | |
| 714 std::sort(prefix_hits->begin(), prefix_hits->end()); | |
| 715 | |
| 716 GetCachedFullHashesForBrowse(*prefix_hits, full_browse_hashes_, | |
| 717 full_hits, last_update); | |
| 718 GetCachedFullHashesForBrowse(*prefix_hits, pending_browse_hashes_, | |
| 719 full_hits, last_update); | |
| 720 return true; | |
| 721 } | 707 } |
| 722 | 708 |
| 723 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( | 709 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( |
| 724 const std::vector<GURL>& urls, | 710 const std::vector<GURL>& urls, |
| 725 std::vector<SBPrefix>* prefix_hits) { | 711 std::vector<SBPrefix>* prefix_hits) { |
| 726 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 712 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
| 727 | 713 |
| 728 // Ignore this check when download checking is not enabled. | 714 // Ignore this check when download checking is not enabled. |
| 729 if (!download_store_.get()) | 715 if (!download_store_.get()) |
| 730 return false; | 716 return false; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 STATS_COUNTER("SB.PrefixAdd", 1); | 854 STATS_COUNTER("SB.PrefixAdd", 1); |
| 869 store->WriteAddPrefix(encoded_chunk_id, host); | 855 store->WriteAddPrefix(encoded_chunk_id, host); |
| 870 } else if (entry->IsPrefix()) { | 856 } else if (entry->IsPrefix()) { |
| 871 // Prefixes only. | 857 // Prefixes only. |
| 872 for (int i = 0; i < count; i++) { | 858 for (int i = 0; i < count; i++) { |
| 873 const SBPrefix prefix = entry->PrefixAt(i); | 859 const SBPrefix prefix = entry->PrefixAt(i); |
| 874 STATS_COUNTER("SB.PrefixAdd", 1); | 860 STATS_COUNTER("SB.PrefixAdd", 1); |
| 875 store->WriteAddPrefix(encoded_chunk_id, prefix); | 861 store->WriteAddPrefix(encoded_chunk_id, prefix); |
| 876 } | 862 } |
| 877 } else { | 863 } else { |
| 878 // Prefixes and hashes. | 864 // Full hashes only. |
| 879 const base::Time receive_time = base::Time::Now(); | |
| 880 for (int i = 0; i < count; ++i) { | 865 for (int i = 0; i < count; ++i) { |
| 881 const SBFullHash full_hash = entry->FullHashAt(i); | 866 const SBFullHash full_hash = entry->FullHashAt(i); |
| 882 const SBPrefix prefix = full_hash.prefix; | |
| 883 | |
| 884 STATS_COUNTER("SB.PrefixAdd", 1); | |
| 885 store->WriteAddPrefix(encoded_chunk_id, prefix); | |
| 886 | 867 |
| 887 STATS_COUNTER("SB.PrefixAddFull", 1); | 868 STATS_COUNTER("SB.PrefixAddFull", 1); |
| 888 store->WriteAddHash(encoded_chunk_id, receive_time, full_hash); | 869 store->WriteAddHash(encoded_chunk_id, full_hash); |
| 889 } | 870 } |
| 890 } | 871 } |
| 891 } | 872 } |
| 892 | 873 |
| 893 // Helper to iterate over all the entries in the hosts in |chunks| and | 874 // Helper to iterate over all the entries in the hosts in |chunks| and |
| 894 // add them to the store. | 875 // add them to the store. |
| 895 void SafeBrowsingDatabaseNew::InsertAddChunks( | 876 void SafeBrowsingDatabaseNew::InsertAddChunks( |
| 896 const safe_browsing_util::ListType list_id, | 877 const safe_browsing_util::ListType list_id, |
| 897 const SBChunkList& chunks) { | 878 const SBChunkList& chunks) { |
| 898 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 879 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 // Prefixes only. | 924 // Prefixes only. |
| 944 for (int i = 0; i < count; i++) { | 925 for (int i = 0; i < count; i++) { |
| 945 const SBPrefix prefix = entry->PrefixAt(i); | 926 const SBPrefix prefix = entry->PrefixAt(i); |
| 946 const int add_chunk_id = | 927 const int add_chunk_id = |
| 947 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); | 928 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); |
| 948 | 929 |
| 949 STATS_COUNTER("SB.PrefixSub", 1); | 930 STATS_COUNTER("SB.PrefixSub", 1); |
| 950 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, prefix); | 931 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, prefix); |
| 951 } | 932 } |
| 952 } else { | 933 } else { |
| 953 // Prefixes and hashes. | 934 // Full hashes only. |
| 954 for (int i = 0; i < count; ++i) { | 935 for (int i = 0; i < count; ++i) { |
| 955 const SBFullHash full_hash = entry->FullHashAt(i); | 936 const SBFullHash full_hash = entry->FullHashAt(i); |
| 956 const int add_chunk_id = | 937 const int add_chunk_id = |
| 957 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); | 938 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); |
| 958 | 939 |
| 959 STATS_COUNTER("SB.PrefixSub", 1); | |
| 960 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, full_hash.prefix); | |
| 961 | |
| 962 STATS_COUNTER("SB.PrefixSubFull", 1); | 940 STATS_COUNTER("SB.PrefixSubFull", 1); |
| 963 store->WriteSubHash(encoded_chunk_id, add_chunk_id, full_hash); | 941 store->WriteSubHash(encoded_chunk_id, add_chunk_id, full_hash); |
| 964 } | 942 } |
| 965 } | 943 } |
| 966 } | 944 } |
| 967 | 945 |
| 968 // Helper to iterate over all the entries in the hosts in |chunks| and | 946 // Helper to iterate over all the entries in the hosts in |chunks| and |
| 969 // add them to the store. | 947 // add them to the store. |
| 970 void SafeBrowsingDatabaseNew::InsertSubChunks( | 948 void SafeBrowsingDatabaseNew::InsertSubChunks( |
| 971 safe_browsing_util::ListType list_id, | 949 safe_browsing_util::ListType list_id, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 if (chunk_deletes[i].is_sub_del) | 1024 if (chunk_deletes[i].is_sub_del) |
| 1047 store->DeleteSubChunk(encoded_chunk_id); | 1025 store->DeleteSubChunk(encoded_chunk_id); |
| 1048 else | 1026 else |
| 1049 store->DeleteAddChunk(encoded_chunk_id); | 1027 store->DeleteAddChunk(encoded_chunk_id); |
| 1050 } | 1028 } |
| 1051 } | 1029 } |
| 1052 } | 1030 } |
| 1053 | 1031 |
| 1054 void SafeBrowsingDatabaseNew::CacheHashResults( | 1032 void SafeBrowsingDatabaseNew::CacheHashResults( |
| 1055 const std::vector<SBPrefix>& prefixes, | 1033 const std::vector<SBPrefix>& prefixes, |
| 1056 const std::vector<SBFullHashResult>& full_hits) { | 1034 const std::vector<SBFullHashResult>& full_hits, |
| 1035 const base::TimeDelta& cache_lifetime) { |
| 1036 |
| 1037 const base::Time expire_after = base::Time::Now() + cache_lifetime; |
| 1038 |
| 1057 // This is called on the I/O thread, lock against updates. | 1039 // This is called on the I/O thread, lock against updates. |
| 1058 base::AutoLock locked(lookup_lock_); | 1040 base::AutoLock locked(lookup_lock_); |
| 1059 | 1041 |
| 1060 if (full_hits.empty()) { | 1042 // Create or reset all cached results for these prefixes. |
| 1061 prefix_miss_cache_.insert(prefixes.begin(), prefixes.end()); | 1043 for (std::vector<SBPrefix>::const_iterator i = prefixes.begin(); |
| 1062 return; | 1044 i != prefixes.end(); |
| 1045 ++i) { |
| 1046 browse_gethash_cache_[*i] = SBCachedFullHashResult(expire_after); |
| 1063 } | 1047 } |
| 1064 | 1048 |
| 1065 // TODO(shess): SBFullHashResult and SBAddFullHash are very similar. | 1049 // Insert any fullhash hits. Note that there may be one, multiple, or no |
| 1066 // Refactor to make them identical. | 1050 // fullhashes for any given entry in |prefixes|. |
| 1067 const base::Time now = base::Time::Now(); | 1051 for (std::vector<SBFullHashResult>::const_iterator i = full_hits.begin(); |
| 1068 const size_t orig_size = pending_browse_hashes_.size(); | 1052 i != full_hits.end(); |
| 1069 for (std::vector<SBFullHashResult>::const_iterator iter = full_hits.begin(); | 1053 ++i) { |
| 1070 iter != full_hits.end(); ++iter) { | 1054 browse_gethash_cache_[i->hash.prefix].full_hashes.push_back(*i); |
| 1071 const int list_id = safe_browsing_util::GetListId(iter->list_name); | |
| 1072 if (list_id == safe_browsing_util::MALWARE || | |
| 1073 list_id == safe_browsing_util::PHISH) { | |
| 1074 int encoded_chunk_id = EncodeChunkId(iter->add_chunk_id, list_id); | |
| 1075 SBAddFullHash add_full_hash(encoded_chunk_id, now, iter->hash); | |
| 1076 pending_browse_hashes_.push_back(add_full_hash); | |
| 1077 } | |
| 1078 } | 1055 } |
| 1079 | |
| 1080 // Sort new entries then merge with the previously-sorted entries. | |
| 1081 std::vector<SBAddFullHash>::iterator | |
| 1082 orig_end = pending_browse_hashes_.begin() + orig_size; | |
| 1083 std::sort(orig_end, pending_browse_hashes_.end(), SBAddFullHashPrefixLess); | |
| 1084 std::inplace_merge(pending_browse_hashes_.begin(), | |
| 1085 orig_end, pending_browse_hashes_.end(), | |
| 1086 SBAddFullHashPrefixLess); | |
| 1087 } | 1056 } |
| 1088 | 1057 |
| 1089 bool SafeBrowsingDatabaseNew::UpdateStarted( | 1058 bool SafeBrowsingDatabaseNew::UpdateStarted( |
| 1090 std::vector<SBListChunkRanges>* lists) { | 1059 std::vector<SBListChunkRanges>* lists) { |
| 1091 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1060 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
| 1092 DCHECK(lists); | 1061 DCHECK(lists); |
| 1093 | 1062 |
| 1094 // If |BeginUpdate()| fails, reset the database. | 1063 // If |BeginUpdate()| fails, reset the database. |
| 1095 if (!browse_store_->BeginUpdate()) { | 1064 if (!browse_store_->BeginUpdate()) { |
| 1096 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); | 1065 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 if (ip_blacklist_store_ && !ip_blacklist_store_->BeginUpdate()) { | 1103 if (ip_blacklist_store_ && !ip_blacklist_store_->BeginUpdate()) { |
| 1135 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_BEGIN); | 1104 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_BEGIN); |
| 1136 HandleCorruptDatabase(); | 1105 HandleCorruptDatabase(); |
| 1137 return false; | 1106 return false; |
| 1138 } | 1107 } |
| 1139 | 1108 |
| 1140 UpdateChunkRangesForLists(browse_store_.get(), | 1109 UpdateChunkRangesForLists(browse_store_.get(), |
| 1141 safe_browsing_util::kMalwareList, | 1110 safe_browsing_util::kMalwareList, |
| 1142 safe_browsing_util::kPhishingList, | 1111 safe_browsing_util::kPhishingList, |
| 1143 lists); | 1112 lists); |
| 1113 // Cached fullhash results must be cleared on every database update (whether |
| 1114 // successful or not.) |
| 1115 browse_gethash_cache_.clear(); |
| 1144 | 1116 |
| 1145 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been | 1117 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been |
| 1146 // deprecated. Code to delete the list from the store shows ~15k hits/day as | 1118 // deprecated. Code to delete the list from the store shows ~15k hits/day as |
| 1147 // of Feb 2014, so it has been removed. Everything _should_ be resilient to | 1119 // of Feb 2014, so it has been removed. Everything _should_ be resilient to |
| 1148 // extra data of that sort. | 1120 // extra data of that sort. |
| 1149 UpdateChunkRangesForList(download_store_.get(), | 1121 UpdateChunkRangesForList(download_store_.get(), |
| 1150 safe_browsing_util::kBinUrlList, lists); | 1122 safe_browsing_util::kBinUrlList, lists); |
| 1151 | 1123 |
| 1152 UpdateChunkRangesForList(csd_whitelist_store_.get(), | 1124 UpdateChunkRangesForList(csd_whitelist_store_.get(), |
| 1153 safe_browsing_util::kCsdWhiteList, lists); | 1125 safe_browsing_util::kCsdWhiteList, lists); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 UpdateIpBlacklistStore(); | 1240 UpdateIpBlacklistStore(); |
| 1269 } | 1241 } |
| 1270 | 1242 |
| 1271 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( | 1243 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( |
| 1272 const base::FilePath& store_filename, | 1244 const base::FilePath& store_filename, |
| 1273 SafeBrowsingStore* store, | 1245 SafeBrowsingStore* store, |
| 1274 SBWhitelist* whitelist) { | 1246 SBWhitelist* whitelist) { |
| 1275 if (!store) | 1247 if (!store) |
| 1276 return; | 1248 return; |
| 1277 | 1249 |
| 1278 // For the whitelists, we don't cache and save full hashes since all | |
| 1279 // hashes are already full. | |
| 1280 std::vector<SBAddFullHash> empty_add_hashes; | |
| 1281 | |
| 1282 // Note: |builder| will not be empty. The current data store implementation | 1250 // Note: |builder| will not be empty. The current data store implementation |
| 1283 // stores all full-length hashes as both full and prefix hashes. | 1251 // stores all full-length hashes as both full and prefix hashes. |
| 1284 safe_browsing::PrefixSetBuilder builder; | 1252 safe_browsing::PrefixSetBuilder builder; |
| 1285 std::vector<SBAddFullHash> full_hashes; | 1253 std::vector<SBAddFullHash> full_hashes; |
| 1286 if (!store->FinishUpdate(empty_add_hashes, &builder, &full_hashes)) { | 1254 if (!store->FinishUpdate(&builder, &full_hashes)) { |
| 1287 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); | 1255 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); |
| 1288 WhitelistEverything(whitelist); | 1256 WhitelistEverything(whitelist); |
| 1289 return; | 1257 return; |
| 1290 } | 1258 } |
| 1291 | 1259 |
| 1292 #if defined(OS_MACOSX) | 1260 #if defined(OS_MACOSX) |
| 1293 base::mac::SetFileBackupExclusion(store_filename); | 1261 base::mac::SetFileBackupExclusion(store_filename); |
| 1294 #endif | 1262 #endif |
| 1295 | 1263 |
| 1296 LoadWhitelist(full_hashes, whitelist); | 1264 LoadWhitelist(full_hashes, whitelist); |
| 1297 } | 1265 } |
| 1298 | 1266 |
| 1299 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( | 1267 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( |
| 1300 const base::FilePath& store_filename, | 1268 const base::FilePath& store_filename, |
| 1301 SafeBrowsingStore* store, | 1269 SafeBrowsingStore* store, |
| 1302 FailureType failure_type) { | 1270 FailureType failure_type) { |
| 1303 // We don't cache and save full hashes. | |
| 1304 std::vector<SBAddFullHash> empty_add_hashes; | |
| 1305 | |
| 1306 // These results are not used after this call. Simply ignore the | 1271 // These results are not used after this call. Simply ignore the |
| 1307 // returned value after FinishUpdate(...). | 1272 // returned value after FinishUpdate(...). |
| 1308 safe_browsing::PrefixSetBuilder builder; | 1273 safe_browsing::PrefixSetBuilder builder; |
| 1309 std::vector<SBAddFullHash> add_full_hashes_result; | 1274 std::vector<SBAddFullHash> add_full_hashes_result; |
| 1310 | 1275 |
| 1311 if (!store->FinishUpdate(empty_add_hashes, | 1276 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) { |
| 1312 &builder, | |
| 1313 &add_full_hashes_result)) { | |
| 1314 RecordFailure(failure_type); | 1277 RecordFailure(failure_type); |
| 1315 } | 1278 } |
| 1316 | 1279 |
| 1317 #if defined(OS_MACOSX) | 1280 #if defined(OS_MACOSX) |
| 1318 base::mac::SetFileBackupExclusion(store_filename); | 1281 base::mac::SetFileBackupExclusion(store_filename); |
| 1319 #endif | 1282 #endif |
| 1320 | 1283 |
| 1321 return GetFileSizeOrZero(store_filename); | 1284 return GetFileSizeOrZero(store_filename); |
| 1322 } | 1285 } |
| 1323 | 1286 |
| 1324 void SafeBrowsingDatabaseNew::UpdateBrowseStore() { | 1287 void SafeBrowsingDatabaseNew::UpdateBrowseStore() { |
| 1325 // Copy out the pending add hashes. Copy rather than swapping in | |
| 1326 // case |ContainsBrowseURL()| is called before the new filter is complete. | |
| 1327 std::vector<SBAddFullHash> pending_add_hashes; | |
| 1328 { | |
| 1329 base::AutoLock locked(lookup_lock_); | |
| 1330 pending_add_hashes.insert(pending_add_hashes.end(), | |
| 1331 pending_browse_hashes_.begin(), | |
| 1332 pending_browse_hashes_.end()); | |
| 1333 } | |
| 1334 | |
| 1335 // Measure the amount of IO during the filter build. | 1288 // Measure the amount of IO during the filter build. |
| 1336 base::IoCounters io_before, io_after; | 1289 base::IoCounters io_before, io_after; |
| 1337 base::ProcessHandle handle = base::Process::Current().handle(); | 1290 base::ProcessHandle handle = base::Process::Current().handle(); |
| 1338 scoped_ptr<base::ProcessMetrics> metric( | 1291 scoped_ptr<base::ProcessMetrics> metric( |
| 1339 #if !defined(OS_MACOSX) | 1292 #if !defined(OS_MACOSX) |
| 1340 base::ProcessMetrics::CreateProcessMetrics(handle) | 1293 base::ProcessMetrics::CreateProcessMetrics(handle) |
| 1341 #else | 1294 #else |
| 1342 // Getting stats only for the current process is enough, so NULL is fine. | 1295 // Getting stats only for the current process is enough, so NULL is fine. |
| 1343 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) | 1296 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) |
| 1344 #endif | 1297 #endif |
| 1345 ); | 1298 ); |
| 1346 | 1299 |
| 1347 // IoCounters are currently not supported on Mac, and may not be | 1300 // IoCounters are currently not supported on Mac, and may not be |
| 1348 // available for Linux, so we check the result and only show IO | 1301 // available for Linux, so we check the result and only show IO |
| 1349 // stats if they are available. | 1302 // stats if they are available. |
| 1350 const bool got_counters = metric->GetIOCounters(&io_before); | 1303 const bool got_counters = metric->GetIOCounters(&io_before); |
| 1351 | 1304 |
| 1352 const base::TimeTicks before = base::TimeTicks::Now(); | 1305 const base::TimeTicks before = base::TimeTicks::Now(); |
| 1353 | 1306 |
| 1354 safe_browsing::PrefixSetBuilder builder; | 1307 safe_browsing::PrefixSetBuilder builder; |
| 1355 std::vector<SBAddFullHash> add_full_hashes; | 1308 std::vector<SBAddFullHash> add_full_hashes; |
| 1356 if (!browse_store_->FinishUpdate(pending_add_hashes, | 1309 if (!browse_store_->FinishUpdate(&builder, &add_full_hashes)) { |
| 1357 &builder, &add_full_hashes)) { | |
| 1358 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_FINISH); | 1310 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_FINISH); |
| 1359 return; | 1311 return; |
| 1360 } | 1312 } |
| 1361 scoped_ptr<safe_browsing::PrefixSet> prefix_set(builder.GetPrefixSet()); | 1313 scoped_ptr<safe_browsing::PrefixSet> prefix_set(builder.GetPrefixSet()); |
| 1362 | 1314 |
| 1363 // This needs to be in sorted order by prefix for efficient access. | 1315 // This needs to be in sorted order by prefix for efficient access. |
| 1364 std::sort(add_full_hashes.begin(), add_full_hashes.end(), | 1316 std::sort(add_full_hashes.begin(), add_full_hashes.end(), |
| 1365 SBAddFullHashPrefixLess); | 1317 SBAddFullHashPrefixLess); |
| 1366 | 1318 |
| 1367 // Swap in the newly built filter and cache. | 1319 // Swap in the newly built filter and cache. |
| 1368 { | 1320 { |
| 1369 base::AutoLock locked(lookup_lock_); | 1321 base::AutoLock locked(lookup_lock_); |
| 1370 full_browse_hashes_.swap(add_full_hashes); | 1322 full_browse_hashes_.swap(add_full_hashes); |
| 1371 | |
| 1372 // TODO(shess): If |CacheHashResults()| is posted between the | |
| 1373 // earlier lock and this clear, those pending hashes will be lost. | |
| 1374 // It could be fixed by only removing hashes which were collected | |
| 1375 // at the earlier point. I believe that is fail-safe as-is (the | |
| 1376 // hash will be fetched again). | |
| 1377 pending_browse_hashes_.clear(); | |
| 1378 prefix_miss_cache_.clear(); | |
| 1379 browse_prefix_set_.swap(prefix_set); | 1323 browse_prefix_set_.swap(prefix_set); |
| 1380 } | 1324 } |
| 1381 | 1325 |
| 1382 DVLOG(1) << "SafeBrowsingDatabaseImpl built prefix set in " | 1326 DVLOG(1) << "SafeBrowsingDatabaseImpl built prefix set in " |
| 1383 << (base::TimeTicks::Now() - before).InMilliseconds() | 1327 << (base::TimeTicks::Now() - before).InMilliseconds() |
| 1384 << " ms total."; | 1328 << " ms total."; |
| 1385 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); | 1329 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); |
| 1386 | 1330 |
| 1387 // Persist the prefix set to disk. Since only this thread changes | 1331 // Persist the prefix set to disk. Since only this thread changes |
| 1388 // |browse_prefix_set_|, there is no need to lock. | 1332 // |browse_prefix_set_|, there is no need to lock. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1410 file_size = GetFileSizeOrZero(browse_filename_); | 1354 file_size = GetFileSizeOrZero(browse_filename_); |
| 1411 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", | 1355 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", |
| 1412 static_cast<int>(file_size / 1024)); | 1356 static_cast<int>(file_size / 1024)); |
| 1413 | 1357 |
| 1414 #if defined(OS_MACOSX) | 1358 #if defined(OS_MACOSX) |
| 1415 base::mac::SetFileBackupExclusion(browse_filename_); | 1359 base::mac::SetFileBackupExclusion(browse_filename_); |
| 1416 #endif | 1360 #endif |
| 1417 } | 1361 } |
| 1418 | 1362 |
| 1419 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { | 1363 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { |
| 1420 std::vector<SBAddFullHash> empty_add_hashes; | |
| 1421 safe_browsing::PrefixSetBuilder builder; | 1364 safe_browsing::PrefixSetBuilder builder; |
| 1422 std::vector<SBAddFullHash> add_full_hashes_result; | 1365 std::vector<SBAddFullHash> add_full_hashes_result; |
| 1423 | 1366 |
| 1424 if (!side_effect_free_whitelist_store_->FinishUpdate( | 1367 if (!side_effect_free_whitelist_store_->FinishUpdate( |
| 1425 empty_add_hashes, | 1368 &builder, &add_full_hashes_result)) { |
| 1426 &builder, | |
| 1427 &add_full_hashes_result)) { | |
| 1428 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); | 1369 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); |
| 1429 return; | 1370 return; |
| 1430 } | 1371 } |
| 1431 scoped_ptr<safe_browsing::PrefixSet> prefix_set(builder.GetPrefixSet()); | 1372 scoped_ptr<safe_browsing::PrefixSet> prefix_set(builder.GetPrefixSet()); |
| 1432 | 1373 |
| 1433 // Swap in the newly built prefix set. | 1374 // Swap in the newly built prefix set. |
| 1434 { | 1375 { |
| 1435 base::AutoLock locked(lookup_lock_); | 1376 base::AutoLock locked(lookup_lock_); |
| 1436 side_effect_free_whitelist_prefix_set_.swap(prefix_set); | 1377 side_effect_free_whitelist_prefix_set_.swap(prefix_set); |
| 1437 } | 1378 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1458 static_cast<int>(file_size / 1024)); | 1399 static_cast<int>(file_size / 1024)); |
| 1459 | 1400 |
| 1460 #if defined(OS_MACOSX) | 1401 #if defined(OS_MACOSX) |
| 1461 base::mac::SetFileBackupExclusion(side_effect_free_whitelist_filename_); | 1402 base::mac::SetFileBackupExclusion(side_effect_free_whitelist_filename_); |
| 1462 base::mac::SetFileBackupExclusion( | 1403 base::mac::SetFileBackupExclusion( |
| 1463 side_effect_free_whitelist_prefix_set_filename_); | 1404 side_effect_free_whitelist_prefix_set_filename_); |
| 1464 #endif | 1405 #endif |
| 1465 } | 1406 } |
| 1466 | 1407 |
| 1467 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { | 1408 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { |
| 1468 // For the IP blacklist, we don't cache and save full hashes since all | |
| 1469 // hashes are already full. | |
| 1470 std::vector<SBAddFullHash> empty_add_hashes; | |
| 1471 | |
| 1472 // Note: prefixes will not be empty. The current data store implementation | 1409 // Note: prefixes will not be empty. The current data store implementation |
| 1473 // stores all full-length hashes as both full and prefix hashes. | 1410 // stores all full-length hashes as both full and prefix hashes. |
| 1474 safe_browsing::PrefixSetBuilder builder; | 1411 safe_browsing::PrefixSetBuilder builder; |
| 1475 std::vector<SBAddFullHash> full_hashes; | 1412 std::vector<SBAddFullHash> full_hashes; |
| 1476 if (!ip_blacklist_store_->FinishUpdate(empty_add_hashes, | 1413 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { |
| 1477 &builder, &full_hashes)) { | |
| 1478 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); | 1414 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); |
| 1479 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. | 1415 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. |
| 1480 return; | 1416 return; |
| 1481 } | 1417 } |
| 1482 | 1418 |
| 1483 #if defined(OS_MACOSX) | 1419 #if defined(OS_MACOSX) |
| 1484 base::mac::SetFileBackupExclusion(ip_blacklist_filename_); | 1420 base::mac::SetFileBackupExclusion(ip_blacklist_filename_); |
| 1485 #endif | 1421 #endif |
| 1486 | 1422 |
| 1487 LoadIpBlacklist(full_hashes); | 1423 LoadIpBlacklist(full_hashes); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 base::AutoLock locked(lookup_lock_); | 1619 base::AutoLock locked(lookup_lock_); |
| 1684 ip_blacklist_.swap(new_blacklist); | 1620 ip_blacklist_.swap(new_blacklist); |
| 1685 } | 1621 } |
| 1686 | 1622 |
| 1687 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { | 1623 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
| 1688 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1624 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
| 1689 std::vector<SBFullHash> full_hashes; | 1625 std::vector<SBFullHash> full_hashes; |
| 1690 full_hashes.push_back(malware_kill_switch); | 1626 full_hashes.push_back(malware_kill_switch); |
| 1691 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1627 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
| 1692 } | 1628 } |
| OLD | NEW |