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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( | 679 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( |
680 const GURL& url, | 680 const GURL& url, |
681 std::vector<SBPrefix>* prefix_hits, | 681 std::vector<SBPrefix>* prefix_hits, |
682 std::vector<SBFullHashResult>* cache_hits) { | 682 std::vector<SBFullHashResult>* cache_hits) { |
683 return PrefixSetContainsUrl( | 683 return PrefixSetContainsUrl( |
684 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); | 684 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); |
685 } | 685 } |
686 | 686 |
687 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( | 687 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( |
688 const GURL& url, | 688 const GURL& url, |
689 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, | 689 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, |
690 std::vector<SBPrefix>* prefix_hits, | 690 std::vector<SBPrefix>* prefix_hits, |
691 std::vector<SBFullHashResult>* cache_hits) { | 691 std::vector<SBFullHashResult>* cache_hits) { |
692 // Clear the results first. | 692 // Clear the results first. |
693 prefix_hits->clear(); | 693 prefix_hits->clear(); |
694 cache_hits->clear(); | 694 cache_hits->clear(); |
695 | 695 |
696 std::vector<SBFullHash> full_hashes; | 696 std::vector<SBFullHash> full_hashes; |
697 UrlToFullHashes(url, false, &full_hashes); | 697 UrlToFullHashes(url, false, &full_hashes); |
698 if (full_hashes.empty()) | 698 if (full_hashes.empty()) |
699 return false; | 699 return false; |
700 | 700 |
701 return PrefixSetContainsUrlHashes( | 701 return PrefixSetContainsUrlHashes( |
702 full_hashes, prefix_set_getter, prefix_hits, cache_hits); | 702 full_hashes, prefix_set_getter, prefix_hits, cache_hits); |
703 } | 703 } |
704 | 704 |
705 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( | 705 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( |
706 const std::vector<SBFullHash>& full_hashes, | 706 const std::vector<SBFullHash>& full_hashes, |
707 std::vector<SBPrefix>* prefix_hits, | 707 std::vector<SBPrefix>* prefix_hits, |
708 std::vector<SBFullHashResult>* cache_hits) { | 708 std::vector<SBFullHashResult>* cache_hits) { |
709 return PrefixSetContainsUrlHashes( | 709 return PrefixSetContainsUrlHashes( |
710 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); | 710 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); |
711 } | 711 } |
712 | 712 |
713 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( | 713 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( |
714 const std::vector<SBFullHash>& full_hashes, | 714 const std::vector<SBFullHash>& full_hashes, |
715 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, | 715 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, |
716 std::vector<SBPrefix>* prefix_hits, | 716 std::vector<SBPrefix>* prefix_hits, |
717 std::vector<SBFullHashResult>* cache_hits) { | 717 std::vector<SBFullHashResult>* cache_hits) { |
718 // Used to determine cache expiration. | 718 // Used to determine cache expiration. |
719 const base::Time now = base::Time::Now(); | 719 const base::Time now = base::Time::Now(); |
720 | 720 |
721 // This function is called on the I/O thread, prevent changes to | 721 // This function is called on the I/O thread, prevent changes to |
722 // filter and caches. | 722 // filter and caches. |
723 base::AutoLock locked(lookup_lock_); | 723 base::AutoLock locked(lookup_lock_); |
724 | 724 |
725 // |prefix_set| is empty until it is either read from disk, or the first | 725 // |prefix_set| is empty until it is either read from disk, or the first |
726 // update populates it. Bail out without a hit if not yet available. | 726 // update populates it. Bail out without a hit if not yet available. |
727 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence | 727 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence |
728 // why it is passed as a parameter rather than passing the |prefix_set| | 728 // why it is passed as a parameter rather than passing the |prefix_set| |
729 // directly. | 729 // directly. |
730 safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); | 730 const safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); |
731 if (!prefix_set) | 731 if (!prefix_set) |
732 return false; | 732 return false; |
733 | 733 |
734 for (size_t i = 0; i < full_hashes.size(); ++i) { | 734 for (size_t i = 0; i < full_hashes.size(); ++i) { |
735 if (!GetCachedFullHash( | 735 if (!GetCachedFullHash( |
736 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) { | 736 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) { |
737 // No valid cached result, check the database. | 737 // No valid cached result, check the database. |
738 if (prefix_set->Exists(full_hashes[i])) | 738 if (prefix_set->Exists(full_hashes[i])) |
739 prefix_hits->push_back(full_hashes[i].prefix); | 739 prefix_hits->push_back(full_hashes[i].prefix); |
740 } | 740 } |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 #if defined(OS_MACOSX) | 1285 #if defined(OS_MACOSX) |
1286 base::mac::SetFileBackupExclusion(store_filename); | 1286 base::mac::SetFileBackupExclusion(store_filename); |
1287 #endif | 1287 #endif |
1288 | 1288 |
1289 return GetFileSizeOrZero(store_filename); | 1289 return GetFileSizeOrZero(store_filename); |
1290 } | 1290 } |
1291 | 1291 |
1292 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( | 1292 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( |
1293 const base::FilePath& db_filename, | 1293 const base::FilePath& db_filename, |
1294 SafeBrowsingStore* url_store, | 1294 SafeBrowsingStore* url_store, |
1295 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, | 1295 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, |
1296 FailureType finish_failure_type, | 1296 FailureType finish_failure_type, |
1297 FailureType write_failure_type) { | 1297 FailureType write_failure_type) { |
1298 // Measure the amount of IO during the filter build. | 1298 // Measure the amount of IO during the filter build. |
1299 base::IoCounters io_before, io_after; | 1299 base::IoCounters io_before, io_after; |
1300 base::ProcessHandle handle = base::GetCurrentProcessHandle(); | 1300 base::ProcessHandle handle = base::GetCurrentProcessHandle(); |
1301 scoped_ptr<base::ProcessMetrics> metric( | 1301 scoped_ptr<base::ProcessMetrics> metric( |
1302 #if !defined(OS_MACOSX) | 1302 #if !defined(OS_MACOSX) |
1303 base::ProcessMetrics::CreateProcessMetrics(handle) | 1303 base::ProcessMetrics::CreateProcessMetrics(handle) |
1304 #else | 1304 #else |
1305 // Getting stats only for the current process is enough, so NULL is fine. | 1305 // Getting stats only for the current process is enough, so NULL is fine. |
(...skipping 16 matching lines...) Expand all Loading... |
1322 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { | 1322 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { |
1323 RecordFailure(finish_failure_type); | 1323 RecordFailure(finish_failure_type); |
1324 return; | 1324 return; |
1325 } | 1325 } |
1326 | 1326 |
1327 std::vector<SBFullHash> full_hash_results; | 1327 std::vector<SBFullHash> full_hash_results; |
1328 for (size_t i = 0; i < add_full_hashes.size(); ++i) { | 1328 for (size_t i = 0; i < add_full_hashes.size(); ++i) { |
1329 full_hash_results.push_back(add_full_hashes[i].full_hash); | 1329 full_hash_results.push_back(add_full_hashes[i].full_hash); |
1330 } | 1330 } |
1331 | 1331 |
1332 scoped_ptr<safe_browsing::PrefixSet> new_prefix_set( | 1332 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set( |
1333 builder.GetPrefixSet(full_hash_results)); | 1333 builder.GetPrefixSet(full_hash_results)); |
1334 | 1334 |
1335 // Swap in the newly built filter. | 1335 // Swap in the newly built filter. |
1336 { | 1336 { |
1337 base::AutoLock locked(lookup_lock_); | 1337 base::AutoLock locked(lookup_lock_); |
1338 prefix_set->swap(new_prefix_set); | 1338 prefix_set->swap(new_prefix_set); |
1339 } | 1339 } |
1340 | 1340 |
1341 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); | 1341 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); |
1342 | 1342 |
1343 // Persist the prefix set to disk. Note: there is no need to lock since the | 1343 // Persist the prefix set to disk. Note: there is no need to lock since the |
1344 // only write to |*prefix_set| is on this thread (in the swap() above). | 1344 // only write to |*prefix_set| is on this thread (in the swap() above). |
1345 // TODO(gab): Strengthen this requirement by design (const pointers) rather | |
1346 // than assumptions. | |
1347 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); | 1345 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); |
1348 | 1346 |
1349 // Gather statistics. | 1347 // Gather statistics. |
1350 if (got_counters && metric->GetIOCounters(&io_after)) { | 1348 if (got_counters && metric->GetIOCounters(&io_after)) { |
1351 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", | 1349 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", |
1352 static_cast<int>(io_after.ReadTransferCount - | 1350 static_cast<int>(io_after.ReadTransferCount - |
1353 io_before.ReadTransferCount) / 1024); | 1351 io_before.ReadTransferCount) / 1024); |
1354 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", | 1352 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", |
1355 static_cast<int>(io_after.WriteTransferCount - | 1353 static_cast<int>(io_after.WriteTransferCount - |
1356 io_before.WriteTransferCount) / 1024); | 1354 io_before.WriteTransferCount) / 1024); |
(...skipping 16 matching lines...) Expand all Loading... |
1373 | 1371 |
1374 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { | 1372 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { |
1375 safe_browsing::PrefixSetBuilder builder; | 1373 safe_browsing::PrefixSetBuilder builder; |
1376 std::vector<SBAddFullHash> add_full_hashes_result; | 1374 std::vector<SBAddFullHash> add_full_hashes_result; |
1377 | 1375 |
1378 if (!side_effect_free_whitelist_store_->FinishUpdate( | 1376 if (!side_effect_free_whitelist_store_->FinishUpdate( |
1379 &builder, &add_full_hashes_result)) { | 1377 &builder, &add_full_hashes_result)) { |
1380 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); | 1378 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); |
1381 return; | 1379 return; |
1382 } | 1380 } |
1383 scoped_ptr<safe_browsing::PrefixSet> | 1381 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set( |
1384 prefix_set(builder.GetPrefixSetNoHashes()); | 1382 builder.GetPrefixSetNoHashes()); |
1385 | 1383 |
1386 // Swap in the newly built prefix set. | 1384 // Swap in the newly built prefix set. |
1387 { | 1385 { |
1388 base::AutoLock locked(lookup_lock_); | 1386 base::AutoLock locked(lookup_lock_); |
1389 side_effect_free_whitelist_prefix_set_.swap(prefix_set); | 1387 side_effect_free_whitelist_prefix_set_.swap(new_prefix_set); |
1390 } | 1388 } |
1391 | 1389 |
1392 const base::FilePath side_effect_free_whitelist_filename = | 1390 const base::FilePath side_effect_free_whitelist_filename = |
1393 SideEffectFreeWhitelistDBFilename(filename_base_); | 1391 SideEffectFreeWhitelistDBFilename(filename_base_); |
1394 const base::FilePath side_effect_free_whitelist_prefix_set_filename = | 1392 const base::FilePath side_effect_free_whitelist_prefix_set_filename = |
1395 PrefixSetForFilename(side_effect_free_whitelist_filename); | 1393 PrefixSetForFilename(side_effect_free_whitelist_filename); |
1396 const base::TimeTicks before = base::TimeTicks::Now(); | 1394 const base::TimeTicks before = base::TimeTicks::Now(); |
1397 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( | 1395 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( |
1398 side_effect_free_whitelist_prefix_set_filename); | 1396 side_effect_free_whitelist_prefix_set_filename); |
1399 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", | 1397 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 // only happen once. If you are here because you are hitting this after a | 1454 // only happen once. If you are here because you are hitting this after a |
1457 // restart, then I would be very interested in working with you to figure out | 1455 // restart, then I would be very interested in working with you to figure out |
1458 // what is happening, since it may affect real users. | 1456 // what is happening, since it may affect real users. |
1459 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; | 1457 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; |
1460 } | 1458 } |
1461 | 1459 |
1462 // TODO(shess): I'm not clear why this code doesn't have any | 1460 // TODO(shess): I'm not clear why this code doesn't have any |
1463 // real error-handling. | 1461 // real error-handling. |
1464 void SafeBrowsingDatabaseNew::LoadPrefixSet( | 1462 void SafeBrowsingDatabaseNew::LoadPrefixSet( |
1465 const base::FilePath& db_filename, | 1463 const base::FilePath& db_filename, |
1466 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, | 1464 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, |
1467 FailureType read_failure_type) { | 1465 FailureType read_failure_type) { |
1468 if (!prefix_set) | 1466 if (!prefix_set) |
1469 return; | 1467 return; |
1470 | 1468 |
1471 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1469 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1472 DCHECK(!filename_base_.empty()); | 1470 DCHECK(!filename_base_.empty()); |
1473 | 1471 |
1474 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); | 1472 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); |
1475 | 1473 |
1476 // Only use the prefix set if database is present and non-empty. | 1474 // Only use the prefix set if database is present and non-empty. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 const bool r11 = | 1564 const bool r11 = |
1567 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false); | 1565 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false); |
1568 if (!r11) | 1566 if (!r11) |
1569 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); | 1567 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); |
1570 | 1568 |
1571 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; | 1569 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; |
1572 } | 1570 } |
1573 | 1571 |
1574 void SafeBrowsingDatabaseNew::WritePrefixSet( | 1572 void SafeBrowsingDatabaseNew::WritePrefixSet( |
1575 const base::FilePath& db_filename, | 1573 const base::FilePath& db_filename, |
1576 safe_browsing::PrefixSet* prefix_set, | 1574 const safe_browsing::PrefixSet* prefix_set, |
1577 FailureType write_failure_type) { | 1575 FailureType write_failure_type) { |
1578 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); | 1576 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
1579 | 1577 |
1580 if (!prefix_set) | 1578 if (!prefix_set) |
1581 return; | 1579 return; |
1582 | 1580 |
1583 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); | 1581 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); |
1584 | 1582 |
1585 const base::TimeTicks before = base::TimeTicks::Now(); | 1583 const base::TimeTicks before = base::TimeTicks::Now(); |
1586 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); | 1584 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { | 1674 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
1677 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1675 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
1678 std::vector<SBFullHash> full_hashes; | 1676 std::vector<SBFullHash> full_hashes; |
1679 full_hashes.push_back(malware_kill_switch); | 1677 full_hashes.push_back(malware_kill_switch); |
1680 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1678 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
1681 } | 1679 } |
1682 | 1680 |
1683 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { | 1681 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { |
1684 return csd_whitelist_.second; | 1682 return csd_whitelist_.second; |
1685 } | 1683 } |
OLD | NEW |