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

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

Issue 781613002: Make SafeBrowsingDatabase's PrefixSets only updatable by swapping a new one in. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a2_threadchecks
Patch Set: rebase off of CL 744183002 Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_database.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_database.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698