| 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 |