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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 if (extension_blacklist_store_.get()) { | 596 if (extension_blacklist_store_.get()) { |
597 extension_blacklist_store_->Init( | 597 extension_blacklist_store_->Init( |
598 ExtensionBlacklistDBFilename(filename_base_), | 598 ExtensionBlacklistDBFilename(filename_base_), |
599 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 599 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
600 base::Unretained(this))); | 600 base::Unretained(this))); |
601 } | 601 } |
602 | 602 |
603 if (side_effect_free_whitelist_store_.get()) { | 603 if (side_effect_free_whitelist_store_.get()) { |
604 const base::FilePath side_effect_free_whitelist_filename = | 604 const base::FilePath side_effect_free_whitelist_filename = |
605 SideEffectFreeWhitelistDBFilename(filename_base_); | 605 SideEffectFreeWhitelistDBFilename(filename_base_); |
606 const base::FilePath side_effect_free_whitelist_prefix_set_filename = | |
607 PrefixSetForFilename(side_effect_free_whitelist_filename); | |
608 side_effect_free_whitelist_store_->Init( | 606 side_effect_free_whitelist_store_->Init( |
609 side_effect_free_whitelist_filename, | 607 side_effect_free_whitelist_filename, |
610 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, | 608 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, |
611 base::Unretained(this))); | 609 base::Unretained(this))); |
612 | 610 |
613 // Only use the prefix set if database is present and non-empty. | 611 LoadPrefixSet(side_effect_free_whitelist_filename, |
614 if (GetFileSizeOrZero(side_effect_free_whitelist_filename)) { | 612 &side_effect_free_whitelist_prefix_set_, |
615 const base::TimeTicks before = base::TimeTicks::Now(); | 613 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ); |
616 side_effect_free_whitelist_prefix_set_ = | |
617 safe_browsing::PrefixSet::LoadFile( | |
618 side_effect_free_whitelist_prefix_set_filename); | |
619 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreeWhitelistPrefixSetLoad", | |
620 base::TimeTicks::Now() - before); | |
621 if (!side_effect_free_whitelist_prefix_set_.get()) | |
622 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_READ); | |
623 } | |
624 } else { | 614 } else { |
625 // Delete any files of the side-effect free sidelist that may be around | 615 // Delete any files of the side-effect free sidelist that may be around |
626 // from when it was previously enabled. | 616 // from when it was previously enabled. |
627 SafeBrowsingStoreFile::DeleteStore( | 617 SafeBrowsingStoreFile::DeleteStore( |
628 SideEffectFreeWhitelistDBFilename(filename_base_)); | 618 SideEffectFreeWhitelistDBFilename(filename_base_)); |
629 base::DeleteFile( | 619 base::DeleteFile( |
630 PrefixSetForFilename(SideEffectFreeWhitelistDBFilename(filename_base_)), | 620 PrefixSetForFilename(SideEffectFreeWhitelistDBFilename(filename_base_)), |
631 false); | 621 false); |
632 } | 622 } |
633 | 623 |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 download_store_.get(), | 1195 download_store_.get(), |
1206 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); | 1196 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); |
1207 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes", | 1197 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes", |
1208 static_cast<int>(size_bytes / 1024)); | 1198 static_cast<int>(size_bytes / 1024)); |
1209 } | 1199 } |
1210 | 1200 |
1211 UpdatePrefixSetUrlStore(BrowseDBFilename(filename_base_), | 1201 UpdatePrefixSetUrlStore(BrowseDBFilename(filename_base_), |
1212 browse_store_.get(), | 1202 browse_store_.get(), |
1213 &browse_prefix_set_, | 1203 &browse_prefix_set_, |
1214 FAILURE_BROWSE_DATABASE_UPDATE_FINISH, | 1204 FAILURE_BROWSE_DATABASE_UPDATE_FINISH, |
1215 FAILURE_BROWSE_PREFIX_SET_WRITE); | 1205 FAILURE_BROWSE_PREFIX_SET_WRITE, |
| 1206 true); |
1216 | 1207 |
1217 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_), | 1208 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_), |
1218 csd_whitelist_store_.get(), | 1209 csd_whitelist_store_.get(), |
1219 &csd_whitelist_); | 1210 &csd_whitelist_); |
1220 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_), | 1211 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_), |
1221 download_whitelist_store_.get(), | 1212 download_whitelist_store_.get(), |
1222 &download_whitelist_); | 1213 &download_whitelist_); |
1223 | 1214 |
1224 if (extension_blacklist_store_) { | 1215 if (extension_blacklist_store_) { |
1225 int64 size_bytes = UpdateHashPrefixStore( | 1216 int64 size_bytes = UpdateHashPrefixStore( |
1226 ExtensionBlacklistDBFilename(filename_base_), | 1217 ExtensionBlacklistDBFilename(filename_base_), |
1227 extension_blacklist_store_.get(), | 1218 extension_blacklist_store_.get(), |
1228 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH); | 1219 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH); |
1229 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes", | 1220 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes", |
1230 static_cast<int>(size_bytes / 1024)); | 1221 static_cast<int>(size_bytes / 1024)); |
1231 } | 1222 } |
1232 | 1223 |
1233 if (side_effect_free_whitelist_store_) | 1224 if (side_effect_free_whitelist_store_) { |
1234 UpdateSideEffectFreeWhitelistStore(); | 1225 UpdatePrefixSetUrlStore(SideEffectFreeWhitelistDBFilename(filename_base_), |
| 1226 side_effect_free_whitelist_store_.get(), |
| 1227 &side_effect_free_whitelist_prefix_set_, |
| 1228 FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH, |
| 1229 FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE, |
| 1230 false); |
| 1231 } |
1235 | 1232 |
1236 if (ip_blacklist_store_) | 1233 if (ip_blacklist_store_) |
1237 UpdateIpBlacklistStore(); | 1234 UpdateIpBlacklistStore(); |
1238 | 1235 |
1239 if (unwanted_software_store_) { | 1236 if (unwanted_software_store_) { |
1240 UpdatePrefixSetUrlStore(UnwantedSoftwareDBFilename(filename_base_), | 1237 UpdatePrefixSetUrlStore(UnwantedSoftwareDBFilename(filename_base_), |
1241 unwanted_software_store_.get(), | 1238 unwanted_software_store_.get(), |
1242 &unwanted_software_prefix_set_, | 1239 &unwanted_software_prefix_set_, |
1243 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, | 1240 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, |
1244 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE); | 1241 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE, |
| 1242 true); |
1245 } | 1243 } |
1246 } | 1244 } |
1247 | 1245 |
1248 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( | 1246 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( |
1249 const base::FilePath& store_filename, | 1247 const base::FilePath& store_filename, |
1250 SafeBrowsingStore* store, | 1248 SafeBrowsingStore* store, |
1251 SBWhitelist* whitelist) { | 1249 SBWhitelist* whitelist) { |
1252 DCHECK(thread_checker_.CalledOnValidThread()); | 1250 DCHECK(thread_checker_.CalledOnValidThread()); |
1253 | 1251 |
1254 if (!store) | 1252 if (!store) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 #endif | 1288 #endif |
1291 | 1289 |
1292 return GetFileSizeOrZero(store_filename); | 1290 return GetFileSizeOrZero(store_filename); |
1293 } | 1291 } |
1294 | 1292 |
1295 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( | 1293 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( |
1296 const base::FilePath& db_filename, | 1294 const base::FilePath& db_filename, |
1297 SafeBrowsingStore* url_store, | 1295 SafeBrowsingStore* url_store, |
1298 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, | 1296 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, |
1299 FailureType finish_failure_type, | 1297 FailureType finish_failure_type, |
1300 FailureType write_failure_type) { | 1298 FailureType write_failure_type, |
| 1299 bool store_full_hashes_in_prefix_set) { |
1301 DCHECK(thread_checker_.CalledOnValidThread()); | 1300 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1301 DCHECK(url_store); |
| 1302 DCHECK(prefix_set); |
1302 | 1303 |
1303 // Measure the amount of IO during the filter build. | 1304 // Measure the amount of IO during the filter build. |
1304 base::IoCounters io_before, io_after; | 1305 base::IoCounters io_before, io_after; |
1305 base::ProcessHandle handle = base::GetCurrentProcessHandle(); | 1306 base::ProcessHandle handle = base::GetCurrentProcessHandle(); |
1306 scoped_ptr<base::ProcessMetrics> metric( | 1307 scoped_ptr<base::ProcessMetrics> metric( |
1307 #if !defined(OS_MACOSX) | 1308 #if !defined(OS_MACOSX) |
1308 base::ProcessMetrics::CreateProcessMetrics(handle) | 1309 base::ProcessMetrics::CreateProcessMetrics(handle) |
1309 #else | 1310 #else |
1310 // Getting stats only for the current process is enough, so NULL is fine. | 1311 // Getting stats only for the current process is enough, so NULL is fine. |
1311 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) | 1312 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) |
(...skipping 10 matching lines...) Expand all Loading... |
1322 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the | 1323 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the |
1323 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use | 1324 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use |
1324 // the SBFullHash portion. It would need an accessor on PrefixSet. | 1325 // the SBFullHash portion. It would need an accessor on PrefixSet. |
1325 safe_browsing::PrefixSetBuilder builder; | 1326 safe_browsing::PrefixSetBuilder builder; |
1326 std::vector<SBAddFullHash> add_full_hashes; | 1327 std::vector<SBAddFullHash> add_full_hashes; |
1327 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { | 1328 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) { |
1328 RecordFailure(finish_failure_type); | 1329 RecordFailure(finish_failure_type); |
1329 return; | 1330 return; |
1330 } | 1331 } |
1331 | 1332 |
1332 std::vector<SBFullHash> full_hash_results; | 1333 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set; |
1333 for (size_t i = 0; i < add_full_hashes.size(); ++i) { | 1334 if (store_full_hashes_in_prefix_set) { |
1334 full_hash_results.push_back(add_full_hashes[i].full_hash); | 1335 std::vector<SBFullHash> full_hash_results; |
| 1336 for (size_t i = 0; i < add_full_hashes.size(); ++i) { |
| 1337 full_hash_results.push_back(add_full_hashes[i].full_hash); |
| 1338 } |
| 1339 |
| 1340 new_prefix_set = builder.GetPrefixSet(full_hash_results); |
| 1341 } else { |
| 1342 // TODO(gab): Ensure that stores which do not want full hashes just don't |
| 1343 // have full hashes in the first place and remove |
| 1344 // |store_full_hashes_in_prefix_set| and the code specialization incurred |
| 1345 // here. |
| 1346 new_prefix_set = builder.GetPrefixSetNoHashes(); |
1335 } | 1347 } |
1336 | 1348 |
1337 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set( | |
1338 builder.GetPrefixSet(full_hash_results)); | |
1339 | |
1340 // Swap in the newly built filter. | 1349 // Swap in the newly built filter. |
1341 { | 1350 { |
1342 base::AutoLock locked(lookup_lock_); | 1351 base::AutoLock locked(lookup_lock_); |
1343 prefix_set->swap(new_prefix_set); | 1352 prefix_set->swap(new_prefix_set); |
1344 } | 1353 } |
1345 | 1354 |
1346 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); | 1355 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); |
1347 | 1356 |
1348 // Persist the prefix set to disk. Note: there is no need to lock since the | 1357 // Persist the prefix set to disk. Note: there is no need to lock since the |
1349 // only write to |*prefix_set| is on this thread (in the swap() above). | 1358 // only write to |*prefix_set| is on this thread (in the swap() above). |
1350 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); | 1359 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type); |
1351 | 1360 |
1352 // Gather statistics. | 1361 // Gather statistics. |
1353 if (got_counters && metric->GetIOCounters(&io_after)) { | 1362 if (got_counters && metric->GetIOCounters(&io_after)) { |
1354 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", | 1363 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", |
1355 static_cast<int>(io_after.ReadTransferCount - | 1364 static_cast<int>(io_after.ReadTransferCount - |
1356 io_before.ReadTransferCount) / 1024); | 1365 io_before.ReadTransferCount) / 1024); |
1357 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", | 1366 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", |
1358 static_cast<int>(io_after.WriteTransferCount - | 1367 static_cast<int>(io_after.WriteTransferCount - |
1359 io_before.WriteTransferCount) / 1024); | 1368 io_before.WriteTransferCount) / 1024); |
1360 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations", | 1369 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations", |
1361 static_cast<int>(io_after.ReadOperationCount - | 1370 static_cast<int>(io_after.ReadOperationCount - |
1362 io_before.ReadOperationCount)); | 1371 io_before.ReadOperationCount)); |
1363 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteOperations", | 1372 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteOperations", |
1364 static_cast<int>(io_after.WriteOperationCount - | 1373 static_cast<int>(io_after.WriteOperationCount - |
1365 io_before.WriteOperationCount)); | 1374 io_before.WriteOperationCount)); |
1366 } | 1375 } |
1367 | 1376 |
1368 const int64 file_size = GetFileSizeOrZero(db_filename); | 1377 const int64 file_size = GetFileSizeOrZero(db_filename); |
1369 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", | 1378 UMA_HISTOGRAM_COUNTS("SB2.DatabaseKilobytes", |
1370 static_cast<int>(file_size / 1024)); | 1379 static_cast<int>(file_size / 1024)); |
1371 | 1380 |
1372 #if defined(OS_MACOSX) | 1381 #if defined(OS_MACOSX) |
1373 base::mac::SetFileBackupExclusion(db_filename); | 1382 base::mac::SetFileBackupExclusion(db_filename); |
1374 #endif | 1383 #endif |
1375 } | 1384 } |
1376 | 1385 |
1377 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { | |
1378 DCHECK(thread_checker_.CalledOnValidThread()); | |
1379 | |
1380 safe_browsing::PrefixSetBuilder builder; | |
1381 std::vector<SBAddFullHash> add_full_hashes_result; | |
1382 | |
1383 if (!side_effect_free_whitelist_store_->FinishUpdate( | |
1384 &builder, &add_full_hashes_result)) { | |
1385 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); | |
1386 return; | |
1387 } | |
1388 scoped_ptr<const safe_browsing::PrefixSet> new_prefix_set( | |
1389 builder.GetPrefixSetNoHashes()); | |
1390 | |
1391 // Swap in the newly built prefix set. | |
1392 { | |
1393 base::AutoLock locked(lookup_lock_); | |
1394 side_effect_free_whitelist_prefix_set_.swap(new_prefix_set); | |
1395 } | |
1396 | |
1397 const base::FilePath side_effect_free_whitelist_filename = | |
1398 SideEffectFreeWhitelistDBFilename(filename_base_); | |
1399 const base::FilePath side_effect_free_whitelist_prefix_set_filename = | |
1400 PrefixSetForFilename(side_effect_free_whitelist_filename); | |
1401 const base::TimeTicks before = base::TimeTicks::Now(); | |
1402 const bool write_ok = side_effect_free_whitelist_prefix_set_->WriteFile( | |
1403 side_effect_free_whitelist_prefix_set_filename); | |
1404 UMA_HISTOGRAM_TIMES("SB2.SideEffectFreePrefixSetWrite", | |
1405 base::TimeTicks::Now() - before); | |
1406 | |
1407 if (!write_ok) | |
1408 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_WRITE); | |
1409 | |
1410 // Gather statistics. | |
1411 int64 file_size = GetFileSizeOrZero( | |
1412 side_effect_free_whitelist_prefix_set_filename); | |
1413 UMA_HISTOGRAM_COUNTS("SB2.SideEffectFreeWhitelistPrefixSetKilobytes", | |
1414 static_cast<int>(file_size / 1024)); | |
1415 file_size = GetFileSizeOrZero(side_effect_free_whitelist_filename); | |
1416 UMA_HISTOGRAM_COUNTS("SB2.SideEffectFreeWhitelistDatabaseKilobytes", | |
1417 static_cast<int>(file_size / 1024)); | |
1418 | |
1419 #if defined(OS_MACOSX) | |
1420 base::mac::SetFileBackupExclusion(side_effect_free_whitelist_filename); | |
1421 base::mac::SetFileBackupExclusion( | |
1422 side_effect_free_whitelist_prefix_set_filename); | |
1423 #endif | |
1424 } | |
1425 | |
1426 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { | 1386 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { |
1427 DCHECK(thread_checker_.CalledOnValidThread()); | 1387 DCHECK(thread_checker_.CalledOnValidThread()); |
1428 | 1388 |
1429 // Note: prefixes will not be empty. The current data store implementation | 1389 // Note: prefixes will not be empty. The current data store implementation |
1430 // stores all full-length hashes as both full and prefix hashes. | 1390 // stores all full-length hashes as both full and prefix hashes. |
1431 safe_browsing::PrefixSetBuilder builder; | 1391 safe_browsing::PrefixSetBuilder builder; |
1432 std::vector<SBAddFullHash> full_hashes; | 1392 std::vector<SBAddFullHash> full_hashes; |
1433 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { | 1393 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { |
1434 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); | 1394 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); |
1435 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. | 1395 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1652 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
1693 std::vector<SBFullHash> full_hashes; | 1653 std::vector<SBFullHash> full_hashes; |
1694 full_hashes.push_back(malware_kill_switch); | 1654 full_hashes.push_back(malware_kill_switch); |
1695 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1655 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
1696 } | 1656 } |
1697 | 1657 |
1698 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { | 1658 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { |
1699 base::AutoLock locked(lookup_lock_); | 1659 base::AutoLock locked(lookup_lock_); |
1700 return csd_whitelist_.second; | 1660 return csd_whitelist_.second; |
1701 } | 1661 } |
OLD | NEW |