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 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 DCHECK(side_effect_free_whitelist_filename_.empty()); | 498 DCHECK(side_effect_free_whitelist_filename_.empty()); |
499 DCHECK(ip_blacklist_filename_.empty()); | 499 DCHECK(ip_blacklist_filename_.empty()); |
500 | 500 |
501 browse_filename_ = BrowseDBFilename(filename_base); | 501 browse_filename_ = BrowseDBFilename(filename_base); |
502 browse_prefix_set_filename_ = PrefixSetForFilename(browse_filename_); | 502 browse_prefix_set_filename_ = PrefixSetForFilename(browse_filename_); |
503 | 503 |
504 browse_store_->Init( | 504 browse_store_->Init( |
505 browse_filename_, | 505 browse_filename_, |
506 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 506 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
507 base::Unretained(this))); | 507 base::Unretained(this))); |
508 DVLOG(1) << "Init browse store: " << browse_filename_.value(); | |
509 | 508 |
510 { | 509 { |
511 // NOTE: There is no need to grab the lock in this function, since | 510 // NOTE: There is no need to grab the lock in this function, since |
512 // until it returns, there are no pointers to this class on other | 511 // until it returns, there are no pointers to this class on other |
513 // threads. Then again, that means there is no possibility of | 512 // threads. Then again, that means there is no possibility of |
514 // contention on the lock... | 513 // contention on the lock... |
515 base::AutoLock locked(lookup_lock_); | 514 base::AutoLock locked(lookup_lock_); |
516 cached_browse_hashes_.clear(); | 515 cached_browse_hashes_.clear(); |
517 LoadPrefixSet(); | 516 LoadPrefixSet(); |
518 } | 517 } |
519 | 518 |
520 if (download_store_.get()) { | 519 if (download_store_.get()) { |
521 download_filename_ = DownloadDBFilename(filename_base); | 520 download_filename_ = DownloadDBFilename(filename_base); |
522 download_store_->Init( | 521 download_store_->Init( |
523 download_filename_, | 522 download_filename_, |
524 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 523 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
525 base::Unretained(this))); | 524 base::Unretained(this))); |
526 DVLOG(1) << "Init download store: " << download_filename_.value(); | |
527 } | 525 } |
528 | 526 |
529 if (csd_whitelist_store_.get()) { | 527 if (csd_whitelist_store_.get()) { |
530 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base); | 528 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base); |
531 csd_whitelist_store_->Init( | 529 csd_whitelist_store_->Init( |
532 csd_whitelist_filename_, | 530 csd_whitelist_filename_, |
533 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 531 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
534 base::Unretained(this))); | 532 base::Unretained(this))); |
535 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value(); | 533 |
536 std::vector<SBAddFullHash> full_hashes; | 534 std::vector<SBAddFullHash> full_hashes; |
537 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { | 535 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { |
538 LoadWhitelist(full_hashes, &csd_whitelist_); | 536 LoadWhitelist(full_hashes, &csd_whitelist_); |
539 } else { | 537 } else { |
540 WhitelistEverything(&csd_whitelist_); | 538 WhitelistEverything(&csd_whitelist_); |
541 } | 539 } |
542 } else { | 540 } else { |
543 WhitelistEverything(&csd_whitelist_); // Just to be safe. | 541 WhitelistEverything(&csd_whitelist_); // Just to be safe. |
544 } | 542 } |
545 | 543 |
546 if (download_whitelist_store_.get()) { | 544 if (download_whitelist_store_.get()) { |
547 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base); | 545 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base); |
548 download_whitelist_store_->Init( | 546 download_whitelist_store_->Init( |
549 download_whitelist_filename_, | 547 download_whitelist_filename_, |
550 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 548 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
551 base::Unretained(this))); | 549 base::Unretained(this))); |
552 DVLOG(1) << "Init download whitelist store: " | 550 |
553 << download_whitelist_filename_.value(); | |
554 std::vector<SBAddFullHash> full_hashes; | 551 std::vector<SBAddFullHash> full_hashes; |
555 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) { | 552 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) { |
556 LoadWhitelist(full_hashes, &download_whitelist_); | 553 LoadWhitelist(full_hashes, &download_whitelist_); |
557 } else { | 554 } else { |
558 WhitelistEverything(&download_whitelist_); | 555 WhitelistEverything(&download_whitelist_); |
559 } | 556 } |
560 } else { | 557 } else { |
561 WhitelistEverything(&download_whitelist_); // Just to be safe. | 558 WhitelistEverything(&download_whitelist_); // Just to be safe. |
562 } | 559 } |
563 | 560 |
564 if (extension_blacklist_store_.get()) { | 561 if (extension_blacklist_store_.get()) { |
565 extension_blacklist_filename_ = ExtensionBlacklistDBFilename(filename_base); | 562 extension_blacklist_filename_ = ExtensionBlacklistDBFilename(filename_base); |
566 extension_blacklist_store_->Init( | 563 extension_blacklist_store_->Init( |
567 extension_blacklist_filename_, | 564 extension_blacklist_filename_, |
568 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 565 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
569 base::Unretained(this))); | 566 base::Unretained(this))); |
570 DVLOG(1) << "Init extension blacklist store: " | |
571 << extension_blacklist_filename_.value(); | |
572 } | 567 } |
573 | 568 |
574 if (side_effect_free_whitelist_store_.get()) { | 569 if (side_effect_free_whitelist_store_.get()) { |
575 side_effect_free_whitelist_filename_ = | 570 side_effect_free_whitelist_filename_ = |
576 SideEffectFreeWhitelistDBFilename(filename_base); | 571 SideEffectFreeWhitelistDBFilename(filename_base); |
577 side_effect_free_whitelist_prefix_set_filename_ = | 572 side_effect_free_whitelist_prefix_set_filename_ = |
578 PrefixSetForFilename(side_effect_free_whitelist_filename_); | 573 PrefixSetForFilename(side_effect_free_whitelist_filename_); |
579 side_effect_free_whitelist_store_->Init( | 574 side_effect_free_whitelist_store_->Init( |
580 side_effect_free_whitelist_filename_, | 575 side_effect_free_whitelist_filename_, |
581 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 576 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
582 base::Unretained(this))); | 577 base::Unretained(this))); |
583 DVLOG(1) << "Init side-effect free whitelist store: " | |
584 << side_effect_free_whitelist_filename_.value(); | |
585 | 578 |
586 // If there is no database, the filter cannot be used. | 579 // If there is no database, the filter cannot be used. |
587 base::File::Info db_info; | 580 base::File::Info db_info; |
588 if (base::GetFileInfo(side_effect_free_whitelist_filename_, &db_info) | 581 if (base::GetFileInfo(side_effect_free_whitelist_filename_, &db_info) |
589 && db_info.size != 0) { | 582 && db_info.size != 0) { |
590 const base::TimeTicks before = base::TimeTicks::Now(); | 583 const base::TimeTicks before = base::TimeTicks::Now(); |
591 side_effect_free_whitelist_prefix_set_ = | 584 side_effect_free_whitelist_prefix_set_ = |
592 safe_browsing::PrefixSet::LoadFile( | 585 safe_browsing::PrefixSet::LoadFile( |
593 side_effect_free_whitelist_prefix_set_filename_); | 586 side_effect_free_whitelist_prefix_set_filename_); |
594 DVLOG(1) << "SafeBrowsingDatabaseNew read side-effect free whitelist " | |
595 << "prefix set in " | |
596 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | |
597 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreeWhitelistPrefixSetLoad", | 587 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreeWhitelistPrefixSetLoad", |
598 base::TimeTicks::Now() - before); | 588 base::TimeTicks::Now() - before); |
599 if (!side_effect_free_whitelist_prefix_set_.get()) | 589 if (!side_effect_free_whitelist_prefix_set_.get()) |
600 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ); | 590 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ); |
601 } | 591 } |
602 } else { | 592 } else { |
603 // Delete any files of the side-effect free sidelist that may be around | 593 // Delete any files of the side-effect free sidelist that may be around |
604 // from when it was previously enabled. | 594 // from when it was previously enabled. |
605 SafeBrowsingStoreFile::DeleteStore( | 595 SafeBrowsingStoreFile::DeleteStore( |
606 SideEffectFreeWhitelistDBFilename(filename_base)); | 596 SideEffectFreeWhitelistDBFilename(filename_base)); |
607 } | 597 } |
608 | 598 |
609 if (ip_blacklist_store_.get()) { | 599 if (ip_blacklist_store_.get()) { |
610 ip_blacklist_filename_ = IpBlacklistDBFilename(filename_base); | 600 ip_blacklist_filename_ = IpBlacklistDBFilename(filename_base); |
611 ip_blacklist_store_->Init( | 601 ip_blacklist_store_->Init( |
612 ip_blacklist_filename_, | 602 ip_blacklist_filename_, |
613 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 603 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
614 base::Unretained(this))); | 604 base::Unretained(this))); |
615 DVLOG(1) << "SafeBrowsingDatabaseNew read ip blacklist: " | 605 |
616 << ip_blacklist_filename_.value(); | |
617 std::vector<SBAddFullHash> full_hashes; | 606 std::vector<SBAddFullHash> full_hashes; |
618 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { | 607 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { |
619 LoadIpBlacklist(full_hashes); | 608 LoadIpBlacklist(full_hashes); |
620 } else { | 609 } else { |
621 DVLOG(1) << "Unable to load full hashes from the IP blacklist."; | |
622 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. | 610 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. |
623 } | 611 } |
624 } | 612 } |
625 } | 613 } |
626 | 614 |
627 bool SafeBrowsingDatabaseNew::ResetDatabase() { | 615 bool SafeBrowsingDatabaseNew::ResetDatabase() { |
628 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 616 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
629 | 617 |
630 // Delete files on disk. | 618 // Delete files on disk. |
631 // TODO(shess): Hard to see where one might want to delete without a | 619 // TODO(shess): Hard to see where one might want to delete without a |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
755 // from disk, or the first update populates it. Bail out without a hit if | 743 // from disk, or the first update populates it. Bail out without a hit if |
756 // not yet available. | 744 // not yet available. |
757 if (!side_effect_free_whitelist_prefix_set_.get()) | 745 if (!side_effect_free_whitelist_prefix_set_.get()) |
758 return false; | 746 return false; |
759 | 747 |
760 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); | 748 return side_effect_free_whitelist_prefix_set_->Exists(full_hash); |
761 } | 749 } |
762 | 750 |
763 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { | 751 bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { |
764 net::IPAddressNumber ip_number; | 752 net::IPAddressNumber ip_number; |
765 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) { | 753 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) |
766 DVLOG(2) << "Unable to parse IP address: '" << ip_address << "'"; | |
767 return false; | 754 return false; |
768 } | 755 if (ip_number.size() == net::kIPv4AddressSize) |
769 if (ip_number.size() == net::kIPv4AddressSize) { | |
770 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); | 756 ip_number = net::ConvertIPv4NumberToIPv6Number(ip_number); |
771 } | 757 if (ip_number.size() != net::kIPv6AddressSize) |
772 if (ip_number.size() != net::kIPv6AddressSize) { | |
773 DVLOG(2) << "Unable to convert IPv4 address to IPv6: '" | |
774 << ip_address << "'"; | |
775 return false; // better safe than sorry. | 758 return false; // better safe than sorry. |
776 } | 759 |
777 // This function can be called from any thread. | 760 // This function can be called from any thread. |
778 base::AutoLock locked(lookup_lock_); | 761 base::AutoLock locked(lookup_lock_); |
779 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); | 762 for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); |
780 it != ip_blacklist_.end(); | 763 it != ip_blacklist_.end(); |
781 ++it) { | 764 ++it) { |
782 const std::string& mask = it->first; | 765 const std::string& mask = it->first; |
783 DCHECK_EQ(mask.size(), ip_number.size()); | 766 DCHECK_EQ(mask.size(), ip_number.size()); |
784 std::string subnet(net::kIPv6AddressSize, '\0'); | 767 std::string subnet(net::kIPv6AddressSize, '\0'); |
785 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { | 768 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { |
786 subnet[i] = ip_number[i] & mask[i]; | 769 subnet[i] = ip_number[i] & mask[i]; |
787 } | 770 } |
788 const std::string hash = base::SHA1HashString(subnet); | 771 const std::string hash = base::SHA1HashString(subnet); |
789 DVLOG(2) << "Lookup Malware IP: " | 772 DVLOG(2) << "Lookup Malware IP: " |
790 << " ip:" << ip_address | 773 << " ip:" << ip_address |
791 << " mask:" << base::HexEncode(mask.data(), mask.size()) | 774 << " mask:" << base::HexEncode(mask.data(), mask.size()) |
792 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) | 775 << " subnet:" << base::HexEncode(subnet.data(), subnet.size()) |
793 << " hash:" << base::HexEncode(hash.data(), hash.size()); | 776 << " hash:" << base::HexEncode(hash.data(), hash.size()); |
Scott Hess - ex-Googler
2014/06/18 00:08:41
I did not remove this one because it looks complic
| |
794 if (it->second.count(hash) > 0) { | 777 if (it->second.count(hash) > 0) { |
795 return true; | 778 return true; |
796 } | 779 } |
797 } | 780 } |
798 return false; | 781 return false; |
799 } | 782 } |
800 | 783 |
801 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( | 784 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( |
802 const std::string& str) { | 785 const std::string& str) { |
803 std::vector<SBFullHash> hashes; | 786 std::vector<SBFullHash> hashes; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
895 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 878 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
896 | 879 |
897 if (corruption_detected_ || chunks.empty()) | 880 if (corruption_detected_ || chunks.empty()) |
898 return; | 881 return; |
899 | 882 |
900 const base::TimeTicks before = base::TimeTicks::Now(); | 883 const base::TimeTicks before = base::TimeTicks::Now(); |
901 | 884 |
902 // TODO(shess): The caller should just pass list_id. | 885 // TODO(shess): The caller should just pass list_id. |
903 const safe_browsing_util::ListType list_id = | 886 const safe_browsing_util::ListType list_id = |
904 safe_browsing_util::GetListId(list_name); | 887 safe_browsing_util::GetListId(list_name); |
905 DVLOG(2) << list_name << ": " << list_id; | |
906 | 888 |
907 SafeBrowsingStore* store = GetStore(list_id); | 889 SafeBrowsingStore* store = GetStore(list_id); |
908 if (!store) return; | 890 if (!store) return; |
909 | 891 |
910 change_detected_ = true; | 892 change_detected_ = true; |
911 | 893 |
912 // TODO(shess): I believe that the list is always add or sub. Can this use | 894 // TODO(shess): I believe that the list is always add or sub. Can this use |
913 // that productively? | 895 // that productively? |
914 store->BeginChunk(); | 896 store->BeginChunk(); |
915 for (size_t i = 0; i < chunks.size(); ++i) { | 897 for (size_t i = 0; i < chunks.size(); ++i) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1261 // TODO(shess): If |CacheHashResults()| is posted between the | 1243 // TODO(shess): If |CacheHashResults()| is posted between the |
1262 // earlier lock and this clear, those pending hashes will be lost. | 1244 // earlier lock and this clear, those pending hashes will be lost. |
1263 // It could be fixed by only removing hashes which were collected | 1245 // It could be fixed by only removing hashes which were collected |
1264 // at the earlier point. I believe that is fail-safe as-is (the | 1246 // at the earlier point. I believe that is fail-safe as-is (the |
1265 // hash will be fetched again). | 1247 // hash will be fetched again). |
1266 cached_browse_hashes_.clear(); | 1248 cached_browse_hashes_.clear(); |
1267 prefix_miss_cache_.clear(); | 1249 prefix_miss_cache_.clear(); |
1268 browse_prefix_set_.swap(prefix_set); | 1250 browse_prefix_set_.swap(prefix_set); |
1269 } | 1251 } |
1270 | 1252 |
1271 DVLOG(1) << "SafeBrowsingDatabaseImpl built prefix set in " | |
1272 << (base::TimeTicks::Now() - before).InMilliseconds() | |
1273 << " ms total."; | |
1274 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); | 1253 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); |
1275 | 1254 |
1276 // Persist the prefix set to disk. Since only this thread changes | 1255 // Persist the prefix set to disk. Since only this thread changes |
1277 // |browse_prefix_set_|, there is no need to lock. | 1256 // |browse_prefix_set_|, there is no need to lock. |
1278 WritePrefixSet(); | 1257 WritePrefixSet(); |
1279 | 1258 |
1280 // Gather statistics. | 1259 // Gather statistics. |
1281 if (got_counters && metric->GetIOCounters(&io_after)) { | 1260 if (got_counters && metric->GetIOCounters(&io_after)) { |
1282 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", | 1261 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", |
1283 static_cast<int>(io_after.ReadTransferCount - | 1262 static_cast<int>(io_after.ReadTransferCount - |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1319 | 1298 |
1320 // Swap in the newly built prefix set. | 1299 // Swap in the newly built prefix set. |
1321 { | 1300 { |
1322 base::AutoLock locked(lookup_lock_); | 1301 base::AutoLock locked(lookup_lock_); |
1323 side_effect_free_whitelist_prefix_set_.swap(prefix_set); | 1302 side_effect_free_whitelist_prefix_set_.swap(prefix_set); |
1324 } | 1303 } |
1325 | 1304 |
1326 const base::TimeTicks before = base::TimeTicks::Now(); | 1305 const base::TimeTicks before = base::TimeTicks::Now(); |
1327 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( | 1306 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( |
1328 side_effect_free_whitelist_prefix_set_filename_); | 1307 side_effect_free_whitelist_prefix_set_filename_); |
1329 DVLOG(1) << "SafeBrowsingDatabaseNew wrote side-effect free whitelist prefix " | |
1330 << "set in " << (base::TimeTicks::Now() - before).InMilliseconds() | |
1331 << " ms"; | |
1332 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", | 1308 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", |
1333 base::TimeTicks::Now() - before); | 1309 base::TimeTicks::Now() - before); |
1334 | 1310 |
1335 if (!write_ok) | 1311 if (!write_ok) |
1336 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE); | 1312 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE); |
1337 | 1313 |
1338 // Gather statistics. | 1314 // Gather statistics. |
1339 int64 file_size = GetFileSizeOrZero( | 1315 int64 file_size = GetFileSizeOrZero( |
1340 side_effect_free_whitelist_prefix_set_filename_); | 1316 side_effect_free_whitelist_prefix_set_filename_); |
1341 UMA_HISTOGRAM_COUNTS("SB2.SideEffectFreeWhitelistPrefixSetKilobytes", | 1317 UMA_HISTOGRAM_COUNTS("SB2.SideEffectFreeWhitelistPrefixSetKilobytes", |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1377 base::MessageLoop::current()->PostTask(FROM_HERE, | 1353 base::MessageLoop::current()->PostTask(FROM_HERE, |
1378 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, | 1354 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, |
1379 reset_factory_.GetWeakPtr())); | 1355 reset_factory_.GetWeakPtr())); |
1380 } | 1356 } |
1381 } | 1357 } |
1382 | 1358 |
1383 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { | 1359 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { |
1384 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); | 1360 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); |
1385 corruption_detected_ = true; // Stop updating the database. | 1361 corruption_detected_ = true; // Stop updating the database. |
1386 ResetDatabase(); | 1362 ResetDatabase(); |
1363 | |
1364 // NOTE(shess): ResetDatabase() should remove the corruption, so this should | |
1365 // only happen once. If you are here because you are hitting this after a | |
1366 // restart, then I would be very interested in working with you to figure out | |
1367 // what is happening, since it may affect real users. | |
1387 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; | 1368 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; |
1388 } | 1369 } |
1389 | 1370 |
1390 // TODO(shess): I'm not clear why this code doesn't have any | 1371 // TODO(shess): I'm not clear why this code doesn't have any |
1391 // real error-handling. | 1372 // real error-handling. |
1392 void SafeBrowsingDatabaseNew::LoadPrefixSet() { | 1373 void SafeBrowsingDatabaseNew::LoadPrefixSet() { |
1393 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1374 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1394 DCHECK(!browse_prefix_set_filename_.empty()); | 1375 DCHECK(!browse_prefix_set_filename_.empty()); |
1395 | 1376 |
1396 // If there is no database, the filter cannot be used. | 1377 // If there is no database, the filter cannot be used. |
1397 base::File::Info db_info; | 1378 base::File::Info db_info; |
1398 if (!base::GetFileInfo(browse_filename_, &db_info) || db_info.size == 0) | 1379 if (!base::GetFileInfo(browse_filename_, &db_info) || db_info.size == 0) |
1399 return; | 1380 return; |
1400 | 1381 |
1401 // Cleanup any stale bloom filter (no longer used). | 1382 // Cleanup any stale bloom filter (no longer used). |
1402 // TODO(shess): Track failure to delete? | 1383 // TODO(shess): Track failure to delete? |
1403 base::FilePath bloom_filter_filename = | 1384 base::FilePath bloom_filter_filename = |
1404 BloomFilterForFilename(browse_filename_); | 1385 BloomFilterForFilename(browse_filename_); |
1405 base::DeleteFile(bloom_filter_filename, false); | 1386 base::DeleteFile(bloom_filter_filename, false); |
1406 | 1387 |
1407 const base::TimeTicks before = base::TimeTicks::Now(); | 1388 const base::TimeTicks before = base::TimeTicks::Now(); |
1408 browse_prefix_set_ = safe_browsing::PrefixSet::LoadFile( | 1389 browse_prefix_set_ = safe_browsing::PrefixSet::LoadFile( |
1409 browse_prefix_set_filename_); | 1390 browse_prefix_set_filename_); |
1410 DVLOG(1) << "SafeBrowsingDatabaseNew read prefix set in " | |
1411 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | |
1412 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); | 1391 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); |
1413 | 1392 |
1414 if (!browse_prefix_set_.get()) | 1393 if (!browse_prefix_set_.get()) |
1415 RecordFailure(FAILURE_BROWSE_PREFIX_SET_READ); | 1394 RecordFailure(FAILURE_BROWSE_PREFIX_SET_READ); |
1416 } | 1395 } |
1417 | 1396 |
1418 bool SafeBrowsingDatabaseNew::Delete() { | 1397 bool SafeBrowsingDatabaseNew::Delete() { |
1419 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1398 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1420 | 1399 |
1421 const bool r1 = browse_store_->Delete(); | 1400 const bool r1 = browse_store_->Delete(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1470 | 1449 |
1471 void SafeBrowsingDatabaseNew::WritePrefixSet() { | 1450 void SafeBrowsingDatabaseNew::WritePrefixSet() { |
1472 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1451 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1473 | 1452 |
1474 if (!browse_prefix_set_.get()) | 1453 if (!browse_prefix_set_.get()) |
1475 return; | 1454 return; |
1476 | 1455 |
1477 const base::TimeTicks before = base::TimeTicks::Now(); | 1456 const base::TimeTicks before = base::TimeTicks::Now(); |
1478 const bool write_ok = browse_prefix_set_->WriteFile( | 1457 const bool write_ok = browse_prefix_set_->WriteFile( |
1479 browse_prefix_set_filename_); | 1458 browse_prefix_set_filename_); |
1480 DVLOG(1) << "SafeBrowsingDatabaseNew wrote prefix set in " | |
1481 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | |
1482 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); | 1459 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); |
1483 | 1460 |
1484 if (!write_ok) | 1461 if (!write_ok) |
1485 RecordFailure(FAILURE_BROWSE_PREFIX_SET_WRITE); | 1462 RecordFailure(FAILURE_BROWSE_PREFIX_SET_WRITE); |
1486 | 1463 |
1487 #if defined(OS_MACOSX) | 1464 #if defined(OS_MACOSX) |
1488 base::mac::SetFileBackupExclusion(browse_prefix_set_filename_); | 1465 base::mac::SetFileBackupExclusion(browse_prefix_set_filename_); |
1489 #endif | 1466 #endif |
1490 } | 1467 } |
1491 | 1468 |
(...skipping 29 matching lines...) Expand all Loading... | |
1521 base::AutoLock locked(lookup_lock_); | 1498 base::AutoLock locked(lookup_lock_); |
1522 whitelist->second = false; | 1499 whitelist->second = false; |
1523 whitelist->first.swap(new_whitelist); | 1500 whitelist->first.swap(new_whitelist); |
1524 } | 1501 } |
1525 } | 1502 } |
1526 | 1503 |
1527 void SafeBrowsingDatabaseNew::LoadIpBlacklist( | 1504 void SafeBrowsingDatabaseNew::LoadIpBlacklist( |
1528 const std::vector<SBAddFullHash>& full_hashes) { | 1505 const std::vector<SBAddFullHash>& full_hashes) { |
1529 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1506 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1530 IPBlacklist new_blacklist; | 1507 IPBlacklist new_blacklist; |
1531 DVLOG(2) << "Writing IP blacklist of size: " << full_hashes.size(); | |
1532 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); | 1508 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); |
1533 it != full_hashes.end(); | 1509 it != full_hashes.end(); |
1534 ++it) { | 1510 ++it) { |
1535 const char* full_hash = it->full_hash.full_hash; | 1511 const char* full_hash = it->full_hash.full_hash; |
1536 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); | 1512 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); |
1537 // The format of the IP blacklist is: | 1513 // The format of the IP blacklist is: |
1538 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. | 1514 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. |
1539 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); | 1515 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); |
1540 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); | 1516 size_t prefix_size = static_cast<uint8>(full_hash[base::kSHA1Length]); |
1541 if (prefix_size > kMaxIpPrefixSize || prefix_size < kMinIpPrefixSize) { | 1517 if (prefix_size > kMaxIpPrefixSize || prefix_size < kMinIpPrefixSize) { |
1542 DVLOG(2) << "Invalid IP prefix size in IP blacklist: " << prefix_size; | |
1543 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_INVALID); | 1518 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_INVALID); |
1544 new_blacklist.clear(); // Load empty blacklist. | 1519 new_blacklist.clear(); // Load empty blacklist. |
1545 break; | 1520 break; |
1546 } | 1521 } |
1547 | 1522 |
1548 // We precompute the mask for the given subnet size to speed up lookups. | 1523 // We precompute the mask for the given subnet size to speed up lookups. |
1549 // Basically we need to create a 16B long string which has the highest | 1524 // Basically we need to create a 16B long string which has the highest |
1550 // |size| bits sets to one. | 1525 // |size| bits sets to one. |
1551 std::string mask(net::kIPv6AddressSize, '\0'); | 1526 std::string mask(net::kIPv6AddressSize, '\0'); |
1552 mask.replace(0, prefix_size / 8, prefix_size / 8, '\xFF'); | 1527 mask.replace(0, prefix_size / 8, prefix_size / 8, '\xFF'); |
1553 if ((prefix_size % 8) != 0) { | 1528 if ((prefix_size % 8) != 0) { |
1554 mask[prefix_size / 8] = 0xFF << (8 - (prefix_size % 8)); | 1529 mask[prefix_size / 8] = 0xFF << (8 - (prefix_size % 8)); |
1555 } | 1530 } |
1556 DVLOG(2) << "Inserting malicious IP: " | 1531 DVLOG(2) << "Inserting malicious IP: " |
1557 << " raw:" << base::HexEncode(full_hash, crypto::kSHA256Length) | 1532 << " raw:" << base::HexEncode(full_hash, crypto::kSHA256Length) |
1558 << " mask:" << base::HexEncode(mask.data(), mask.size()) | 1533 << " mask:" << base::HexEncode(mask.data(), mask.size()) |
1559 << " prefix_size:" << prefix_size | 1534 << " prefix_size:" << prefix_size |
1560 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), | 1535 << " hashed_ip:" << base::HexEncode(hashed_ip_prefix.data(), |
Scott Hess - ex-Googler
2014/06/18 00:08:41
Likewise this one.
| |
1561 hashed_ip_prefix.size()); | 1536 hashed_ip_prefix.size()); |
1562 new_blacklist[mask].insert(hashed_ip_prefix); | 1537 new_blacklist[mask].insert(hashed_ip_prefix); |
1563 } | 1538 } |
1564 | 1539 |
1565 base::AutoLock locked(lookup_lock_); | 1540 base::AutoLock locked(lookup_lock_); |
1566 ip_blacklist_.swap(new_blacklist); | 1541 ip_blacklist_.swap(new_blacklist); |
1567 } | 1542 } |
1568 | 1543 |
1569 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { | 1544 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
1570 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1545 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
1571 std::vector<SBFullHash> full_hashes; | 1546 std::vector<SBFullHash> full_hashes; |
1572 full_hashes.push_back(malware_kill_switch); | 1547 full_hashes.push_back(malware_kill_switch); |
1573 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1548 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
1574 } | 1549 } |
1575 | 1550 |
1576 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { | 1551 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { |
1577 return csd_whitelist_.second; | 1552 return csd_whitelist_.second; |
1578 } | 1553 } |
OLD | NEW |