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

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

Issue 794273002: Introduce SafeBrowsingDatabase::ThreadSafeStateManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a6_dedup_sideeffectfreeWLcode
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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
7 7
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 // A SafeBrowsing whitelist contains a list of whitelisted full-hashes (stored 360 // A SafeBrowsing whitelist contains a list of whitelisted full-hashes (stored
361 // in a sorted vector) as well as a boolean flag indicating whether all 361 // in a sorted vector) as well as a boolean flag indicating whether all
362 // lookups in the whitelist should be considered matches for safety. 362 // lookups in the whitelist should be considered matches for safety.
363 typedef std::pair<std::vector<SBFullHash>, bool> SBWhitelist; 363 typedef std::pair<std::vector<SBFullHash>, bool> SBWhitelist;
364 364
365 // This map holds a csd malware IP blacklist which maps a prefix mask 365 // This map holds a csd malware IP blacklist which maps a prefix mask
366 // to a set of hashed blacklisted IP prefixes. Each IP prefix is a hashed 366 // to a set of hashed blacklisted IP prefixes. Each IP prefix is a hashed
367 // IPv6 IP prefix using SHA-1. 367 // IPv6 IP prefix using SHA-1.
368 typedef std::map<std::string, base::hash_set<std::string> > IPBlacklist; 368 typedef std::map<std::string, base::hash_set<std::string> > IPBlacklist;
369 369
370 bool PrefixSetContainsUrl( 370 typedef std::map<SBPrefix, SBCachedFullHashResult> PrefixGetHashCache;
371 const GURL& url, 371
372 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 372 // The ThreadSafeStateManager holds the SafeBrowsingDatabase's state which
373 std::vector<SBPrefix>* prefix_hits, 373 // must be accessed in a thread-safe fashion. It must be constructed on the
374 std::vector<SBFullHashResult>* cache_hits); 374 // SafeBrowsingDatabaseManager's main thread. The main thread will then be the
375 // only thread on which this state can be modified; allowing for unlocked
376 // reads on the main thread and thus avoiding contention while performing
377 // intensive operations such as writing that state to disk. The state can only
378 // be accessed via (Read|Write)Transactions obtained through this class which
379 // will automatically handle thread-safety.
380 class ThreadSafeStateManager {
381 public:
382 // Identifiers for stores held by the ThreadSafeStateManager. Allows helper
383 // methods to start a transaction themselves and keep it as short as
384 // possible rather than force callers to start the transaction early to pass
385 // a store pointer to the said helper methods.
386 enum class SBWhitelistId {
387 CSD,
388 DOWNLOAD,
389 };
390 enum class PrefixSetId {
391 BROWSE,
392 SIDE_EFFECT_FREE_WHITELIST,
393 UNWANTED_SOFTWARE,
394 };
395
396 // A ReadTransaction allows read-only observations of the
397 // ThreadSafeStateManager's state. The |prefix_gethash_cache_| has a special
398 // allowance to be writable from a ReadTransaction but can't benefit from
399 // unlocked ReadTransactions. ReadTransaction should be held for the
400 // shortest amount of time possible (e.g., release it before computing final
401 // results if possible).
402 class ReadTransaction;
403
404 // A WriteTransaction allows modification of the ThreadSafeStateManager's
405 // state. It should be used for the shortest amount of time possible (e.g.,
406 // pre-compute the new state before grabbing a WriteTransaction to swap it
407 // in atomically).
408 class WriteTransaction;
409
410 ThreadSafeStateManager();
411 ~ThreadSafeStateManager();
412
413 scoped_ptr<ReadTransaction> BeginReadTransaction();
414 scoped_ptr<ReadTransaction> BeginReadTransactionNoLockOnMainThread();
415 scoped_ptr<WriteTransaction> BeginWriteTransaction();
416
417 private:
418 // Used to verify that writes are only made on this object's main thread.
419 // This is important as this class allows reading from the main thread
420 // without holding the lock.
421 base::ThreadChecker thread_checker_;
422
423 // Lock for protecting access to this class' state.
424 base::Lock lock_;
425
426 SBWhitelist csd_whitelist_;
427 SBWhitelist download_whitelist_;
428
429 // The IP blacklist should be small. At most a couple hundred IPs.
430 IPBlacklist ip_blacklist_;
431
432 // PrefixSets to speed up lookups for particularly large lists. The
433 // PrefixSet themselves are never modified, instead a new one is swapped in
434 // on update.
435 scoped_ptr<const safe_browsing::PrefixSet> browse_prefix_set_;
436 scoped_ptr<const safe_browsing::PrefixSet>
437 side_effect_free_whitelist_prefix_set_;
438 scoped_ptr<const safe_browsing::PrefixSet> unwanted_software_prefix_set_;
439
440 // Cache of gethash results for prefix stores. Entries should not be used if
441 // they are older than their expire_after field. Cached misses will have
442 // empty full_hashes field. Cleared on each update.
443 PrefixGetHashCache prefix_gethash_cache_;
444
445 DISALLOW_COPY_AND_ASSIGN(ThreadSafeStateManager);
446 };
447
448 // Forward the above inner-definitions to alleviate some verbosity in the
449 // impl.
450 using SBWhitelistId = ThreadSafeStateManager::SBWhitelistId;
451 using PrefixSetId = ThreadSafeStateManager::PrefixSetId;
452 using ReadTransaction = ThreadSafeStateManager::ReadTransaction;
453 using WriteTransaction = ThreadSafeStateManager::WriteTransaction;
454
455 bool PrefixSetContainsUrl(const GURL& url,
456 PrefixSetId prefix_set_id,
457 std::vector<SBPrefix>* prefix_hits,
458 std::vector<SBFullHashResult>* cache_hits);
375 459
376 // Exposed for testing of PrefixSetContainsUrlHashes() on the 460 // Exposed for testing of PrefixSetContainsUrlHashes() on the
377 // PrefixSet backing kMalwareList. 461 // PrefixSet backing kMalwareList.
378 bool ContainsBrowseUrlHashesForTesting( 462 bool ContainsBrowseUrlHashesForTesting(
379 const std::vector<SBFullHash>& full_hashes, 463 const std::vector<SBFullHash>& full_hashes,
380 std::vector<SBPrefix>* prefix_hits, 464 std::vector<SBPrefix>* prefix_hits,
381 std::vector<SBFullHashResult>* cache_hits); 465 std::vector<SBFullHashResult>* cache_hits);
382 466
383 bool PrefixSetContainsUrlHashes( 467 bool PrefixSetContainsUrlHashes(const std::vector<SBFullHash>& full_hashes,
384 const std::vector<SBFullHash>& full_hashes, 468 PrefixSetId prefix_set_id,
385 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 469 std::vector<SBPrefix>* prefix_hits,
386 std::vector<SBPrefix>* prefix_hits, 470 std::vector<SBFullHashResult>* cache_hits);
387 std::vector<SBFullHashResult>* cache_hits);
388 471
389 // Returns true if the whitelist is disabled or if any of the given hashes 472 // Returns true if the whitelist is disabled or if any of the given hashes
390 // matches the whitelist. 473 // matches the whitelist.
391 bool ContainsWhitelistedHashes(const SBWhitelist& whitelist, 474 bool ContainsWhitelistedHashes(SBWhitelistId whitelist_id,
392 const std::vector<SBFullHash>& hashes); 475 const std::vector<SBFullHash>& hashes);
393 476
394 // Return the browse_store_, download_store_, download_whitelist_store or 477 // Return the browse_store_, download_store_, download_whitelist_store or
395 // csd_whitelist_store_ based on list_id. 478 // csd_whitelist_store_ based on list_id.
396 SafeBrowsingStore* GetStore(int list_id); 479 SafeBrowsingStore* GetStore(int list_id);
397 480
398 // Deletes the files on disk. 481 // Deletes the files on disk.
399 bool Delete(); 482 bool Delete();
400 483
401 // Load the prefix set in "|db_filename| Prefix Set" off disk, if available, 484 // Load the prefix set in "|db_filename| Prefix Set" off disk, if available,
402 // and stores it in |prefix_set|. |read_failure_type| provides a 485 // and stores it in the PrefixSet identified by |prefix_set_id|.
403 // caller-specific error code to be used on failure. 486 // |read_failure_type| provides a caller-specific error code to be used on
487 // failure. This method should only ever be called during initialization as
488 // it performs some disk IO while holding a transaction (for the sake of
489 // avoiding uncessary back-and-forth interactions with the lock during
490 // Init()).
404 void LoadPrefixSet(const base::FilePath& db_filename, 491 void LoadPrefixSet(const base::FilePath& db_filename,
405 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 492 ThreadSafeStateManager::WriteTransaction* txn,
493 PrefixSetId prefix_set_id,
406 FailureType read_failure_type); 494 FailureType read_failure_type);
407 495
408 // Writes the current prefix set "|db_filename| Prefix Set" on disk. 496 // Writes the current prefix set "|db_filename| Prefix Set" on disk.
409 // |write_failure_type| provides a caller-specific error code to be used on 497 // |write_failure_type| provides a caller-specific error code to be used on
410 // failure. 498 // failure.
411 void WritePrefixSet(const base::FilePath& db_filename, 499 void WritePrefixSet(const base::FilePath& db_filename,
412 const safe_browsing::PrefixSet* prefix_set, 500 const safe_browsing::PrefixSet* prefix_set,
413 FailureType write_failure_type); 501 FailureType write_failure_type);
414 502
415 // Loads the given full-length hashes to the given whitelist. If the number 503 // Loads the given full-length hashes to the given whitelist. If the number
416 // of hashes is too large or if the kill switch URL is on the whitelist 504 // of hashes is too large or if the kill switch URL is on the whitelist
417 // we will whitelist everything. 505 // we will whitelist everything.
418 void LoadWhitelist(const std::vector<SBAddFullHash>& full_hashes, 506 void LoadWhitelist(const std::vector<SBAddFullHash>& full_hashes,
419 SBWhitelist* whitelist); 507 SBWhitelistId whitelist_id);
420 508
421 // Call this method if an error occured with the given whitelist. This will 509 // Call this method if an error occured with the given whitelist. This will
422 // result in all lookups to the whitelist to return true. 510 // result in all lookups to the whitelist to return true.
423 void WhitelistEverything(SBWhitelist* whitelist); 511 void WhitelistEverything(SBWhitelistId whitelist_id);
424 512
425 // Parses the IP blacklist from the given full-length hashes. 513 // Parses the IP blacklist from the given full-length hashes.
426 void LoadIpBlacklist(const std::vector<SBAddFullHash>& full_hashes); 514 void LoadIpBlacklist(const std::vector<SBAddFullHash>& full_hashes);
427 515
428 // Helpers for handling database corruption. 516 // Helpers for handling database corruption.
429 // |OnHandleCorruptDatabase()| runs |ResetDatabase()| and sets 517 // |OnHandleCorruptDatabase()| runs |ResetDatabase()| and sets
430 // |corruption_detected_|, |HandleCorruptDatabase()| posts 518 // |corruption_detected_|, |HandleCorruptDatabase()| posts
431 // |OnHandleCorruptDatabase()| to the current thread, to be run 519 // |OnHandleCorruptDatabase()| to the current thread, to be run
432 // after the current task completes. 520 // after the current task completes.
433 // TODO(shess): Wire things up to entirely abort the update 521 // TODO(shess): Wire things up to entirely abort the update
(...skipping 12 matching lines...) Expand all
446 // Returns the size in bytes of the store after the update. 534 // Returns the size in bytes of the store after the update.
447 int64 UpdateHashPrefixStore(const base::FilePath& store_filename, 535 int64 UpdateHashPrefixStore(const base::FilePath& store_filename,
448 SafeBrowsingStore* store, 536 SafeBrowsingStore* store,
449 FailureType failure_type); 537 FailureType failure_type);
450 538
451 // Updates a PrefixStore store for URLs (|url_store|) which is backed on disk 539 // Updates a PrefixStore store for URLs (|url_store|) which is backed on disk
452 // by a "|db_filename| Prefix Set" file. Specific failure types are provided 540 // by a "|db_filename| Prefix Set" file. Specific failure types are provided
453 // to highlight the specific store who made the initial request on failure. 541 // to highlight the specific store who made the initial request on failure.
454 // |store_full_hashes_in_prefix_set| dictates whether full_hashes from the 542 // |store_full_hashes_in_prefix_set| dictates whether full_hashes from the
455 // |url_store| should be cached in the |prefix_set| as well. 543 // |url_store| should be cached in the |prefix_set| as well.
456 void UpdatePrefixSetUrlStore( 544 void UpdatePrefixSetUrlStore(const base::FilePath& db_filename,
457 const base::FilePath& db_filename, 545 SafeBrowsingStore* url_store,
458 SafeBrowsingStore* url_store, 546 PrefixSetId prefix_set_id,
459 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 547 FailureType finish_failure_type,
460 FailureType finish_failure_type, 548 FailureType write_failure_type,
461 FailureType write_failure_type, 549 bool store_full_hashes_in_prefix_set);
462 bool store_full_hashes_in_prefix_set);
463 550
464 void UpdateUrlStore(SafeBrowsingStore* url_store, 551 void UpdateUrlStore(SafeBrowsingStore* url_store,
465 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 552 PrefixSetId prefix_set_id,
466 FailureType failure_type); 553 FailureType failure_type);
467 554
468 void UpdateWhitelistStore(const base::FilePath& store_filename, 555 void UpdateWhitelistStore(const base::FilePath& store_filename,
469 SafeBrowsingStore* store, 556 SafeBrowsingStore* store,
470 SBWhitelist* whitelist); 557 SBWhitelistId whitelist_id);
471 void UpdateIpBlacklistStore(); 558 void UpdateIpBlacklistStore();
472 559
473 // Used to verify that various calls are made from the thread the 560 // Returns a raw pointer to ThreadSafeStateManager's PrefixGetHashCache for
474 // object was created on (i.e., the safe_browsing_thread). 561 // testing. This should only be used in unit tests (where multi-threading and
475 base::ThreadChecker thread_checker_; 562 // synchronization are not problematic).
563 PrefixGetHashCache* GetUnsynchronizedPrefixGetHashCacheForTesting();
564
565 ThreadSafeStateManager state_manager_;
476 566
477 // The base filename passed to Init(), used to generate the store and prefix 567 // The base filename passed to Init(), used to generate the store and prefix
478 // set filenames used to store data on disk. 568 // set filenames used to store data on disk.
479 base::FilePath filename_base_; 569 base::FilePath filename_base_;
480 570
481 // Underlying persistent store for chunk data. 571 // Underlying persistent store for chunk data.
482 // For browsing related (phishing and malware URLs) chunks and prefixes. 572 // For browsing related (phishing and malware URLs) chunks and prefixes.
483 scoped_ptr<SafeBrowsingStore> browse_store_; 573 scoped_ptr<SafeBrowsingStore> browse_store_;
484 574
485 // For download related (download URL and binary hash) chunks and prefixes. 575 // For download related (download URL and binary hash) chunks and prefixes.
(...skipping 12 matching lines...) Expand all
498 588
499 // For side-effect free whitelist. 589 // For side-effect free whitelist.
500 scoped_ptr<SafeBrowsingStore> side_effect_free_whitelist_store_; 590 scoped_ptr<SafeBrowsingStore> side_effect_free_whitelist_store_;
501 591
502 // For IP blacklist. 592 // For IP blacklist.
503 scoped_ptr<SafeBrowsingStore> ip_blacklist_store_; 593 scoped_ptr<SafeBrowsingStore> ip_blacklist_store_;
504 594
505 // For unwanted software list. 595 // For unwanted software list.
506 scoped_ptr<SafeBrowsingStore> unwanted_software_store_; 596 scoped_ptr<SafeBrowsingStore> unwanted_software_store_;
507 597
508 // Lock for protecting access to variables that may be used on any threads.
509 // This includes all SBWhitelist's, PrefixSet's, and caches.
510 base::Lock lookup_lock_;
511
512 SBWhitelist csd_whitelist_;
513 SBWhitelist download_whitelist_;
514
515 // The IP blacklist should be small. At most a couple hundred IPs.
516 IPBlacklist ip_blacklist_;
517
518 // Cache of gethash results for prefix stores. Entries should not be used if
519 // they are older than their expire_after field. Cached misses will have
520 // empty full_hashes field. Cleared on each update.
521 std::map<SBPrefix, SBCachedFullHashResult> prefix_gethash_cache_;
522
523 // Set if corruption is detected during the course of an update. 598 // Set if corruption is detected during the course of an update.
524 // Causes the update functions to fail with no side effects, until 599 // Causes the update functions to fail with no side effects, until
525 // the next call to |UpdateStarted()|. 600 // the next call to |UpdateStarted()|.
526 bool corruption_detected_; 601 bool corruption_detected_;
527 602
528 // Set to true if any chunks are added or deleted during an update. 603 // Set to true if any chunks are added or deleted during an update.
529 // Used to optimize away database update. 604 // Used to optimize away database update.
530 bool change_detected_; 605 bool change_detected_;
mattm 2014/12/12 23:20:31 Should all the non-thread-safe members be moved to
gab 2014/12/15 23:02:30 Good point, do you think the SafeBrowsingStores sh
mattm 2014/12/23 02:09:45 I guess to make it more consistent putting them in
gab 2014/12/23 21:39:54 SG, how about we do this in a follow-up CL since t
mattm 2014/12/24 00:29:53 separate CL sounds good
531 606
532 // PrefixSets to speed up lookups for particularly large lists. The PrefixSet
533 // themselves are never modified, instead a new one is swapped in on update
534 // while holding |lookup_lock_|. Any thread other than this class' main thread
535 // (which handles updates) must hold |lookup_lock_| before reading from these
536 // sets.
537 // TODO(gab): Enforce this by design.
538 scoped_ptr<const safe_browsing::PrefixSet> browse_prefix_set_;
539 scoped_ptr<const safe_browsing::PrefixSet>
540 side_effect_free_whitelist_prefix_set_;
541 scoped_ptr<const safe_browsing::PrefixSet> unwanted_software_prefix_set_;
542
543 // Used to schedule resetting the database because of corruption. 607 // Used to schedule resetting the database because of corruption.
544 base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_; 608 base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_;
545 }; 609 };
546 610
547 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 611 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698