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

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: 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
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 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 // This method is theoretically thread-safe but document that it is currently 689 // This method is theoretically thread-safe but document that it is currently
690 // only expected to be called on the IO thread. 690 // only expected to be called on the IO thread.
691 DCHECK_CURRENTLY_ON(BrowserThread::IO); 691 DCHECK_CURRENTLY_ON(BrowserThread::IO);
692 692
693 return PrefixSetContainsUrl( 693 return PrefixSetContainsUrl(
694 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); 694 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits);
695 } 695 }
696 696
697 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( 697 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl(
698 const GURL& url, 698 const GURL& url,
699 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, 699 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter,
700 std::vector<SBPrefix>* prefix_hits, 700 std::vector<SBPrefix>* prefix_hits,
701 std::vector<SBFullHashResult>* cache_hits) { 701 std::vector<SBFullHashResult>* cache_hits) {
702 // This method is theoretically thread-safe but document that it is currently 702 // This method is theoretically thread-safe but document that it is currently
703 // only expected to be called on the IO thread. 703 // only expected to be called on the IO thread.
704 DCHECK_CURRENTLY_ON(BrowserThread::IO); 704 DCHECK_CURRENTLY_ON(BrowserThread::IO);
705 705
706 // Clear the results first. 706 // Clear the results first.
707 prefix_hits->clear(); 707 prefix_hits->clear();
708 cache_hits->clear(); 708 cache_hits->clear();
709 709
710 std::vector<SBFullHash> full_hashes; 710 std::vector<SBFullHash> full_hashes;
711 UrlToFullHashes(url, false, &full_hashes); 711 UrlToFullHashes(url, false, &full_hashes);
712 if (full_hashes.empty()) 712 if (full_hashes.empty())
713 return false; 713 return false;
714 714
715 return PrefixSetContainsUrlHashes( 715 return PrefixSetContainsUrlHashes(
716 full_hashes, prefix_set_getter, prefix_hits, cache_hits); 716 full_hashes, prefix_set_getter, prefix_hits, cache_hits);
717 } 717 }
718 718
719 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting( 719 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting(
720 const std::vector<SBFullHash>& full_hashes, 720 const std::vector<SBFullHash>& full_hashes,
721 std::vector<SBPrefix>* prefix_hits, 721 std::vector<SBPrefix>* prefix_hits,
722 std::vector<SBFullHashResult>* cache_hits) { 722 std::vector<SBFullHashResult>* cache_hits) {
723 return PrefixSetContainsUrlHashes( 723 return PrefixSetContainsUrlHashes(
724 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits); 724 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits);
725 } 725 }
726 726
727 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( 727 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes(
728 const std::vector<SBFullHash>& full_hashes, 728 const std::vector<SBFullHash>& full_hashes,
729 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, 729 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter,
730 std::vector<SBPrefix>* prefix_hits, 730 std::vector<SBPrefix>* prefix_hits,
731 std::vector<SBFullHashResult>* cache_hits) { 731 std::vector<SBFullHashResult>* cache_hits) {
732 // This method is theoretically thread-safe but document that it is currently 732 // This method is theoretically thread-safe but document that it is currently
733 // only expected to be called on the IO thread. 733 // only expected to be called on the IO thread.
734 DCHECK_CURRENTLY_ON(BrowserThread::IO); 734 DCHECK_CURRENTLY_ON(BrowserThread::IO);
735 735
736 // Used to determine cache expiration. 736 // Used to determine cache expiration.
737 const base::Time now = base::Time::Now(); 737 const base::Time now = base::Time::Now();
738 738
739 base::AutoLock locked(lookup_lock_); 739 base::AutoLock locked(lookup_lock_);
740 740
741 // |prefix_set| is empty until it is either read from disk, or the first 741 // |prefix_set| is empty until it is either read from disk, or the first
742 // update populates it. Bail out without a hit if not yet available. 742 // update populates it. Bail out without a hit if not yet available.
743 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence 743 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence
744 // why it is passed as a parameter rather than passing the |prefix_set| 744 // why it is passed as a parameter rather than passing the |prefix_set|
745 // directly. 745 // directly.
746 safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get(); 746 const safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get();
747 if (!prefix_set) 747 if (!prefix_set)
748 return false; 748 return false;
749 749
750 for (size_t i = 0; i < full_hashes.size(); ++i) { 750 for (size_t i = 0; i < full_hashes.size(); ++i) {
751 if (!GetCachedFullHash( 751 if (!GetCachedFullHash(
752 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) { 752 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) {
753 // No valid cached result, check the database. 753 // No valid cached result, check the database.
754 if (prefix_set->Exists(full_hashes[i])) 754 if (prefix_set->Exists(full_hashes[i]))
755 prefix_hits->push_back(full_hashes[i].prefix); 755 prefix_hits->push_back(full_hashes[i].prefix);
756 } 756 }
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 #if defined(OS_MACOSX) 1323 #if defined(OS_MACOSX)
1324 base::mac::SetFileBackupExclusion(store_filename); 1324 base::mac::SetFileBackupExclusion(store_filename);
1325 #endif 1325 #endif
1326 1326
1327 return GetFileSizeOrZero(store_filename); 1327 return GetFileSizeOrZero(store_filename);
1328 } 1328 }
1329 1329
1330 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( 1330 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore(
1331 const base::FilePath& db_filename, 1331 const base::FilePath& db_filename,
1332 SafeBrowsingStore* url_store, 1332 SafeBrowsingStore* url_store,
1333 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, 1333 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set,
1334 FailureType finish_failure_type, 1334 FailureType finish_failure_type,
1335 FailureType write_failure_type) { 1335 FailureType write_failure_type) {
1336 DCHECK(thread_checker_.CalledOnValidThread()); 1336 DCHECK(thread_checker_.CalledOnValidThread());
1337 1337
1338 // Measure the amount of IO during the filter build. 1338 // Measure the amount of IO during the filter build.
1339 base::IoCounters io_before, io_after; 1339 base::IoCounters io_before, io_after;
1340 base::ProcessHandle handle = base::GetCurrentProcessHandle(); 1340 base::ProcessHandle handle = base::GetCurrentProcessHandle();
1341 scoped_ptr<base::ProcessMetrics> metric( 1341 scoped_ptr<base::ProcessMetrics> metric(
1342 #if !defined(OS_MACOSX) 1342 #if !defined(OS_MACOSX)
1343 base::ProcessMetrics::CreateProcessMetrics(handle) 1343 base::ProcessMetrics::CreateProcessMetrics(handle)
(...skipping 18 matching lines...) Expand all
1362 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { 1362 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) {
1363 RecordFailure(finish_failure_type); 1363 RecordFailure(finish_failure_type);
1364 return; 1364 return;
1365 } 1365 }
1366 1366
1367 std::vector<SBFullHash> full_hash_results; 1367 std::vector<SBFullHash> full_hash_results;
1368 for (size_t i = 0; i < add_full_hashes.size(); ++i) { 1368 for (size_t i = 0; i < add_full_hashes.size(); ++i) {
1369 full_hash_results.push_back(add_full_hashes[i].full_hash); 1369 full_hash_results.push_back(add_full_hashes[i].full_hash);
1370 } 1370 }
1371 1371
1372 scoped_ptr<safe_browsing::PrefixSet> new_prefix_set( 1372 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set(
1373 builder.GetPrefixSet(full_hash_results)); 1373 builder.GetPrefixSet(full_hash_results));
1374 1374
1375 // Swap in the newly built filter. 1375 // Swap in the newly built filter.
1376 { 1376 {
1377 base::AutoLock locked(lookup_lock_); 1377 base::AutoLock locked(lookup_lock_);
1378 prefix_set->swap(new_prefix_set); 1378 prefix_set->swap(new_prefix_set);
1379 } 1379 }
1380 1380
1381 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); 1381 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before);
1382 1382
1383 // Persist the prefix set to disk. Note: there is no need to lock since the 1383 // Persist the prefix set to disk. Note: there is no need to lock since the
1384 // only write to |*prefix_set| is on this thread (in the swap() above). 1384 // only write to |*prefix_set| is on this thread (in the swap() above).
1385 // TODO(gab): Strengthen this requirement by design (const pointers) rather
1386 // than assumptions.
1387 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); 1385 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type);
1388 1386
1389 // Gather statistics. 1387 // Gather statistics.
1390 if (got_counters && metric->GetIOCounters(&io_after)) { 1388 if (got_counters && metric->GetIOCounters(&io_after)) {
1391 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", 1389 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes",
1392 static_cast<int>(io_after.ReadTransferCount - 1390 static_cast<int>(io_after.ReadTransferCount -
1393 io_before.ReadTransferCount) / 1024); 1391 io_before.ReadTransferCount) / 1024);
1394 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", 1392 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes",
1395 static_cast<int>(io_after.WriteTransferCount - 1393 static_cast<int>(io_after.WriteTransferCount -
1396 io_before.WriteTransferCount) / 1024); 1394 io_before.WriteTransferCount) / 1024);
(...skipping 18 matching lines...) Expand all
1415 DCHECK(thread_checker_.CalledOnValidThread()); 1413 DCHECK(thread_checker_.CalledOnValidThread());
1416 1414
1417 safe_browsing::PrefixSetBuilder builder; 1415 safe_browsing::PrefixSetBuilder builder;
1418 std::vector<SBAddFullHash> add_full_hashes_result; 1416 std::vector<SBAddFullHash> add_full_hashes_result;
1419 1417
1420 if (!side_effect_free_whitelist_store_->FinishUpdate( 1418 if (!side_effect_free_whitelist_store_->FinishUpdate(
1421 &builder, &add_full_hashes_result)) { 1419 &builder, &add_full_hashes_result)) {
1422 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); 1420 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH);
1423 return; 1421 return;
1424 } 1422 }
1425 scoped_ptr<safe_browsing::PrefixSet> 1423 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set(
1426 prefix_set(builder.GetPrefixSetNoHashes()); 1424 builder.GetPrefixSetNoHashes());
1427 1425
1428 // Swap in the newly built prefix set. 1426 // Swap in the newly built prefix set.
1429 { 1427 {
1430 base::AutoLock locked(lookup_lock_); 1428 base::AutoLock locked(lookup_lock_);
1431 side_effect_free_whitelist_prefix_set_.swap(prefix_set); 1429 side_effect_free_whitelist_prefix_set_.swap(new_prefix_set);
1432 } 1430 }
1433 1431
1434 const base::FilePath side_effect_free_whitelist_filename = 1432 const base::FilePath side_effect_free_whitelist_filename =
1435 SideEffectFreeWhitelistDBFilename(filename_base_); 1433 SideEffectFreeWhitelistDBFilename(filename_base_);
1436 const base::FilePath side_effect_free_whitelist_prefix_set_filename = 1434 const base::FilePath side_effect_free_whitelist_prefix_set_filename =
1437 PrefixSetForFilename(side_effect_free_whitelist_filename); 1435 PrefixSetForFilename(side_effect_free_whitelist_filename);
1438 const base::TimeTicks before = base::TimeTicks::Now(); 1436 const base::TimeTicks before = base::TimeTicks::Now();
1439 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( 1437 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile(
1440 side_effect_free_whitelist_prefix_set_filename); 1438 side_effect_free_whitelist_prefix_set_filename);
1441 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", 1439 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite",
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 // only happen once. If you are here because you are hitting this after a 1502 // only happen once. If you are here because you are hitting this after a
1505 // restart, then I would be very interested in working with you to figure out 1503 // restart, then I would be very interested in working with you to figure out
1506 // what is happening, since it may affect real users. 1504 // what is happening, since it may affect real users.
1507 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; 1505 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset";
1508 } 1506 }
1509 1507
1510 // TODO(shess): I'm not clear why this code doesn't have any 1508 // TODO(shess): I'm not clear why this code doesn't have any
1511 // real error-handling. 1509 // real error-handling.
1512 void SafeBrowsingDatabaseNew::LoadPrefixSet( 1510 void SafeBrowsingDatabaseNew::LoadPrefixSet(
1513 const base::FilePath& db_filename, 1511 const base::FilePath& db_filename,
1514 scoped_ptr<safe_browsing::PrefixSet>* prefix_set, 1512 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set,
1515 FailureType read_failure_type) { 1513 FailureType read_failure_type) {
1516 DCHECK(thread_checker_.CalledOnValidThread()); 1514 DCHECK(thread_checker_.CalledOnValidThread());
1517 1515
1518 if (!prefix_set) 1516 if (!prefix_set)
1519 return; 1517 return;
1520 1518
1521 DCHECK(!filename_base_.empty()); 1519 DCHECK(!filename_base_.empty());
1522 1520
1523 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); 1521 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1524 1522
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 const bool r11 = 1613 const bool r11 =
1616 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false); 1614 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false);
1617 if (!r11) 1615 if (!r11)
1618 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); 1616 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE);
1619 1617
1620 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11; 1618 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11;
1621 } 1619 }
1622 1620
1623 void SafeBrowsingDatabaseNew::WritePrefixSet( 1621 void SafeBrowsingDatabaseNew::WritePrefixSet(
1624 const base::FilePath& db_filename, 1622 const base::FilePath& db_filename,
1625 safe_browsing::PrefixSet* prefix_set, 1623 const safe_browsing::PrefixSet* prefix_set,
1626 FailureType write_failure_type) { 1624 FailureType write_failure_type) {
1627 DCHECK(thread_checker_.CalledOnValidThread()); 1625 DCHECK(thread_checker_.CalledOnValidThread());
1628 1626
1629 if (!prefix_set) 1627 if (!prefix_set)
1630 return; 1628 return;
1631 1629
1632 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); 1630 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1633 1631
1634 const base::TimeTicks before = base::TimeTicks::Now(); 1632 const base::TimeTicks before = base::TimeTicks::Now();
1635 const bool write_ok = prefix_set->WriteFile(prefix_set_filename); 1633 const bool write_ok = prefix_set->WriteFile(prefix_set_filename);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 1734 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
1737 } 1735 }
1738 1736
1739 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { 1737 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() {
1740 // This method is theoretically thread-safe but document that it is currently 1738 // This method is theoretically thread-safe but document that it is currently
1741 // only expected to be called on the IO thread. 1739 // only expected to be called on the IO thread.
1742 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1740 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1743 1741
1744 return csd_whitelist_.second; 1742 return csd_whitelist_.second;
1745 } 1743 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698