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/local_database_manager.h" | 5 #include "chrome/browser/safe_browsing/local_database_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/debug/leak_tracker.h" | 14 #include "base/debug/leak_tracker.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/memory/ptr_util.h" |
16 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
18 #include "base/stl_util.h" | |
19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
20 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
21 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/chrome_notification_types.h" | 22 #include "chrome/browser/chrome_notification_types.h" |
23 #include "chrome/browser/prerender/prerender_field_trial.h" | 23 #include "chrome/browser/prerender/prerender_field_trial.h" |
24 #include "chrome/browser/profiles/profile_manager.h" | 24 #include "chrome/browser/profiles/profile_manager.h" |
25 #include "chrome/browser/safe_browsing/client_side_detection_service.h" | 25 #include "chrome/browser/safe_browsing/client_side_detection_service.h" |
26 #include "chrome/browser/safe_browsing/download_protection_service.h" | 26 #include "chrome/browser/safe_browsing/download_protection_service.h" |
27 #include "chrome/browser/safe_browsing/protocol_manager.h" | 27 #include "chrome/browser/safe_browsing/protocol_manager.h" |
28 #include "chrome/browser/safe_browsing/safe_browsing_database.h" | 28 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 342 |
343 bool LocalSafeBrowsingDatabaseManager::CheckDownloadUrl( | 343 bool LocalSafeBrowsingDatabaseManager::CheckDownloadUrl( |
344 const std::vector<GURL>& url_chain, | 344 const std::vector<GURL>& url_chain, |
345 Client* client) { | 345 Client* client) { |
346 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 346 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
347 if (!enabled_ || !enable_download_protection_) | 347 if (!enabled_ || !enable_download_protection_) |
348 return true; | 348 return true; |
349 | 349 |
350 // We need to check the database for url prefix, and later may fetch the url | 350 // We need to check the database for url prefix, and later may fetch the url |
351 // from the safebrowsing backends. These need to be asynchronous. | 351 // from the safebrowsing backends. These need to be asynchronous. |
352 SafeBrowsingCheck* check = new SafeBrowsingCheck( | 352 std::unique_ptr<SafeBrowsingCheck> check = |
353 url_chain, std::vector<SBFullHash>(), client, BINURL, | 353 base::MakeUnique<SafeBrowsingCheck>( |
354 std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL)); | 354 url_chain, std::vector<SBFullHash>(), client, BINURL, |
| 355 std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL)); |
355 std::vector<SBPrefix> prefixes; | 356 std::vector<SBPrefix> prefixes; |
356 SafeBrowsingDatabase::GetDownloadUrlPrefixes(url_chain, &prefixes); | 357 SafeBrowsingDatabase::GetDownloadUrlPrefixes(url_chain, &prefixes); |
357 StartSafeBrowsingCheck( | 358 StartSafeBrowsingCheck( |
358 check, | 359 std::move(check), |
359 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, | 360 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckDownloadUrlOnSBThread, |
360 this, prefixes)); | 361 this, prefixes)); |
361 return false; | 362 return false; |
362 } | 363 } |
363 | 364 |
364 bool LocalSafeBrowsingDatabaseManager::CheckExtensionIDs( | 365 bool LocalSafeBrowsingDatabaseManager::CheckExtensionIDs( |
365 const std::set<std::string>& extension_ids, | 366 const std::set<std::string>& extension_ids, |
366 Client* client) { | 367 Client* client) { |
367 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 368 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
368 | 369 |
369 if (!enabled_ || !enable_extension_blacklist_) | 370 if (!enabled_ || !enable_extension_blacklist_) |
370 return true; | 371 return true; |
371 | 372 |
372 std::vector<SBFullHash> extension_id_hashes; | 373 std::vector<SBFullHash> extension_id_hashes; |
373 std::transform(extension_ids.begin(), extension_ids.end(), | 374 std::transform(extension_ids.begin(), extension_ids.end(), |
374 std::back_inserter(extension_id_hashes), StringToSBFullHash); | 375 std::back_inserter(extension_id_hashes), StringToSBFullHash); |
375 std::vector<SBPrefix> prefixes; | 376 std::vector<SBPrefix> prefixes; |
376 for (const SBFullHash& hash : extension_id_hashes) | 377 for (const SBFullHash& hash : extension_id_hashes) |
377 prefixes.push_back(hash.prefix); | 378 prefixes.push_back(hash.prefix); |
378 | 379 |
379 SafeBrowsingCheck* check = new SafeBrowsingCheck( | 380 std::unique_ptr<SafeBrowsingCheck> check = |
380 std::vector<GURL>(), extension_id_hashes, client, EXTENSIONBLACKLIST, | 381 base::MakeUnique<SafeBrowsingCheck>( |
381 std::vector<SBThreatType>(1, SB_THREAT_TYPE_EXTENSION)); | 382 std::vector<GURL>(), extension_id_hashes, client, EXTENSIONBLACKLIST, |
| 383 std::vector<SBThreatType>(1, SB_THREAT_TYPE_EXTENSION)); |
382 StartSafeBrowsingCheck( | 384 StartSafeBrowsingCheck( |
383 check, | 385 std::move(check), |
384 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread, | 386 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckExtensionIDsOnSBThread, |
385 this, prefixes)); | 387 this, prefixes)); |
386 return false; | 388 return false; |
387 } | 389 } |
388 | 390 |
389 bool LocalSafeBrowsingDatabaseManager::CheckResourceUrl(const GURL& url, | 391 bool LocalSafeBrowsingDatabaseManager::CheckResourceUrl(const GURL& url, |
390 Client* client) { | 392 Client* client) { |
391 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 393 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
392 | 394 |
393 if (!enabled_ || !CanCheckUrl(url)) | 395 if (!enabled_ || !CanCheckUrl(url)) |
394 return true; | 396 return true; |
395 | 397 |
396 std::vector<SBThreatType> expected_threats = { | 398 std::vector<SBThreatType> expected_threats = { |
397 SB_THREAT_TYPE_BLACKLISTED_RESOURCE}; | 399 SB_THREAT_TYPE_BLACKLISTED_RESOURCE}; |
398 | 400 |
399 if (!MakeDatabaseAvailable()) { | 401 if (!MakeDatabaseAvailable()) { |
400 QueuedCheck queued_check(RESOURCEBLACKLIST, client, url, expected_threats, | 402 QueuedCheck queued_check(RESOURCEBLACKLIST, client, url, expected_threats, |
401 base::TimeTicks::Now()); | 403 base::TimeTicks::Now()); |
402 queued_checks_.push_back(queued_check); | 404 queued_checks_.push_back(queued_check); |
403 return false; | 405 return false; |
404 } | 406 } |
405 | 407 |
406 SafeBrowsingCheck* check = | 408 std::unique_ptr<SafeBrowsingCheck> check = base::WrapUnique( |
407 new SafeBrowsingCheck({url}, std::vector<SBFullHash>(), client, | 409 new SafeBrowsingCheck({url}, std::vector<SBFullHash>(), client, |
408 RESOURCEBLACKLIST, expected_threats); | 410 RESOURCEBLACKLIST, expected_threats)); |
409 | 411 |
410 std::vector<SBPrefix> prefixes; | 412 std::vector<SBPrefix> prefixes; |
411 SafeBrowsingDatabase::GetDownloadUrlPrefixes(check->urls, &prefixes); | 413 SafeBrowsingDatabase::GetDownloadUrlPrefixes(check->urls, &prefixes); |
412 StartSafeBrowsingCheck( | 414 StartSafeBrowsingCheck( |
413 check, | 415 std::move(check), |
414 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckResourceUrlOnSBThread, | 416 base::Bind(&LocalSafeBrowsingDatabaseManager::CheckResourceUrlOnSBThread, |
415 this, prefixes)); | 417 this, prefixes)); |
416 return false; | 418 return false; |
417 } | 419 } |
418 | 420 |
419 bool LocalSafeBrowsingDatabaseManager::MatchMalwareIP( | 421 bool LocalSafeBrowsingDatabaseManager::MatchMalwareIP( |
420 const std::string& ip_address) { | 422 const std::string& ip_address) { |
421 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 423 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
422 if (!enabled_ || !enable_ip_blacklist_ || !MakeDatabaseAvailable()) { | 424 if (!enabled_ || !enable_ip_blacklist_ || !MakeDatabaseAvailable()) { |
423 return false; // Fail open. | 425 return false; // Fail open. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 // This check will ping the Safe Browsing servers and get all lists which it | 542 // This check will ping the Safe Browsing servers and get all lists which it |
541 // matches. These lists will then be filtered against the |expected_threats| | 543 // matches. These lists will then be filtered against the |expected_threats| |
542 // and the result callback for MALWARE (which is the same as for PHISH and | 544 // and the result callback for MALWARE (which is the same as for PHISH and |
543 // UNWANTEDURL) will eventually be invoked with the final decision. | 545 // UNWANTEDURL) will eventually be invoked with the final decision. |
544 SafeBrowsingCheck* check = new SafeBrowsingCheck( | 546 SafeBrowsingCheck* check = new SafeBrowsingCheck( |
545 std::vector<GURL>(1, url), std::vector<SBFullHash>(), client, MALWARE, | 547 std::vector<GURL>(1, url), std::vector<SBFullHash>(), client, MALWARE, |
546 expected_threats); | 548 expected_threats); |
547 check->need_get_hash = cache_hits.empty(); | 549 check->need_get_hash = cache_hits.empty(); |
548 check->prefix_hits.swap(prefix_hits); | 550 check->prefix_hits.swap(prefix_hits); |
549 check->cache_hits.swap(cache_hits); | 551 check->cache_hits.swap(cache_hits); |
550 checks_.insert(check); | 552 checks_[check] = base::WrapUnique(check); |
551 | 553 |
552 BrowserThread::PostTask( | 554 BrowserThread::PostTask( |
553 BrowserThread::IO, FROM_HERE, | 555 BrowserThread::IO, FROM_HERE, |
554 base::Bind(&LocalSafeBrowsingDatabaseManager::OnCheckDone, this, check)); | 556 base::Bind(&LocalSafeBrowsingDatabaseManager::OnCheckDone, this, check)); |
555 | 557 |
556 return false; | 558 return false; |
557 } | 559 } |
558 | 560 |
559 void LocalSafeBrowsingDatabaseManager::CancelCheck(Client* client) { | 561 void LocalSafeBrowsingDatabaseManager::CancelCheck(Client* client) { |
560 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 562 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
561 for (CurrentChecks::iterator i = checks_.begin(); i != checks_.end(); ++i) { | 563 for (const auto& check : checks_) { |
562 // We can't delete matching checks here because the db thread has a copy of | 564 // We can't delete matching checks here because the db thread has a copy of |
563 // the pointer. Instead, we simply NULL out the client, and when the db | 565 // the pointer. Instead, we simply NULL out the client, and when the db |
564 // thread calls us back, we'll clean up the check. | 566 // thread calls us back, we'll clean up the check. |
565 if ((*i)->client == client) | 567 if (check.first->client == client) |
566 (*i)->client = NULL; | 568 check.first->client = NULL; |
567 } | 569 } |
568 | 570 |
569 // Scan the queued clients store. Clients may be here if they requested a URL | 571 // Scan the queued clients store. Clients may be here if they requested a URL |
570 // check before the database has finished loading. | 572 // check before the database has finished loading. |
571 for (std::deque<QueuedCheck>::iterator it(queued_checks_.begin()); | 573 for (auto it = queued_checks_.begin(); it != queued_checks_.end();) { |
572 it != queued_checks_.end();) { | |
573 // In this case it's safe to delete matches entirely since nothing has a | 574 // In this case it's safe to delete matches entirely since nothing has a |
574 // pointer to them. | 575 // pointer to them. |
575 if (it->client == client) | 576 if (it->client == client) |
576 it = queued_checks_.erase(it); | 577 it = queued_checks_.erase(it); |
577 else | 578 else |
578 ++it; | 579 ++it; |
579 } | 580 } |
580 } | 581 } |
581 | 582 |
582 void LocalSafeBrowsingDatabaseManager::HandleGetHashResults( | 583 void LocalSafeBrowsingDatabaseManager::HandleGetHashResults( |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 closing_database_ = true; | 762 closing_database_ = true; |
762 safe_browsing_task_runner_->PostTask( | 763 safe_browsing_task_runner_->PostTask( |
763 FROM_HERE, | 764 FROM_HERE, |
764 base::Bind(&LocalSafeBrowsingDatabaseManager::OnCloseDatabase, this)); | 765 base::Bind(&LocalSafeBrowsingDatabaseManager::OnCloseDatabase, this)); |
765 } | 766 } |
766 | 767 |
767 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. | 768 // Delete pending checks, calling back any clients with 'SB_THREAT_TYPE_SAFE'. |
768 // We have to do this after the db thread returns because methods on it can | 769 // We have to do this after the db thread returns because methods on it can |
769 // have copies of these pointers, so deleting them might lead to accessing | 770 // have copies of these pointers, so deleting them might lead to accessing |
770 // garbage. | 771 // garbage. |
771 for (CurrentChecks::iterator it = checks_.begin(); it != checks_.end(); | 772 for (const auto& check : checks_) { |
772 ++it) { | 773 if (check.first->client) |
773 SafeBrowsingCheck* check = *it; | 774 check.first->OnSafeBrowsingResult(); |
774 if (check->client) | |
775 check->OnSafeBrowsingResult(); | |
776 } | 775 } |
777 base::STLDeleteElements(&checks_); | |
778 | 776 |
| 777 checks_.clear(); |
779 gethash_requests_.clear(); | 778 gethash_requests_.clear(); |
780 } | 779 } |
781 | 780 |
782 bool LocalSafeBrowsingDatabaseManager::DatabaseAvailable() const { | 781 bool LocalSafeBrowsingDatabaseManager::DatabaseAvailable() const { |
783 base::AutoLock lock(database_lock_); | 782 base::AutoLock lock(database_lock_); |
784 return !closing_database_ && (database_ != NULL); | 783 return !closing_database_ && (database_ != NULL); |
785 } | 784 } |
786 | 785 |
787 bool LocalSafeBrowsingDatabaseManager::MakeDatabaseAvailable() { | 786 bool LocalSafeBrowsingDatabaseManager::MakeDatabaseAvailable() { |
788 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 787 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1212 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1214 DCHECK(check); | 1213 DCHECK(check); |
1215 | 1214 |
1216 if (!enabled_) | 1215 if (!enabled_) |
1217 return; | 1216 return; |
1218 | 1217 |
1219 DCHECK(checks_.find(check) != checks_.end()); | 1218 DCHECK(checks_.find(check) != checks_.end()); |
1220 if (check->client) | 1219 if (check->client) |
1221 check->OnSafeBrowsingResult(); | 1220 check->OnSafeBrowsingResult(); |
1222 checks_.erase(check); | 1221 checks_.erase(check); |
1223 delete check; | |
1224 } | 1222 } |
1225 | 1223 |
1226 void LocalSafeBrowsingDatabaseManager::StartSafeBrowsingCheck( | 1224 void LocalSafeBrowsingDatabaseManager::StartSafeBrowsingCheck( |
1227 SafeBrowsingCheck* check, | 1225 std::unique_ptr<SafeBrowsingCheck> check, |
1228 const base::Callback<std::vector<SBPrefix>(void)>& task) { | 1226 const base::Callback<std::vector<SBPrefix>(void)>& task) { |
1229 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1227 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1230 check->weak_ptr_factory_.reset( | 1228 check->weak_ptr_factory_.reset( |
1231 new base::WeakPtrFactory<LocalSafeBrowsingDatabaseManager>(this)); | 1229 new base::WeakPtrFactory<LocalSafeBrowsingDatabaseManager>(this)); |
1232 checks_.insert(check); | 1230 SafeBrowsingCheck* check_ptr = check.get(); |
| 1231 checks_[check_ptr] = std::move(check); |
1233 | 1232 |
1234 base::PostTaskAndReplyWithResult( | 1233 base::PostTaskAndReplyWithResult( |
1235 safe_browsing_task_runner_.get(), FROM_HERE, task, | 1234 safe_browsing_task_runner_.get(), FROM_HERE, task, |
1236 base::Bind(&LocalSafeBrowsingDatabaseManager::OnAsyncCheckDone, | 1235 base::Bind(&LocalSafeBrowsingDatabaseManager::OnAsyncCheckDone, |
1237 check->weak_ptr_factory_->GetWeakPtr(), check)); | 1236 check_ptr->weak_ptr_factory_->GetWeakPtr(), check_ptr)); |
1238 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 1237 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
1239 FROM_HERE, base::Bind(&LocalSafeBrowsingDatabaseManager::TimeoutCallback, | 1238 FROM_HERE, |
1240 check->weak_ptr_factory_->GetWeakPtr(), check), | 1239 base::Bind(&LocalSafeBrowsingDatabaseManager::TimeoutCallback, |
| 1240 check_ptr->weak_ptr_factory_->GetWeakPtr(), check_ptr), |
1241 check_timeout_); | 1241 check_timeout_); |
1242 } | 1242 } |
1243 | 1243 |
1244 bool LocalSafeBrowsingDatabaseManager::IsDownloadProtectionEnabled() const { | 1244 bool LocalSafeBrowsingDatabaseManager::IsDownloadProtectionEnabled() const { |
1245 return enable_download_protection_; | 1245 return enable_download_protection_; |
1246 } | 1246 } |
1247 | 1247 |
1248 } // namespace safe_browsing | 1248 } // namespace safe_browsing |
OLD | NEW |