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

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

Issue 611603002: Add the goog-unwanted-shavar list to a new SafeBrowsing PrefixSet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits and cl format Created 6 years, 1 month 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 FILE_PATH_LITERAL(" Download Whitelist"); 50 FILE_PATH_LITERAL(" Download Whitelist");
51 // Filename suffix for the extension blacklist store. 51 // Filename suffix for the extension blacklist store.
52 const base::FilePath::CharType kExtensionBlacklistDBFile[] = 52 const base::FilePath::CharType kExtensionBlacklistDBFile[] =
53 FILE_PATH_LITERAL(" Extension Blacklist"); 53 FILE_PATH_LITERAL(" Extension Blacklist");
54 // Filename suffix for the side-effect free whitelist store. 54 // Filename suffix for the side-effect free whitelist store.
55 const base::FilePath::CharType kSideEffectFreeWhitelistDBFile[] = 55 const base::FilePath::CharType kSideEffectFreeWhitelistDBFile[] =
56 FILE_PATH_LITERAL(" Side-Effect Free Whitelist"); 56 FILE_PATH_LITERAL(" Side-Effect Free Whitelist");
57 // Filename suffix for the csd malware IP blacklist store. 57 // Filename suffix for the csd malware IP blacklist store.
58 const base::FilePath::CharType kIPBlacklistDBFile[] = 58 const base::FilePath::CharType kIPBlacklistDBFile[] =
59 FILE_PATH_LITERAL(" IP Blacklist"); 59 FILE_PATH_LITERAL(" IP Blacklist");
60 // Filename suffix for the unwanted software blacklist store.
61 const base::FilePath::CharType kUnwantedSoftwareDBFile[] =
62 FILE_PATH_LITERAL(" UwS List");
60 63
61 // Filename suffix for browse store. 64 // Filename suffix for browse store.
62 // TODO(shess): "Safe Browsing Bloom Prefix Set" is full of win. 65 // TODO(shess): "Safe Browsing Bloom Prefix Set" is full of win.
63 // Unfortunately, to change the name implies lots of transition code 66 // Unfortunately, to change the name implies lots of transition code
64 // for little benefit. If/when file formats change (say to put all 67 // for little benefit. If/when file formats change (say to put all
65 // the data in one file), that would be a convenient point to rectify 68 // the data in one file), that would be a convenient point to rectify
66 // this. 69 // this.
67 // TODO(shess): This shouldn't be OS-driven <http://crbug.com/394379> 70 // TODO(shess): This shouldn't be OS-driven <http://crbug.com/394379>
68 #if defined(OS_ANDROID) 71 #if defined(OS_ANDROID)
69 // NOTE(shess): This difference is also reflected in the list name in 72 // NOTE(shess): This difference is also reflected in the list name in
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // Generate the set of full hashes to check for |url|. If 118 // Generate the set of full hashes to check for |url|. If
116 // |include_whitelist_hashes| is true we will generate additional path-prefixes 119 // |include_whitelist_hashes| is true we will generate additional path-prefixes
117 // to match against the csd whitelist. E.g., if the path-prefix /foo is on the 120 // to match against the csd whitelist. E.g., if the path-prefix /foo is on the
118 // whitelist it should also match /foo/bar which is not the case for all the 121 // whitelist it should also match /foo/bar which is not the case for all the
119 // other lists. We'll also always add a pattern for the empty path. 122 // other lists. We'll also always add a pattern for the empty path.
120 // TODO(shess): This function is almost the same as 123 // TODO(shess): This function is almost the same as
121 // |CompareFullHashes()| in safe_browsing_util.cc, except that code 124 // |CompareFullHashes()| in safe_browsing_util.cc, except that code
122 // does an early exit on match. Since match should be the infrequent 125 // does an early exit on match. Since match should be the infrequent
123 // case (phishing or malware found), consider combining this function 126 // case (phishing or malware found), consider combining this function
124 // with that one. 127 // with that one.
125 void BrowseFullHashesToCheck(const GURL& url, 128 void UrlToFullHashes(const GURL& url,
126 bool include_whitelist_hashes, 129 bool include_whitelist_hashes,
127 std::vector<SBFullHash>* full_hashes) { 130 std::vector<SBFullHash>* full_hashes) {
128 std::vector<std::string> hosts; 131 std::vector<std::string> hosts;
129 if (url.HostIsIPAddress()) { 132 if (url.HostIsIPAddress()) {
130 hosts.push_back(url.host()); 133 hosts.push_back(url.host());
131 } else { 134 } else {
132 safe_browsing_util::GenerateHostsToCheck(url, &hosts); 135 safe_browsing_util::GenerateHostsToCheck(url, &hosts);
133 } 136 }
134 137
135 std::vector<std::string> paths; 138 std::vector<std::string> paths;
136 safe_browsing_util::GeneratePathsToCheck(url, &paths); 139 safe_browsing_util::GeneratePathsToCheck(url, &paths);
137 140
(...skipping 13 matching lines...) Expand all
151 } 154 }
152 } 155 }
153 } 156 }
154 } 157 }
155 158
156 // Get the prefixes matching the download |urls|. 159 // Get the prefixes matching the download |urls|.
157 void GetDownloadUrlPrefixes(const std::vector<GURL>& urls, 160 void GetDownloadUrlPrefixes(const std::vector<GURL>& urls,
158 std::vector<SBPrefix>* prefixes) { 161 std::vector<SBPrefix>* prefixes) {
159 std::vector<SBFullHash> full_hashes; 162 std::vector<SBFullHash> full_hashes;
160 for (size_t i = 0; i < urls.size(); ++i) 163 for (size_t i = 0; i < urls.size(); ++i)
161 BrowseFullHashesToCheck(urls[i], false, &full_hashes); 164 UrlToFullHashes(urls[i], false, &full_hashes);
162 165
163 for (size_t i = 0; i < full_hashes.size(); ++i) 166 for (size_t i = 0; i < full_hashes.size(); ++i)
164 prefixes->push_back(full_hashes[i].prefix); 167 prefixes->push_back(full_hashes[i].prefix);
165 } 168 }
166 169
167 // Helper function to compare addprefixes in |store| with |prefixes|. 170 // Helper function to compare addprefixes in |store| with |prefixes|.
168 // The |list_bit| indicates which list (url or hash) to compare. 171 // The |list_bit| indicates which list (url or hash) to compare.
169 // 172 //
170 // Returns true if there is a match, |*prefix_hits| (if non-NULL) will contain 173 // Returns true if there is a match, |*prefix_hits| (if non-NULL) will contain
171 // the actual matching prefixes. 174 // the actual matching prefixes.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 273
271 // This code always checks for non-zero file size. This helper makes 274 // This code always checks for non-zero file size. This helper makes
272 // that less verbose. 275 // that less verbose.
273 int64 GetFileSizeOrZero(const base::FilePath& file_path) { 276 int64 GetFileSizeOrZero(const base::FilePath& file_path) {
274 int64 size_64; 277 int64 size_64;
275 if (!base::GetFileSize(file_path, &size_64)) 278 if (!base::GetFileSize(file_path, &size_64))
276 return 0; 279 return 0;
277 return size_64; 280 return size_64;
278 } 281 }
279 282
280 // Helper for ContainsBrowseUrlHashes(). Returns true if an un-expired match 283 // Helper for PrefixSetContainsUrlHashes(). Returns true if an un-expired match
281 // for |full_hash| is found in |cache|, with any matches appended to |results| 284 // for |full_hash| is found in |cache|, with any matches appended to |results|
282 // (true can be returned with zero matches). |expire_base| is used to check the 285 // (true can be returned with zero matches). |expire_base| is used to check the
283 // cache lifetime of matches, expired matches will be discarded from |cache|. 286 // cache lifetime of matches, expired matches will be discarded from |cache|.
284 bool GetCachedFullHash(std::map<SBPrefix, SBCachedFullHashResult>* cache, 287 bool GetCachedFullHash(std::map<SBPrefix, SBCachedFullHashResult>* cache,
285 const SBFullHash& full_hash, 288 const SBFullHash& full_hash,
286 const base::Time& expire_base, 289 const base::Time& expire_base,
287 std::vector<SBFullHashResult>* results) { 290 std::vector<SBFullHashResult>* results) {
288 // First check if there is a valid cached result for this prefix. 291 // First check if there is a valid cached result for this prefix.
289 std::map<SBPrefix, SBCachedFullHashResult>::iterator 292 std::map<SBPrefix, SBCachedFullHashResult>::iterator
290 citer = cache->find(full_hash.prefix); 293 citer = cache->find(full_hash.prefix);
(...skipping 21 matching lines...) Expand all
312 315
313 // The default SafeBrowsingDatabaseFactory. 316 // The default SafeBrowsingDatabaseFactory.
314 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { 317 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
315 public: 318 public:
316 SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 319 SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
317 bool enable_download_protection, 320 bool enable_download_protection,
318 bool enable_client_side_whitelist, 321 bool enable_client_side_whitelist,
319 bool enable_download_whitelist, 322 bool enable_download_whitelist,
320 bool enable_extension_blacklist, 323 bool enable_extension_blacklist,
321 bool enable_side_effect_free_whitelist, 324 bool enable_side_effect_free_whitelist,
322 bool enable_ip_blacklist) override { 325 bool enable_ip_blacklist,
326 bool enable_unwanted_software_list) override {
323 return new SafeBrowsingDatabaseNew( 327 return new SafeBrowsingDatabaseNew(
324 new SafeBrowsingStoreFile, 328 new SafeBrowsingStoreFile,
325 enable_download_protection ? new SafeBrowsingStoreFile : NULL, 329 enable_download_protection ? new SafeBrowsingStoreFile : NULL,
326 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL, 330 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL,
327 enable_download_whitelist ? new SafeBrowsingStoreFile : NULL, 331 enable_download_whitelist ? new SafeBrowsingStoreFile : NULL,
328 enable_extension_blacklist ? new SafeBrowsingStoreFile : NULL, 332 enable_extension_blacklist ? new SafeBrowsingStoreFile : NULL,
329 enable_side_effect_free_whitelist ? new SafeBrowsingStoreFile : NULL, 333 enable_side_effect_free_whitelist ? new SafeBrowsingStoreFile : NULL,
330 enable_ip_blacklist ? new SafeBrowsingStoreFile : NULL); 334 enable_ip_blacklist ? new SafeBrowsingStoreFile : NULL,
335 enable_unwanted_software_list ? new SafeBrowsingStoreFile : NULL);
331 } 336 }
332 337
333 SafeBrowsingDatabaseFactoryImpl() { } 338 SafeBrowsingDatabaseFactoryImpl() { }
334 339
335 private: 340 private:
336 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl); 341 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl);
337 }; 342 };
338 343
339 // static 344 // static
340 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL; 345 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL;
341 346
342 // Factory method, non-thread safe. Caller has to make sure this s called 347 // Factory method, non-thread safe. Caller has to make sure this s called
343 // on SafeBrowsing Thread. 348 // on SafeBrowsing Thread.
344 // TODO(shess): There's no need for a factory any longer. Convert 349 // TODO(shess): There's no need for a factory any longer. Convert
345 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create() 350 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create()
346 // callers just construct things directly. 351 // callers just construct things directly.
347 SafeBrowsingDatabase* SafeBrowsingDatabase::Create( 352 SafeBrowsingDatabase* SafeBrowsingDatabase::Create(
348 bool enable_download_protection, 353 bool enable_download_protection,
349 bool enable_client_side_whitelist, 354 bool enable_client_side_whitelist,
350 bool enable_download_whitelist, 355 bool enable_download_whitelist,
351 bool enable_extension_blacklist, 356 bool enable_extension_blacklist,
352 bool enable_side_effect_free_whitelist, 357 bool enable_side_effect_free_whitelist,
353 bool enable_ip_blacklist) { 358 bool enable_ip_blacklist,
359 bool enable_unwanted_software_list) {
354 if (!factory_) 360 if (!factory_)
355 factory_ = new SafeBrowsingDatabaseFactoryImpl(); 361 factory_ = new SafeBrowsingDatabaseFactoryImpl();
356 return factory_->CreateSafeBrowsingDatabase( 362 return factory_->CreateSafeBrowsingDatabase(enable_download_protection,
357 enable_download_protection, 363 enable_client_side_whitelist,
358 enable_client_side_whitelist, 364 enable_download_whitelist,
359 enable_download_whitelist, 365 enable_extension_blacklist,
360 enable_extension_blacklist, 366 enable_side_effect_free_whitelist,
361 enable_side_effect_free_whitelist, 367 enable_ip_blacklist,
362 enable_ip_blacklist); 368 enable_unwanted_software_list);
363 } 369 }
364 370
365 SafeBrowsingDatabase::~SafeBrowsingDatabase() { 371 SafeBrowsingDatabase::~SafeBrowsingDatabase() {
366 } 372 }
367 373
368 // static 374 // static
369 base::FilePath SafeBrowsingDatabase::BrowseDBFilename( 375 base::FilePath SafeBrowsingDatabase::BrowseDBFilename(
370 const base::FilePath& db_base_filename) { 376 const base::FilePath& db_base_filename) {
371 return base::FilePath(db_base_filename.value() + kBrowseDBFile); 377 return base::FilePath(db_base_filename.value() + kBrowseDBFile);
372 } 378 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 const base::FilePath& db_filename) { 418 const base::FilePath& db_filename) {
413 return base::FilePath(db_filename.value() + kSideEffectFreeWhitelistDBFile); 419 return base::FilePath(db_filename.value() + kSideEffectFreeWhitelistDBFile);
414 } 420 }
415 421
416 // static 422 // static
417 base::FilePath SafeBrowsingDatabase::IpBlacklistDBFilename( 423 base::FilePath SafeBrowsingDatabase::IpBlacklistDBFilename(
418 const base::FilePath& db_filename) { 424 const base::FilePath& db_filename) {
419 return base::FilePath(db_filename.value() + kIPBlacklistDBFile); 425 return base::FilePath(db_filename.value() + kIPBlacklistDBFile);
420 } 426 }
421 427
428 // static
429 base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename(
430 const base::FilePath& db_filename) {
431 return base::FilePath(db_filename.value() + kUnwantedSoftwareDBFile);
432 }
433
422 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { 434 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) {
423 if (list_id == safe_browsing_util::PHISH || 435 if (list_id == safe_browsing_util::PHISH ||
424 list_id == safe_browsing_util::MALWARE) { 436 list_id == safe_browsing_util::MALWARE) {
425 return browse_store_.get(); 437 return browse_store_.get();
426 } else if (list_id == safe_browsing_util::BINURL) { 438 } else if (list_id == safe_browsing_util::BINURL) {
427 return download_store_.get(); 439 return download_store_.get();
428 } else if (list_id == safe_browsing_util::CSDWHITELIST) { 440 } else if (list_id == safe_browsing_util::CSDWHITELIST) {
429 return csd_whitelist_store_.get(); 441 return csd_whitelist_store_.get();
430 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) { 442 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) {
431 return download_whitelist_store_.get(); 443 return download_whitelist_store_.get();
432 } else if (list_id == safe_browsing_util::EXTENSIONBLACKLIST) { 444 } else if (list_id == safe_browsing_util::EXTENSIONBLACKLIST) {
433 return extension_blacklist_store_.get(); 445 return extension_blacklist_store_.get();
434 } else if (list_id == safe_browsing_util::SIDEEFFECTFREEWHITELIST) { 446 } else if (list_id == safe_browsing_util::SIDEEFFECTFREEWHITELIST) {
435 return side_effect_free_whitelist_store_.get(); 447 return side_effect_free_whitelist_store_.get();
436 } else if (list_id == safe_browsing_util::IPBLACKLIST) { 448 } else if (list_id == safe_browsing_util::IPBLACKLIST) {
437 return ip_blacklist_store_.get(); 449 return ip_blacklist_store_.get();
450 } else if (list_id == safe_browsing_util::UNWANTEDURL) {
451 return unwanted_software_store_.get();
438 } 452 }
439 return NULL; 453 return NULL;
440 } 454 }
441 455
442 // static 456 // static
443 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) { 457 void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) {
444 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type, 458 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type,
445 FAILURE_DATABASE_MAX); 459 FAILURE_DATABASE_MAX);
446 } 460 }
447 461
448 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew() 462 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
449 : creation_loop_(base::MessageLoop::current()), 463 : creation_loop_(base::MessageLoop::current()),
450 browse_store_(new SafeBrowsingStoreFile), 464 browse_store_(new SafeBrowsingStoreFile),
451 corruption_detected_(false), 465 corruption_detected_(false),
452 change_detected_(false), 466 change_detected_(false),
453 reset_factory_(this) { 467 reset_factory_(this) {
454 DCHECK(browse_store_.get()); 468 DCHECK(browse_store_.get());
455 DCHECK(!download_store_.get()); 469 DCHECK(!download_store_.get());
456 DCHECK(!csd_whitelist_store_.get()); 470 DCHECK(!csd_whitelist_store_.get());
457 DCHECK(!download_whitelist_store_.get()); 471 DCHECK(!download_whitelist_store_.get());
458 DCHECK(!extension_blacklist_store_.get()); 472 DCHECK(!extension_blacklist_store_.get());
459 DCHECK(!side_effect_free_whitelist_store_.get()); 473 DCHECK(!side_effect_free_whitelist_store_.get());
460 DCHECK(!ip_blacklist_store_.get()); 474 DCHECK(!ip_blacklist_store_.get());
475 DCHECK(!unwanted_software_store_.get());
461 } 476 }
462 477
463 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( 478 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew(
464 SafeBrowsingStore* browse_store, 479 SafeBrowsingStore* browse_store,
465 SafeBrowsingStore* download_store, 480 SafeBrowsingStore* download_store,
466 SafeBrowsingStore* csd_whitelist_store, 481 SafeBrowsingStore* csd_whitelist_store,
467 SafeBrowsingStore* download_whitelist_store, 482 SafeBrowsingStore* download_whitelist_store,
468 SafeBrowsingStore* extension_blacklist_store, 483 SafeBrowsingStore* extension_blacklist_store,
469 SafeBrowsingStore* side_effect_free_whitelist_store, 484 SafeBrowsingStore* side_effect_free_whitelist_store,
470 SafeBrowsingStore* ip_blacklist_store) 485 SafeBrowsingStore* ip_blacklist_store,
486 SafeBrowsingStore* unwanted_software_store)
471 : creation_loop_(base::MessageLoop::current()), 487 : creation_loop_(base::MessageLoop::current()),
472 browse_store_(browse_store), 488 browse_store_(browse_store),
473 download_store_(download_store), 489 download_store_(download_store),
474 csd_whitelist_store_(csd_whitelist_store), 490 csd_whitelist_store_(csd_whitelist_store),
475 download_whitelist_store_(download_whitelist_store), 491 download_whitelist_store_(download_whitelist_store),
476 extension_blacklist_store_(extension_blacklist_store), 492 extension_blacklist_store_(extension_blacklist_store),
477 side_effect_free_whitelist_store_(side_effect_free_whitelist_store), 493 side_effect_free_whitelist_store_(side_effect_free_whitelist_store),
478 ip_blacklist_store_(ip_blacklist_store), 494 ip_blacklist_store_(ip_blacklist_store),
495 unwanted_software_store_(unwanted_software_store),
479 corruption_detected_(false), 496 corruption_detected_(false),
480 reset_factory_(this) { 497 reset_factory_(this) {
481 DCHECK(browse_store_.get()); 498 DCHECK(browse_store_.get());
482 } 499 }
483 500
484 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { 501 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() {
485 // The DCHECK is disabled due to crbug.com/338486 . 502 // The DCHECK is disabled due to crbug.com/338486 .
486 // DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 503 // DCHECK_EQ(creation_loop_, base::MessageLoop::current());
487 } 504 }
488 505
489 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { 506 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) {
490 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 507 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
491 508
492 // This should not be run multiple times. 509 // This should not be run multiple times.
493 DCHECK(filename_base_.empty()); 510 DCHECK(filename_base_.empty());
494 511
495 filename_base_ = filename_base; 512 filename_base_ = filename_base;
496 513
497 // TODO(shess): The various stores are really only necessary while doing 514 // TODO(shess): The various stores are really only necessary while doing
498 // updates, or when querying a store directly (see |ContainsDownloadUrl()|). 515 // updates (see |UpdateFinished()|) or when querying a store directly (see
516 // |ContainsDownloadUrl()|).
499 // The store variables are also tested to see if a list is enabled. Perhaps 517 // The store variables are also tested to see if a list is enabled. Perhaps
500 // the stores could be refactored into an update object so that they are only 518 // the stores could be refactored into an update object so that they are only
501 // live in memory while being actively used. The sense of enabled probably 519 // live in memory while being actively used. The sense of enabled probably
502 // belongs in protocol_manager or database_manager. 520 // belongs in protocol_manager or database_manager.
503 521
504 browse_store_->Init( 522 browse_store_->Init(
505 BrowseDBFilename(filename_base_), 523 BrowseDBFilename(filename_base_),
506 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 524 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
507 base::Unretained(this))); 525 base::Unretained(this)));
508 526
527 if (unwanted_software_store_.get()) {
528 unwanted_software_store_->Init(
529 UnwantedSoftwareDBFilename(filename_base_),
530 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
531 base::Unretained(this)));
532 }
533
509 { 534 {
510 // NOTE: There is no need to grab the lock in this function, since 535 // NOTE: There is no need to grab the lock in this function, since
511 // until it returns, there are no pointers to this class on other 536 // until it returns, there are no pointers to this class on other
512 // threads. Then again, that means there is no possibility of 537 // threads. Then again, that means there is no possibility of
513 // contention on the lock... 538 // contention on the lock...
514 base::AutoLock locked(lookup_lock_); 539 base::AutoLock locked(lookup_lock_);
515 browse_gethash_cache_.clear(); 540 prefix_gethash_cache_.clear();
516 LoadPrefixSet(); 541 LoadPrefixSet(BrowseDBFilename(filename_base_),
542 &browse_prefix_set_,
543 FAILURE_BROWSE_PREFIX_SET_READ);
544 if (unwanted_software_store_.get()) {
545 LoadPrefixSet(UnwantedSoftwareDBFilename(filename_base_),
546 &unwanted_software_prefix_set_,
547 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_READ);
548 }
517 } 549 }
518 550
519 if (download_store_.get()) { 551 if (download_store_.get()) {
520 download_store_->Init( 552 download_store_->Init(
521 DownloadDBFilename(filename_base_), 553 DownloadDBFilename(filename_base_),
522 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 554 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
523 base::Unretained(this))); 555 base::Unretained(this)));
524 } 556 }
525 557
526 if (csd_whitelist_store_.get()) { 558 if (csd_whitelist_store_.get()) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 645
614 // Delete files on disk. 646 // Delete files on disk.
615 // TODO(shess): Hard to see where one might want to delete without a 647 // TODO(shess): Hard to see where one might want to delete without a
616 // reset. Perhaps inline |Delete()|? 648 // reset. Perhaps inline |Delete()|?
617 if (!Delete()) 649 if (!Delete())
618 return false; 650 return false;
619 651
620 // Reset objects in memory. 652 // Reset objects in memory.
621 { 653 {
622 base::AutoLock locked(lookup_lock_); 654 base::AutoLock locked(lookup_lock_);
623 browse_gethash_cache_.clear(); 655 prefix_gethash_cache_.clear();
624 browse_prefix_set_.reset(); 656 browse_prefix_set_.reset();
625 side_effect_free_whitelist_prefix_set_.reset(); 657 side_effect_free_whitelist_prefix_set_.reset();
626 ip_blacklist_.clear(); 658 ip_blacklist_.clear();
659 unwanted_software_prefix_set_.reset();
627 } 660 }
628 // Wants to acquire the lock itself. 661 // Wants to acquire the lock itself.
629 WhitelistEverything(&csd_whitelist_); 662 WhitelistEverything(&csd_whitelist_);
630 WhitelistEverything(&download_whitelist_); 663 WhitelistEverything(&download_whitelist_);
631 return true; 664 return true;
632 } 665 }
633 666
634 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( 667 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl(
635 const GURL& url, 668 const GURL& url,
636 std::vector<SBPrefix>* prefix_hits, 669 std::vector<SBPrefix>* prefix_hits,
637 std::vector<SBFullHashResult>* cache_hits) { 670 std::vector<SBFullHashResult>* cache_hits) {
671 return PrefixSetContainsUrl(
672 url, &browse_prefix_set_, prefix_hits, cache_hits);
673 }
674
675 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl(
676 const GURL& url,
677 std::vector<SBPrefix>* prefix_hits,
678 std::vector<SBFullHashResult>* cache_hits) {
679 return PrefixSetContainsUrl(
680 url, &unwanted_software_prefix_set_, prefix_hits, cache_hits);
681 }
682
683 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl(
684 const GURL& url,
685 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter,
686 std::vector<SBPrefix>* prefix_hits,
687 std::vector<SBFullHashResult>* cache_hits) {
638 // Clear the results first. 688 // Clear the results first.
639 prefix_hits->clear(); 689 prefix_hits->clear();
640 cache_hits->clear(); 690 cache_hits->clear();
641 691
642 std::vector<SBFullHash> full_hashes; 692 std::vector<SBFullHash> full_hashes;
643 BrowseFullHashesToCheck(url, false, &full_hashes); 693 UrlToFullHashes(url, false, &full_hashes);
644 if (full_hashes.empty()) 694 if (full_hashes.empty())
645 return false; 695 return false;
646 696
647 return ContainsBrowseUrlHashes(full_hashes, prefix_hits, cache_hits); 697 return PrefixSetContainsUrlHashes(
698 full_hashes, prefix_set_getter, prefix_hits, cache_hits);
648 } 699 }
649 700
650 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashes( 701 bool SafeBrowsingDatabaseNew::ContainsBrowseUrlHashesForTesting(
651 const std::vector<SBFullHash>& full_hashes, 702 const std::vector<SBFullHash>& full_hashes,
652 std::vector<SBPrefix>* prefix_hits, 703 std::vector<SBPrefix>* prefix_hits,
653 std::vector<SBFullHashResult>* cache_hits) { 704 std::vector<SBFullHashResult>* cache_hits) {
705 return PrefixSetContainsUrlHashes(
706 full_hashes, &browse_prefix_set_, prefix_hits, cache_hits);
707 }
708
709 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes(
710 const std::vector<SBFullHash>& full_hashes,
711 scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter,
712 std::vector<SBPrefix>* prefix_hits,
713 std::vector<SBFullHashResult>* cache_hits) {
654 // Used to determine cache expiration. 714 // Used to determine cache expiration.
655 const base::Time now = base::Time::Now(); 715 const base::Time now = base::Time::Now();
656 716
657 // This function is called on the I/O thread, prevent changes to 717 // This function is called on the I/O thread, prevent changes to
658 // filter and caches. 718 // filter and caches.
659 base::AutoLock locked(lookup_lock_); 719 base::AutoLock locked(lookup_lock_);
660 720
661 // |browse_prefix_set_| is empty until it is either read from disk, or the 721 // |prefix_set| is empty until it is either read from disk, or the first
662 // first update populates it. Bail out without a hit if not yet 722 // update populates it. Bail out without a hit if not yet available.
663 // available. 723 // |prefix_set_getter| can only be accessed while holding |lookup_lock_| hence
664 if (!browse_prefix_set_.get()) 724 // why it is passed as a parameter rather than passing the |prefix_set|
725 // directly.
726 safe_browsing::PrefixSet* prefix_set = prefix_set_getter->get();
727 if (!prefix_set)
665 return false; 728 return false;
666 729
667 for (size_t i = 0; i < full_hashes.size(); ++i) { 730 for (size_t i = 0; i < full_hashes.size(); ++i) {
668 if (!GetCachedFullHash(&browse_gethash_cache_, 731 if (!GetCachedFullHash(
669 full_hashes[i], 732 &prefix_gethash_cache_, full_hashes[i], now, cache_hits)) {
670 now,
671 cache_hits)) {
672 // No valid cached result, check the database. 733 // No valid cached result, check the database.
673 if (browse_prefix_set_->Exists(full_hashes[i])) 734 if (prefix_set->Exists(full_hashes[i]))
674 prefix_hits->push_back(full_hashes[i].prefix); 735 prefix_hits->push_back(full_hashes[i].prefix);
675 } 736 }
676 } 737 }
677 738
678 // Multiple full hashes could share prefix, remove duplicates. 739 // Multiple full hashes could share prefix, remove duplicates.
679 std::sort(prefix_hits->begin(), prefix_hits->end()); 740 std::sort(prefix_hits->begin(), prefix_hits->end());
680 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), 741 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()),
681 prefix_hits->end()); 742 prefix_hits->end());
682 743
683 return !prefix_hits->empty() || !cache_hits->empty(); 744 return !prefix_hits->empty() || !cache_hits->empty();
(...skipping 14 matching lines...) Expand all
698 safe_browsing_util::BINURL % 2, 759 safe_browsing_util::BINURL % 2,
699 prefixes, 760 prefixes,
700 prefix_hits); 761 prefix_hits);
701 } 762 }
702 763
703 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { 764 bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) {
704 // This method is theoretically thread-safe but we expect all calls to 765 // This method is theoretically thread-safe but we expect all calls to
705 // originate from the IO thread. 766 // originate from the IO thread.
706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 767 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
707 std::vector<SBFullHash> full_hashes; 768 std::vector<SBFullHash> full_hashes;
708 BrowseFullHashesToCheck(url, true, &full_hashes); 769 UrlToFullHashes(url, true, &full_hashes);
709 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 770 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
710 } 771 }
711 772
712 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { 773 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) {
713 std::vector<SBFullHash> full_hashes; 774 std::vector<SBFullHash> full_hashes;
714 BrowseFullHashesToCheck(url, true, &full_hashes); 775 UrlToFullHashes(url, true, &full_hashes);
715 return ContainsWhitelistedHashes(download_whitelist_, full_hashes); 776 return ContainsWhitelistedHashes(download_whitelist_, full_hashes);
716 } 777 }
717 778
718 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( 779 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes(
719 const std::vector<SBPrefix>& prefixes, 780 const std::vector<SBPrefix>& prefixes,
720 std::vector<SBPrefix>* prefix_hits) { 781 std::vector<SBPrefix>* prefix_hits) {
721 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 782 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
722 if (!extension_blacklist_store_) 783 if (!extension_blacklist_store_)
723 return false; 784 return false;
724 785
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 const std::vector<SBPrefix>& prefixes, 1005 const std::vector<SBPrefix>& prefixes,
945 const std::vector<SBFullHashResult>& full_hits, 1006 const std::vector<SBFullHashResult>& full_hits,
946 const base::TimeDelta& cache_lifetime) { 1007 const base::TimeDelta& cache_lifetime) {
947 const base::Time expire_after = base::Time::Now() + cache_lifetime; 1008 const base::Time expire_after = base::Time::Now() + cache_lifetime;
948 1009
949 // This is called on the I/O thread, lock against updates. 1010 // This is called on the I/O thread, lock against updates.
950 base::AutoLock locked(lookup_lock_); 1011 base::AutoLock locked(lookup_lock_);
951 1012
952 // Create or reset all cached results for these prefixes. 1013 // Create or reset all cached results for these prefixes.
953 for (size_t i = 0; i < prefixes.size(); ++i) { 1014 for (size_t i = 0; i < prefixes.size(); ++i) {
954 browse_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after); 1015 prefix_gethash_cache_[prefixes[i]] = SBCachedFullHashResult(expire_after);
955 } 1016 }
956 1017
957 // Insert any fullhash hits. Note that there may be one, multiple, or no 1018 // Insert any fullhash hits. Note that there may be one, multiple, or no
958 // fullhashes for any given entry in |prefixes|. 1019 // fullhashes for any given entry in |prefixes|.
959 for (size_t i = 0; i < full_hits.size(); ++i) { 1020 for (size_t i = 0; i < full_hits.size(); ++i) {
960 const SBPrefix prefix = full_hits[i].hash.prefix; 1021 const SBPrefix prefix = full_hits[i].hash.prefix;
961 browse_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]); 1022 prefix_gethash_cache_[prefix].full_hashes.push_back(full_hits[i]);
962 } 1023 }
963 } 1024 }
964 1025
965 bool SafeBrowsingDatabaseNew::UpdateStarted( 1026 bool SafeBrowsingDatabaseNew::UpdateStarted(
966 std::vector<SBListChunkRanges>* lists) { 1027 std::vector<SBListChunkRanges>* lists) {
967 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1028 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
968 DCHECK(lists); 1029 DCHECK(lists);
969 1030
970 // If |BeginUpdate()| fails, reset the database. 1031 // If |BeginUpdate()| fails, reset the database.
971 if (!browse_store_->BeginUpdate()) { 1032 if (!browse_store_->BeginUpdate()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 HandleCorruptDatabase(); 1067 HandleCorruptDatabase();
1007 return false; 1068 return false;
1008 } 1069 }
1009 1070
1010 if (ip_blacklist_store_ && !ip_blacklist_store_->BeginUpdate()) { 1071 if (ip_blacklist_store_ && !ip_blacklist_store_->BeginUpdate()) {
1011 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_BEGIN); 1072 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_BEGIN);
1012 HandleCorruptDatabase(); 1073 HandleCorruptDatabase();
1013 return false; 1074 return false;
1014 } 1075 }
1015 1076
1077 if (unwanted_software_store_ && !unwanted_software_store_->BeginUpdate()) {
1078 RecordFailure(FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_BEGIN);
1079 HandleCorruptDatabase();
1080 return false;
1081 }
1082
1016 { 1083 {
1017 base::AutoLock locked(lookup_lock_); 1084 base::AutoLock locked(lookup_lock_);
1018 // Cached fullhash results must be cleared on every database update (whether 1085 // Cached fullhash results must be cleared on every database update (whether
1019 // successful or not.) 1086 // successful or not.)
1020 browse_gethash_cache_.clear(); 1087 prefix_gethash_cache_.clear();
1021 } 1088 }
1022 1089
1023 UpdateChunkRangesForLists(browse_store_.get(), 1090 UpdateChunkRangesForLists(browse_store_.get(),
1024 safe_browsing_util::kMalwareList, 1091 safe_browsing_util::kMalwareList,
1025 safe_browsing_util::kPhishingList, 1092 safe_browsing_util::kPhishingList,
1026 lists); 1093 lists);
1027 1094
1028 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been 1095 // NOTE(shess): |download_store_| used to contain kBinHashList, which has been
1029 // deprecated. Code to delete the list from the store shows ~15k hits/day as 1096 // deprecated. Code to delete the list from the store shows ~15k hits/day as
1030 // of Feb 2014, so it has been removed. Everything _should_ be resilient to 1097 // of Feb 2014, so it has been removed. Everything _should_ be resilient to
1031 // extra data of that sort. 1098 // extra data of that sort.
1032 UpdateChunkRangesForList(download_store_.get(), 1099 UpdateChunkRangesForList(download_store_.get(),
1033 safe_browsing_util::kBinUrlList, lists); 1100 safe_browsing_util::kBinUrlList, lists);
1034 1101
1035 UpdateChunkRangesForList(csd_whitelist_store_.get(), 1102 UpdateChunkRangesForList(csd_whitelist_store_.get(),
1036 safe_browsing_util::kCsdWhiteList, lists); 1103 safe_browsing_util::kCsdWhiteList, lists);
1037 1104
1038 UpdateChunkRangesForList(download_whitelist_store_.get(), 1105 UpdateChunkRangesForList(download_whitelist_store_.get(),
1039 safe_browsing_util::kDownloadWhiteList, lists); 1106 safe_browsing_util::kDownloadWhiteList, lists);
1040 1107
1041 UpdateChunkRangesForList(extension_blacklist_store_.get(), 1108 UpdateChunkRangesForList(extension_blacklist_store_.get(),
1042 safe_browsing_util::kExtensionBlacklist, lists); 1109 safe_browsing_util::kExtensionBlacklist, lists);
1043 1110
1044 UpdateChunkRangesForList(side_effect_free_whitelist_store_.get(), 1111 UpdateChunkRangesForList(side_effect_free_whitelist_store_.get(),
1045 safe_browsing_util::kSideEffectFreeWhitelist, lists); 1112 safe_browsing_util::kSideEffectFreeWhitelist, lists);
1046 1113
1047 UpdateChunkRangesForList(ip_blacklist_store_.get(), 1114 UpdateChunkRangesForList(ip_blacklist_store_.get(),
1048 safe_browsing_util::kIPBlacklist, lists); 1115 safe_browsing_util::kIPBlacklist, lists);
1049 1116
1117 UpdateChunkRangesForList(unwanted_software_store_.get(),
1118 safe_browsing_util::kUnwantedUrlList,
1119 lists);
1120
1050 corruption_detected_ = false; 1121 corruption_detected_ = false;
1051 change_detected_ = false; 1122 change_detected_ = false;
1052 return true; 1123 return true;
1053 } 1124 }
1054 1125
1055 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { 1126 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) {
1056 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1127 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
1057 1128
1058 // The update may have failed due to corrupt storage (for instance, 1129 // The update may have failed due to corrupt storage (for instance,
1059 // an excessive number of invalid add_chunks and sub_chunks). 1130 // an excessive number of invalid add_chunks and sub_chunks).
(...skipping 23 matching lines...) Expand all
1083 1154
1084 if (side_effect_free_whitelist_store_ && 1155 if (side_effect_free_whitelist_store_ &&
1085 !side_effect_free_whitelist_store_->CheckValidity()) { 1156 !side_effect_free_whitelist_store_->CheckValidity()) {
1086 DLOG(ERROR) << "Safe-browsing side-effect free whitelist database " 1157 DLOG(ERROR) << "Safe-browsing side-effect free whitelist database "
1087 << "corrupt."; 1158 << "corrupt.";
1088 } 1159 }
1089 1160
1090 if (ip_blacklist_store_ && !ip_blacklist_store_->CheckValidity()) { 1161 if (ip_blacklist_store_ && !ip_blacklist_store_->CheckValidity()) {
1091 DLOG(ERROR) << "Safe-browsing IP blacklist database corrupt."; 1162 DLOG(ERROR) << "Safe-browsing IP blacklist database corrupt.";
1092 } 1163 }
1164
1165 if (unwanted_software_store_ &&
1166 !unwanted_software_store_->CheckValidity()) {
1167 DLOG(ERROR) << "Unwanted software url list database corrupt.";
1168 }
1093 } 1169 }
1094 1170
1095 if (corruption_detected_) 1171 if (corruption_detected_)
1096 return; 1172 return;
1097 1173
1098 // Unroll the transaction if there was a protocol error or if the 1174 // Unroll the transaction if there was a protocol error or if the
1099 // transaction was empty. This will leave the prefix set, the 1175 // transaction was empty. This will leave the prefix set, the
1100 // pending hashes, and the prefix miss cache in place. 1176 // pending hashes, and the prefix miss cache in place.
1101 if (!update_succeeded || !change_detected_) { 1177 if (!update_succeeded || !change_detected_) {
1102 // Track empty updates to answer questions at http://crbug.com/72216 . 1178 // Track empty updates to answer questions at http://crbug.com/72216 .
1103 if (update_succeeded && !change_detected_) 1179 if (update_succeeded && !change_detected_)
1104 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0); 1180 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", 0);
1105 browse_store_->CancelUpdate(); 1181 browse_store_->CancelUpdate();
1106 if (download_store_.get()) 1182 if (download_store_.get())
1107 download_store_->CancelUpdate(); 1183 download_store_->CancelUpdate();
1108 if (csd_whitelist_store_.get()) 1184 if (csd_whitelist_store_.get())
1109 csd_whitelist_store_->CancelUpdate(); 1185 csd_whitelist_store_->CancelUpdate();
1110 if (download_whitelist_store_.get()) 1186 if (download_whitelist_store_.get())
1111 download_whitelist_store_->CancelUpdate(); 1187 download_whitelist_store_->CancelUpdate();
1112 if (extension_blacklist_store_) 1188 if (extension_blacklist_store_)
1113 extension_blacklist_store_->CancelUpdate(); 1189 extension_blacklist_store_->CancelUpdate();
1114 if (side_effect_free_whitelist_store_) 1190 if (side_effect_free_whitelist_store_)
1115 side_effect_free_whitelist_store_->CancelUpdate(); 1191 side_effect_free_whitelist_store_->CancelUpdate();
1116 if (ip_blacklist_store_) 1192 if (ip_blacklist_store_)
1117 ip_blacklist_store_->CancelUpdate(); 1193 ip_blacklist_store_->CancelUpdate();
1194 if (unwanted_software_store_)
1195 unwanted_software_store_->CancelUpdate();
1118 return; 1196 return;
1119 } 1197 }
1120 1198
1121 if (download_store_) { 1199 if (download_store_) {
1122 int64 size_bytes = UpdateHashPrefixStore( 1200 int64 size_bytes = UpdateHashPrefixStore(
1123 DownloadDBFilename(filename_base_), 1201 DownloadDBFilename(filename_base_),
1124 download_store_.get(), 1202 download_store_.get(),
1125 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); 1203 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH);
1126 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes", 1204 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes",
1127 static_cast<int>(size_bytes / 1024)); 1205 static_cast<int>(size_bytes / 1024));
1128 } 1206 }
1129 1207
1130 UpdateBrowseStore(); 1208 UpdatePrefixSetUrlStore(BrowseDBFilename(filename_base_),
1209 browse_store_.get(),
1210 &browse_prefix_set_,
1211 FAILURE_BROWSE_DATABASE_UPDATE_FINISH,
1212 FAILURE_BROWSE_PREFIX_SET_WRITE);
1213
1131 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_), 1214 UpdateWhitelistStore(CsdWhitelistDBFilename(filename_base_),
1132 csd_whitelist_store_.get(), 1215 csd_whitelist_store_.get(),
1133 &csd_whitelist_); 1216 &csd_whitelist_);
1134 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_), 1217 UpdateWhitelistStore(DownloadWhitelistDBFilename(filename_base_),
1135 download_whitelist_store_.get(), 1218 download_whitelist_store_.get(),
1136 &download_whitelist_); 1219 &download_whitelist_);
1137 1220
1138 if (extension_blacklist_store_) { 1221 if (extension_blacklist_store_) {
1139 int64 size_bytes = UpdateHashPrefixStore( 1222 int64 size_bytes = UpdateHashPrefixStore(
1140 ExtensionBlacklistDBFilename(filename_base_), 1223 ExtensionBlacklistDBFilename(filename_base_),
1141 extension_blacklist_store_.get(), 1224 extension_blacklist_store_.get(),
1142 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH); 1225 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH);
1143 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes", 1226 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes",
1144 static_cast<int>(size_bytes / 1024)); 1227 static_cast<int>(size_bytes / 1024));
1145 } 1228 }
1146 1229
1147 if (side_effect_free_whitelist_store_) 1230 if (side_effect_free_whitelist_store_)
1148 UpdateSideEffectFreeWhitelistStore(); 1231 UpdateSideEffectFreeWhitelistStore();
1149 1232
1150 if (ip_blacklist_store_) 1233 if (ip_blacklist_store_)
1151 UpdateIpBlacklistStore(); 1234 UpdateIpBlacklistStore();
1235
1236 if (unwanted_software_store_) {
1237 UpdatePrefixSetUrlStore(UnwantedSoftwareDBFilename(filename_base_),
1238 unwanted_software_store_.get(),
1239 &unwanted_software_prefix_set_,
1240 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH,
1241 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE);
1242 }
1152 } 1243 }
1153 1244
1154 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( 1245 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1155 const base::FilePath& store_filename, 1246 const base::FilePath& store_filename,
1156 SafeBrowsingStore* store, 1247 SafeBrowsingStore* store,
1157 SBWhitelist* whitelist) { 1248 SBWhitelist* whitelist) {
1158 if (!store) 1249 if (!store)
1159 return; 1250 return;
1160 1251
1161 // Note: |builder| will not be empty. The current data store implementation 1252 // Note: |builder| will not be empty. The current data store implementation
(...skipping 25 matching lines...) Expand all
1187 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) 1278 if (!store->FinishUpdate(&builder, &add_full_hashes_result))
1188 RecordFailure(failure_type); 1279 RecordFailure(failure_type);
1189 1280
1190 #if defined(OS_MACOSX) 1281 #if defined(OS_MACOSX)
1191 base::mac::SetFileBackupExclusion(store_filename); 1282 base::mac::SetFileBackupExclusion(store_filename);
1192 #endif 1283 #endif
1193 1284
1194 return GetFileSizeOrZero(store_filename); 1285 return GetFileSizeOrZero(store_filename);
1195 } 1286 }
1196 1287
1197 void SafeBrowsingDatabaseNew::UpdateBrowseStore() { 1288 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore(
1289 const base::FilePath& db_filename,
1290 SafeBrowsingStore* url_store,
1291 scoped_ptr<safe_browsing::PrefixSet>* prefix_set,
1292 FailureType finish_failure_type,
1293 FailureType write_failure_type) {
1198 // Measure the amount of IO during the filter build. 1294 // Measure the amount of IO during the filter build.
1199 base::IoCounters io_before, io_after; 1295 base::IoCounters io_before, io_after;
1200 base::ProcessHandle handle = base::GetCurrentProcessHandle(); 1296 base::ProcessHandle handle = base::GetCurrentProcessHandle();
1201 scoped_ptr<base::ProcessMetrics> metric( 1297 scoped_ptr<base::ProcessMetrics> metric(
1202 #if !defined(OS_MACOSX) 1298 #if !defined(OS_MACOSX)
1203 base::ProcessMetrics::CreateProcessMetrics(handle) 1299 base::ProcessMetrics::CreateProcessMetrics(handle)
1204 #else 1300 #else
1205 // Getting stats only for the current process is enough, so NULL is fine. 1301 // Getting stats only for the current process is enough, so NULL is fine.
1206 base::ProcessMetrics::CreateProcessMetrics(handle, NULL) 1302 base::ProcessMetrics::CreateProcessMetrics(handle, NULL)
1207 #endif 1303 #endif
1208 ); 1304 );
1209 1305
1210 // IoCounters are currently not supported on Mac, and may not be 1306 // IoCounters are currently not supported on Mac, and may not be
1211 // available for Linux, so we check the result and only show IO 1307 // available for Linux, so we check the result and only show IO
1212 // stats if they are available. 1308 // stats if they are available.
1213 const bool got_counters = metric->GetIOCounters(&io_before); 1309 const bool got_counters = metric->GetIOCounters(&io_before);
1214 1310
1215 const base::TimeTicks before = base::TimeTicks::Now(); 1311 const base::TimeTicks before = base::TimeTicks::Now();
1216 1312
1217 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the 1313 // TODO(shess): Perhaps refactor to let builder accumulate full hashes on the
1218 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use 1314 // fly? Other clients use the SBAddFullHash vector, but AFAICT they only use
1219 // the SBFullHash portion. It would need an accessor on PrefixSet. 1315 // the SBFullHash portion. It would need an accessor on PrefixSet.
1220 safe_browsing::PrefixSetBuilder builder; 1316 safe_browsing::PrefixSetBuilder builder;
1221 std::vector<SBAddFullHash> add_full_hashes; 1317 std::vector<SBAddFullHash> add_full_hashes;
1222 if (!browse_store_->FinishUpdate(&builder, &add_full_hashes)) { 1318 if (!url_store->FinishUpdate(&builder, &add_full_hashes)) {
1223 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_FINISH); 1319 RecordFailure(finish_failure_type);
1224 return; 1320 return;
1225 } 1321 }
1226 1322
1227 std::vector<SBFullHash> full_hash_results; 1323 std::vector<SBFullHash> full_hash_results;
1228 for (size_t i = 0; i < add_full_hashes.size(); ++i) { 1324 for (size_t i = 0; i < add_full_hashes.size(); ++i) {
1229 full_hash_results.push_back(add_full_hashes[i].full_hash); 1325 full_hash_results.push_back(add_full_hashes[i].full_hash);
1230 } 1326 }
1231 1327
1232 scoped_ptr<safe_browsing::PrefixSet> 1328 scoped_ptr<safe_browsing::PrefixSet> new_prefix_set(
1233 prefix_set(builder.GetPrefixSet(full_hash_results)); 1329 builder.GetPrefixSet(full_hash_results));
1234 1330
1235 // Swap in the newly built filter. 1331 // Swap in the newly built filter.
1236 { 1332 {
1237 base::AutoLock locked(lookup_lock_); 1333 base::AutoLock locked(lookup_lock_);
1238 browse_prefix_set_.swap(prefix_set); 1334 prefix_set->swap(new_prefix_set);
1239 } 1335 }
1240 1336
1241 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before); 1337 UMA_HISTOGRAM_LONG_TIMES("SB2.BuildFilter", base::TimeTicks::Now() - before);
1242 1338
1243 // Persist the prefix set to disk. Since only this thread changes 1339 // Persist the prefix set to disk. Note: there is no need to lock since the
1244 // |browse_prefix_set_|, there is no need to lock. 1340 // only write to |*prefix_set| is on this thread (in the swap() above).
1245 WritePrefixSet(); 1341 // TODO(gab): Strengthen this requirement by design (const pointers) rather
1342 // than assumptions.
1343 WritePrefixSet(db_filename, prefix_set->get(), write_failure_type);
1246 1344
1247 // Gather statistics. 1345 // Gather statistics.
1248 if (got_counters && metric->GetIOCounters(&io_after)) { 1346 if (got_counters && metric->GetIOCounters(&io_after)) {
1249 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes", 1347 UMA_HISTOGRAM_COUNTS("SB2.BuildReadKilobytes",
1250 static_cast<int>(io_after.ReadTransferCount - 1348 static_cast<int>(io_after.ReadTransferCount -
1251 io_before.ReadTransferCount) / 1024); 1349 io_before.ReadTransferCount) / 1024);
1252 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes", 1350 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteKilobytes",
1253 static_cast<int>(io_after.WriteTransferCount - 1351 static_cast<int>(io_after.WriteTransferCount -
1254 io_before.WriteTransferCount) / 1024); 1352 io_before.WriteTransferCount) / 1024);
1255 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations", 1353 UMA_HISTOGRAM_COUNTS("SB2.BuildReadOperations",
1256 static_cast<int>(io_after.ReadOperationCount - 1354 static_cast<int>(io_after.ReadOperationCount -
1257 io_before.ReadOperationCount)); 1355 io_before.ReadOperationCount));
1258 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteOperations", 1356 UMA_HISTOGRAM_COUNTS("SB2.BuildWriteOperations",
1259 static_cast<int>(io_after.WriteOperationCount - 1357 static_cast<int>(io_after.WriteOperationCount -
1260 io_before.WriteOperationCount)); 1358 io_before.WriteOperationCount));
1261 } 1359 }
1262 1360
1263 const base::FilePath browse_filename = BrowseDBFilename(filename_base_); 1361 const int64 file_size = GetFileSizeOrZero(db_filename);
1264 const int64 file_size = GetFileSizeOrZero(browse_filename);
1265 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes", 1362 UMA_HISTOGRAM_COUNTS("SB2.BrowseDatabaseKilobytes",
1266 static_cast<int>(file_size / 1024)); 1363 static_cast<int>(file_size / 1024));
1267 1364
1268 #if defined(OS_MACOSX) 1365 #if defined(OS_MACOSX)
1269 base::mac::SetFileBackupExclusion(browse_filename); 1366 base::mac::SetFileBackupExclusion(db_filename);
1270 #endif 1367 #endif
1271 } 1368 }
1272 1369
1273 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { 1370 void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() {
1274 safe_browsing::PrefixSetBuilder builder; 1371 safe_browsing::PrefixSetBuilder builder;
1275 std::vector<SBAddFullHash> add_full_hashes_result; 1372 std::vector<SBAddFullHash> add_full_hashes_result;
1276 1373
1277 if (!side_effect_free_whitelist_store_->FinishUpdate( 1374 if (!side_effect_free_whitelist_store_->FinishUpdate(
1278 &builder, &add_full_hashes_result)) { 1375 &builder, &add_full_hashes_result)) {
1279 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH); 1376 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_UPDATE_FINISH);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 1450
1354 // NOTE(shess): ResetDatabase() should remove the corruption, so this should 1451 // NOTE(shess): ResetDatabase() should remove the corruption, so this should
1355 // only happen once. If you are here because you are hitting this after a 1452 // only happen once. If you are here because you are hitting this after a
1356 // restart, then I would be very interested in working with you to figure out 1453 // restart, then I would be very interested in working with you to figure out
1357 // what is happening, since it may affect real users. 1454 // what is happening, since it may affect real users.
1358 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; 1455 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset";
1359 } 1456 }
1360 1457
1361 // TODO(shess): I'm not clear why this code doesn't have any 1458 // TODO(shess): I'm not clear why this code doesn't have any
1362 // real error-handling. 1459 // real error-handling.
1363 void SafeBrowsingDatabaseNew::LoadPrefixSet() { 1460 void SafeBrowsingDatabaseNew::LoadPrefixSet(
1461 const base::FilePath& db_filename,
1462 scoped_ptr<safe_browsing::PrefixSet>* prefix_set,
1463 FailureType read_failure_type) {
1464 if (!prefix_set)
1465 return;
1466
1364 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1467 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
1365 DCHECK(!filename_base_.empty()); 1468 DCHECK(!filename_base_.empty());
1366 1469
1367 const base::FilePath browse_filename = BrowseDBFilename(filename_base_); 1470 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1368 const base::FilePath browse_prefix_set_filename =
1369 PrefixSetForFilename(browse_filename);
1370 1471
1371 // Only use the prefix set if database is present and non-empty. 1472 // Only use the prefix set if database is present and non-empty.
1372 if (!GetFileSizeOrZero(browse_filename)) 1473 if (!GetFileSizeOrZero(db_filename))
1373 return; 1474 return;
1374 1475
1375 // Cleanup any stale bloom filter (no longer used). 1476 // Cleanup any stale bloom filter (no longer used).
1376 // TODO(shess): Track existence to drive removal of this code? 1477 // TODO(shess): Track existence to drive removal of this code?
1377 const base::FilePath bloom_filter_filename = 1478 const base::FilePath bloom_filter_filename =
1378 BloomFilterForFilename(browse_filename); 1479 BloomFilterForFilename(db_filename);
1379 base::DeleteFile(bloom_filter_filename, false); 1480 base::DeleteFile(bloom_filter_filename, false);
1380 1481
1381 const base::TimeTicks before = base::TimeTicks::Now(); 1482 const base::TimeTicks before = base::TimeTicks::Now();
1382 browse_prefix_set_ = safe_browsing::PrefixSet::LoadFile( 1483 *prefix_set = safe_browsing::PrefixSet::LoadFile(prefix_set_filename);
1383 browse_prefix_set_filename);
1384 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); 1484 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before);
1385 1485
1386 if (!browse_prefix_set_.get()) 1486 if (!prefix_set->get())
1387 RecordFailure(FAILURE_BROWSE_PREFIX_SET_READ); 1487 RecordFailure(read_failure_type);
1388 } 1488 }
1389 1489
1390 bool SafeBrowsingDatabaseNew::Delete() { 1490 bool SafeBrowsingDatabaseNew::Delete() {
1391 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1491 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
1392 DCHECK(!filename_base_.empty()); 1492 DCHECK(!filename_base_.empty());
1393 1493
1394 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the 1494 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the
1395 // store before calling DeleteStore(). DeleteStore() deletes transient files 1495 // store before calling DeleteStore(). DeleteStore() deletes transient files
1396 // in addition to the main file. Probably all of these should be converted to 1496 // in addition to the main file. Probably all of these should be converted to
1397 // a helper which calls Delete() if the store exists, else DeleteStore() on 1497 // a helper which calls Delete() if the store exists, else DeleteStore() on
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 side_effect_free_whitelist_prefix_set_filename, 1552 side_effect_free_whitelist_prefix_set_filename,
1453 false); 1553 false);
1454 if (!r9) 1554 if (!r9)
1455 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_DELETE); 1555 RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_PREFIX_SET_DELETE);
1456 1556
1457 const bool r10 = base::DeleteFile(IpBlacklistDBFilename(filename_base_), 1557 const bool r10 = base::DeleteFile(IpBlacklistDBFilename(filename_base_),
1458 false); 1558 false);
1459 if (!r10) 1559 if (!r10)
1460 RecordFailure(FAILURE_IP_BLACKLIST_DELETE); 1560 RecordFailure(FAILURE_IP_BLACKLIST_DELETE);
1461 1561
1462 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10; 1562 const bool r11 =
1563 base::DeleteFile(UnwantedSoftwareDBFilename(filename_base_), false);
1564 if (!r11)
1565 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE);
1566
1567 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11;
1463 } 1568 }
1464 1569
1465 void SafeBrowsingDatabaseNew::WritePrefixSet() { 1570 void SafeBrowsingDatabaseNew::WritePrefixSet(
1571 const base::FilePath& db_filename,
1572 safe_browsing::PrefixSet* prefix_set,
1573 FailureType write_failure_type) {
1466 DCHECK_EQ(creation_loop_, base::MessageLoop::current()); 1574 DCHECK_EQ(creation_loop_, base::MessageLoop::current());
1467 1575
1468 if (!browse_prefix_set_.get()) 1576 if (!prefix_set)
1469 return; 1577 return;
1470 1578
1471 const base::FilePath browse_filename = BrowseDBFilename(filename_base_); 1579 const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename);
1472 const base::FilePath browse_prefix_set_filename =
1473 PrefixSetForFilename(browse_filename);
1474 1580
1475 const base::TimeTicks before = base::TimeTicks::Now(); 1581 const base::TimeTicks before = base::TimeTicks::Now();
1476 const bool write_ok = browse_prefix_set_->WriteFile( 1582 const bool write_ok = prefix_set->WriteFile(prefix_set_filename);
1477 browse_prefix_set_filename);
1478 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before); 1583 UMA_HISTOGRAM_TIMES("SB2.PrefixSetWrite", base::TimeTicks::Now() - before);
1479 1584
1480 const int64 file_size = GetFileSizeOrZero(browse_prefix_set_filename); 1585 const int64 file_size = GetFileSizeOrZero(prefix_set_filename);
1481 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes", 1586 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetKilobytes",
1482 static_cast<int>(file_size / 1024)); 1587 static_cast<int>(file_size / 1024));
1483 1588
1484 if (!write_ok) 1589 if (!write_ok)
1485 RecordFailure(FAILURE_BROWSE_PREFIX_SET_WRITE); 1590 RecordFailure(write_failure_type);
1486 1591
1487 #if defined(OS_MACOSX) 1592 #if defined(OS_MACOSX)
1488 base::mac::SetFileBackupExclusion(browse_prefix_set_filename); 1593 base::mac::SetFileBackupExclusion(prefix_set_filename);
1489 #endif 1594 #endif
1490 } 1595 }
1491 1596
1492 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { 1597 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1493 base::AutoLock locked(lookup_lock_); 1598 base::AutoLock locked(lookup_lock_);
1494 whitelist->second = true; 1599 whitelist->second = true;
1495 whitelist->first.clear(); 1600 whitelist->first.clear();
1496 } 1601 }
1497 1602
1498 void SafeBrowsingDatabaseNew::LoadWhitelist( 1603 void SafeBrowsingDatabaseNew::LoadWhitelist(
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { 1672 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() {
1568 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); 1673 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl);
1569 std::vector<SBFullHash> full_hashes; 1674 std::vector<SBFullHash> full_hashes;
1570 full_hashes.push_back(malware_kill_switch); 1675 full_hashes.push_back(malware_kill_switch);
1571 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); 1676 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes);
1572 } 1677 }
1573 1678
1574 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { 1679 bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() {
1575 return csd_whitelist_.second; 1680 return csd_whitelist_.second;
1576 } 1681 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698