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

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

Issue 744183002: More explicit thread checking in SafeBrowsingDatabase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a3_deadcode
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
6 6
7 #include "base/files/file_util.h" 7 #include "base/files/file_util.h"
8 #include "base/files/scoped_file.h" 8 #include "base/files/scoped_file.h"
9 #include "base/md5.h" 9 #include "base/md5.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 551
552 return static_cast<int64>(ftell(file.get())) == size; 552 return static_cast<int64>(ftell(file.get())) == size;
553 } 553 }
554 554
555 } // namespace 555 } // namespace
556 556
557 SafeBrowsingStoreFile::SafeBrowsingStoreFile() 557 SafeBrowsingStoreFile::SafeBrowsingStoreFile()
558 : chunks_written_(0), empty_(false), corruption_seen_(false) {} 558 : chunks_written_(0), empty_(false), corruption_seen_(false) {}
559 559
560 SafeBrowsingStoreFile::~SafeBrowsingStoreFile() { 560 SafeBrowsingStoreFile::~SafeBrowsingStoreFile() {
561 DCHECK(CalledOnValidThread());
561 Close(); 562 Close();
562 } 563 }
563 564
564 bool SafeBrowsingStoreFile::Delete() { 565 bool SafeBrowsingStoreFile::Delete() {
566 DCHECK(CalledOnValidThread());
567
565 // The database should not be open at this point. But, just in 568 // The database should not be open at this point. But, just in
566 // case, close everything before deleting. 569 // case, close everything before deleting.
567 if (!Close()) { 570 if (!Close()) {
568 NOTREACHED(); 571 NOTREACHED();
569 return false; 572 return false;
570 } 573 }
571 574
572 return DeleteStore(filename_); 575 return DeleteStore(filename_);
573 } 576 }
574 577
575 bool SafeBrowsingStoreFile::CheckValidity() { 578 bool SafeBrowsingStoreFile::CheckValidity() {
579 DCHECK(CalledOnValidThread());
580
576 // The file was either empty or never opened. The empty case is 581 // The file was either empty or never opened. The empty case is
577 // presumed not to be invalid. The never-opened case can happen if 582 // presumed not to be invalid. The never-opened case can happen if
578 // BeginUpdate() fails for any databases, and should already have 583 // BeginUpdate() fails for any databases, and should already have
579 // caused the corruption callback to fire. 584 // caused the corruption callback to fire.
580 if (!file_.get()) 585 if (!file_.get())
581 return true; 586 return true;
582 587
583 if (!FileRewind(file_.get())) 588 if (!FileRewind(file_.get()))
584 return OnCorruptDatabase(); 589 return OnCorruptDatabase();
585 590
(...skipping 27 matching lines...) Expand all
613 if (!ReadAndVerifyChecksum(file_.get(), &context)) { 618 if (!ReadAndVerifyChecksum(file_.get(), &context)) {
614 RecordFormatEvent(FORMAT_EVENT_VALIDITY_CHECKSUM_FAILURE); 619 RecordFormatEvent(FORMAT_EVENT_VALIDITY_CHECKSUM_FAILURE);
615 return OnCorruptDatabase(); 620 return OnCorruptDatabase();
616 } 621 }
617 622
618 return true; 623 return true;
619 } 624 }
620 625
621 void SafeBrowsingStoreFile::Init(const base::FilePath& filename, 626 void SafeBrowsingStoreFile::Init(const base::FilePath& filename,
622 const base::Closure& corruption_callback) { 627 const base::Closure& corruption_callback) {
628 DCHECK(CalledOnValidThread());
623 filename_ = filename; 629 filename_ = filename;
624 corruption_callback_ = corruption_callback; 630 corruption_callback_ = corruption_callback;
625 } 631 }
626 632
627 bool SafeBrowsingStoreFile::BeginChunk() { 633 bool SafeBrowsingStoreFile::BeginChunk() {
634 DCHECK(CalledOnValidThread());
628 return ClearChunkBuffers(); 635 return ClearChunkBuffers();
629 } 636 }
630 637
631 bool SafeBrowsingStoreFile::WriteAddPrefix(int32 chunk_id, SBPrefix prefix) { 638 bool SafeBrowsingStoreFile::WriteAddPrefix(int32 chunk_id, SBPrefix prefix) {
639 DCHECK(CalledOnValidThread());
632 add_prefixes_.push_back(SBAddPrefix(chunk_id, prefix)); 640 add_prefixes_.push_back(SBAddPrefix(chunk_id, prefix));
633 return true; 641 return true;
634 } 642 }
635 643
636 bool SafeBrowsingStoreFile::GetAddPrefixes(SBAddPrefixes* add_prefixes) { 644 bool SafeBrowsingStoreFile::GetAddPrefixes(SBAddPrefixes* add_prefixes) {
645 DCHECK(CalledOnValidThread());
646
637 add_prefixes->clear(); 647 add_prefixes->clear();
638 if (!base::PathExists(filename_)) 648 if (!base::PathExists(filename_))
639 return true; 649 return true;
640 650
641 StateInternal db_state; 651 StateInternal db_state;
642 if (!ReadDbStateHelper(filename_, &db_state)) 652 if (!ReadDbStateHelper(filename_, &db_state))
643 return OnCorruptDatabase(); 653 return OnCorruptDatabase();
644 654
645 add_prefixes->swap(db_state.add_prefixes_); 655 add_prefixes->swap(db_state.add_prefixes_);
646 return true; 656 return true;
647 } 657 }
648 658
649 bool SafeBrowsingStoreFile::GetAddFullHashes( 659 bool SafeBrowsingStoreFile::GetAddFullHashes(
650 std::vector<SBAddFullHash>* add_full_hashes) { 660 std::vector<SBAddFullHash>* add_full_hashes) {
661 DCHECK(CalledOnValidThread());
662
651 add_full_hashes->clear(); 663 add_full_hashes->clear();
652 if (!base::PathExists(filename_)) 664 if (!base::PathExists(filename_))
653 return true; 665 return true;
654 666
655 StateInternal db_state; 667 StateInternal db_state;
656 if (!ReadDbStateHelper(filename_, &db_state)) 668 if (!ReadDbStateHelper(filename_, &db_state))
657 return OnCorruptDatabase(); 669 return OnCorruptDatabase();
658 670
659 add_full_hashes->swap(db_state.add_full_hashes_); 671 add_full_hashes->swap(db_state.add_full_hashes_);
660 return true; 672 return true;
661 } 673 }
662 674
663 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id, 675 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id,
664 const SBFullHash& full_hash) { 676 const SBFullHash& full_hash) {
677 DCHECK(CalledOnValidThread());
665 add_hashes_.push_back(SBAddFullHash(chunk_id, full_hash)); 678 add_hashes_.push_back(SBAddFullHash(chunk_id, full_hash));
666 return true; 679 return true;
667 } 680 }
668 681
669 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id, 682 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id,
670 int32 add_chunk_id, 683 int32 add_chunk_id,
671 SBPrefix prefix) { 684 SBPrefix prefix) {
685 DCHECK(CalledOnValidThread());
672 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix)); 686 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix));
673 return true; 687 return true;
674 } 688 }
675 689
676 bool SafeBrowsingStoreFile::WriteSubHash(int32 chunk_id, int32 add_chunk_id, 690 bool SafeBrowsingStoreFile::WriteSubHash(int32 chunk_id, int32 add_chunk_id,
677 const SBFullHash& full_hash) { 691 const SBFullHash& full_hash) {
692 DCHECK(CalledOnValidThread());
678 sub_hashes_.push_back(SBSubFullHash(chunk_id, add_chunk_id, full_hash)); 693 sub_hashes_.push_back(SBSubFullHash(chunk_id, add_chunk_id, full_hash));
679 return true; 694 return true;
680 } 695 }
681 696
682 bool SafeBrowsingStoreFile::OnCorruptDatabase() { 697 bool SafeBrowsingStoreFile::OnCorruptDatabase() {
698 DCHECK(CalledOnValidThread());
699
683 if (!corruption_seen_) 700 if (!corruption_seen_)
684 RecordFormatEvent(FORMAT_EVENT_FILE_CORRUPT); 701 RecordFormatEvent(FORMAT_EVENT_FILE_CORRUPT);
685 corruption_seen_ = true; 702 corruption_seen_ = true;
686 703
687 corruption_callback_.Run(); 704 corruption_callback_.Run();
688 705
689 // Return false as a convenience to callers. 706 // Return false as a convenience to callers.
690 return false; 707 return false;
691 } 708 }
692 709
693 bool SafeBrowsingStoreFile::Close() { 710 bool SafeBrowsingStoreFile::Close() {
711 DCHECK(CalledOnValidThread());
712
694 ClearUpdateBuffers(); 713 ClearUpdateBuffers();
695 714
696 // Make sure the files are closed. 715 // Make sure the files are closed.
697 file_.reset(); 716 file_.reset();
698 new_file_.reset(); 717 new_file_.reset();
699 return true; 718 return true;
700 } 719 }
701 720
702 bool SafeBrowsingStoreFile::BeginUpdate() { 721 bool SafeBrowsingStoreFile::BeginUpdate() {
722 DCHECK(CalledOnValidThread());
703 DCHECK(!file_.get() && !new_file_.get()); 723 DCHECK(!file_.get() && !new_file_.get());
704 724
705 // Structures should all be clear unless something bad happened. 725 // Structures should all be clear unless something bad happened.
706 DCHECK(add_chunks_cache_.empty()); 726 DCHECK(add_chunks_cache_.empty());
707 DCHECK(sub_chunks_cache_.empty()); 727 DCHECK(sub_chunks_cache_.empty());
708 DCHECK(add_del_cache_.empty()); 728 DCHECK(add_del_cache_.empty());
709 DCHECK(sub_del_cache_.empty()); 729 DCHECK(sub_del_cache_.empty());
710 DCHECK(add_prefixes_.empty()); 730 DCHECK(add_prefixes_.empty());
711 DCHECK(sub_prefixes_.empty()); 731 DCHECK(sub_prefixes_.empty());
712 DCHECK(add_hashes_.empty()); 732 DCHECK(add_hashes_.empty());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 774
755 return OnCorruptDatabase(); 775 return OnCorruptDatabase();
756 } 776 }
757 777
758 file_.swap(file); 778 file_.swap(file);
759 new_file_.swap(new_file); 779 new_file_.swap(new_file);
760 return true; 780 return true;
761 } 781 }
762 782
763 bool SafeBrowsingStoreFile::FinishChunk() { 783 bool SafeBrowsingStoreFile::FinishChunk() {
784 DCHECK(CalledOnValidThread());
785
764 if (!add_prefixes_.size() && !sub_prefixes_.size() && 786 if (!add_prefixes_.size() && !sub_prefixes_.size() &&
765 !add_hashes_.size() && !sub_hashes_.size()) 787 !add_hashes_.size() && !sub_hashes_.size())
766 return true; 788 return true;
767 789
768 ChunkHeader header; 790 ChunkHeader header;
769 header.add_prefix_count = add_prefixes_.size(); 791 header.add_prefix_count = add_prefixes_.size();
770 header.sub_prefix_count = sub_prefixes_.size(); 792 header.sub_prefix_count = sub_prefixes_.size();
771 header.add_hash_count = add_hashes_.size(); 793 header.add_hash_count = add_hashes_.size();
772 header.sub_hash_count = sub_hashes_.size(); 794 header.sub_hash_count = sub_hashes_.size();
773 if (!WriteItem(header, new_file_.get(), NULL)) 795 if (!WriteItem(header, new_file_.get(), NULL))
774 return false; 796 return false;
775 797
776 if (!WriteContainer(add_prefixes_, new_file_.get(), NULL) || 798 if (!WriteContainer(add_prefixes_, new_file_.get(), NULL) ||
777 !WriteContainer(sub_prefixes_, new_file_.get(), NULL) || 799 !WriteContainer(sub_prefixes_, new_file_.get(), NULL) ||
778 !WriteContainer(add_hashes_, new_file_.get(), NULL) || 800 !WriteContainer(add_hashes_, new_file_.get(), NULL) ||
779 !WriteContainer(sub_hashes_, new_file_.get(), NULL)) 801 !WriteContainer(sub_hashes_, new_file_.get(), NULL))
780 return false; 802 return false;
781 803
782 ++chunks_written_; 804 ++chunks_written_;
783 805
784 // Clear everything to save memory. 806 // Clear everything to save memory.
785 return ClearChunkBuffers(); 807 return ClearChunkBuffers();
786 } 808 }
787 809
788 bool SafeBrowsingStoreFile::DoUpdate( 810 bool SafeBrowsingStoreFile::DoUpdate(
789 safe_browsing::PrefixSetBuilder* builder, 811 safe_browsing::PrefixSetBuilder* builder,
790 std::vector<SBAddFullHash>* add_full_hashes_result) { 812 std::vector<SBAddFullHash>* add_full_hashes_result) {
813 DCHECK(CalledOnValidThread());
791 DCHECK(file_.get() || empty_); 814 DCHECK(file_.get() || empty_);
792 DCHECK(new_file_.get()); 815 DCHECK(new_file_.get());
793 CHECK(builder); 816 CHECK(builder);
794 CHECK(add_full_hashes_result); 817 CHECK(add_full_hashes_result);
795 818
796 // Rewind the temporary storage. 819 // Rewind the temporary storage.
797 if (!FileRewind(new_file_.get())) 820 if (!FileRewind(new_file_.get()))
798 return false; 821 return false;
799 822
800 // Get chunk file's size for validating counts. 823 // Get chunk file's size for validating counts.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 // Record counts before swapping to caller. 1051 // Record counts before swapping to caller.
1029 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count); 1052 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count);
1030 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count); 1053 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count);
1031 1054
1032 return true; 1055 return true;
1033 } 1056 }
1034 1057
1035 bool SafeBrowsingStoreFile::FinishUpdate( 1058 bool SafeBrowsingStoreFile::FinishUpdate(
1036 safe_browsing::PrefixSetBuilder* builder, 1059 safe_browsing::PrefixSetBuilder* builder,
1037 std::vector<SBAddFullHash>* add_full_hashes_result) { 1060 std::vector<SBAddFullHash>* add_full_hashes_result) {
1061 DCHECK(CalledOnValidThread());
1038 DCHECK(builder); 1062 DCHECK(builder);
1039 DCHECK(add_full_hashes_result); 1063 DCHECK(add_full_hashes_result);
1040 1064
1041 if (!DoUpdate(builder, add_full_hashes_result)) { 1065 if (!DoUpdate(builder, add_full_hashes_result)) {
1042 CancelUpdate(); 1066 CancelUpdate();
1043 return false; 1067 return false;
1044 } 1068 }
1045 1069
1046 DCHECK(!new_file_.get()); 1070 DCHECK(!new_file_.get());
1047 DCHECK(!file_.get()); 1071 DCHECK(!file_.get());
1048 1072
1049 return Close(); 1073 return Close();
1050 } 1074 }
1051 1075
1052 bool SafeBrowsingStoreFile::CancelUpdate() { 1076 bool SafeBrowsingStoreFile::CancelUpdate() {
1077 DCHECK(CalledOnValidThread());
1053 bool ret = Close(); 1078 bool ret = Close();
1054 1079
1055 // Delete stale staging file. 1080 // Delete stale staging file.
1056 const base::FilePath new_filename = TemporaryFileForFilename(filename_); 1081 const base::FilePath new_filename = TemporaryFileForFilename(filename_);
1057 base::DeleteFile(new_filename, false); 1082 base::DeleteFile(new_filename, false);
1058 1083
1059 return ret; 1084 return ret;
1060 } 1085 }
1061 1086
1062 void SafeBrowsingStoreFile::SetAddChunk(int32 chunk_id) { 1087 void SafeBrowsingStoreFile::SetAddChunk(int32 chunk_id) {
1088 DCHECK(CalledOnValidThread());
1063 add_chunks_cache_.insert(chunk_id); 1089 add_chunks_cache_.insert(chunk_id);
1064 } 1090 }
1065 1091
1066 bool SafeBrowsingStoreFile::CheckAddChunk(int32 chunk_id) { 1092 bool SafeBrowsingStoreFile::CheckAddChunk(int32 chunk_id) {
1093 DCHECK(CalledOnValidThread());
1067 return add_chunks_cache_.count(chunk_id) > 0; 1094 return add_chunks_cache_.count(chunk_id) > 0;
1068 } 1095 }
1069 1096
1070 void SafeBrowsingStoreFile::GetAddChunks(std::vector<int32>* out) { 1097 void SafeBrowsingStoreFile::GetAddChunks(std::vector<int32>* out) {
1098 DCHECK(CalledOnValidThread());
1071 out->clear(); 1099 out->clear();
1072 out->insert(out->end(), add_chunks_cache_.begin(), add_chunks_cache_.end()); 1100 out->insert(out->end(), add_chunks_cache_.begin(), add_chunks_cache_.end());
1073 } 1101 }
1074 1102
1075 void SafeBrowsingStoreFile::SetSubChunk(int32 chunk_id) { 1103 void SafeBrowsingStoreFile::SetSubChunk(int32 chunk_id) {
1104 DCHECK(CalledOnValidThread());
1076 sub_chunks_cache_.insert(chunk_id); 1105 sub_chunks_cache_.insert(chunk_id);
1077 } 1106 }
1078 1107
1079 bool SafeBrowsingStoreFile::CheckSubChunk(int32 chunk_id) { 1108 bool SafeBrowsingStoreFile::CheckSubChunk(int32 chunk_id) {
1109 DCHECK(CalledOnValidThread());
1080 return sub_chunks_cache_.count(chunk_id) > 0; 1110 return sub_chunks_cache_.count(chunk_id) > 0;
1081 } 1111 }
1082 1112
1083 void SafeBrowsingStoreFile::GetSubChunks(std::vector<int32>* out) { 1113 void SafeBrowsingStoreFile::GetSubChunks(std::vector<int32>* out) {
1114 DCHECK(CalledOnValidThread());
1084 out->clear(); 1115 out->clear();
1085 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end()); 1116 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end());
1086 } 1117 }
1087 1118
1088 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { 1119 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) {
1120 DCHECK(CalledOnValidThread());
1089 add_del_cache_.insert(chunk_id); 1121 add_del_cache_.insert(chunk_id);
1090 } 1122 }
1091 1123
1092 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { 1124 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) {
1125 DCHECK(CalledOnValidThread());
1093 sub_del_cache_.insert(chunk_id); 1126 sub_del_cache_.insert(chunk_id);
1094 } 1127 }
1095 1128
1096 // static 1129 // static
1097 bool SafeBrowsingStoreFile::DeleteStore(const base::FilePath& basename) { 1130 bool SafeBrowsingStoreFile::DeleteStore(const base::FilePath& basename) {
1098 if (!base::DeleteFile(basename, false) && 1131 if (!base::DeleteFile(basename, false) &&
1099 base::PathExists(basename)) { 1132 base::PathExists(basename)) {
1100 NOTREACHED(); 1133 NOTREACHED();
1101 return false; 1134 return false;
1102 } 1135 }
1103 1136
1104 const base::FilePath new_filename = TemporaryFileForFilename(basename); 1137 const base::FilePath new_filename = TemporaryFileForFilename(basename);
1105 if (!base::DeleteFile(new_filename, false) && 1138 if (!base::DeleteFile(new_filename, false) &&
1106 base::PathExists(new_filename)) { 1139 base::PathExists(new_filename)) {
1107 NOTREACHED(); 1140 NOTREACHED();
1108 return false; 1141 return false;
1109 } 1142 }
1110 1143
1111 // With SQLite support gone, one way to get to this code is if the 1144 // With SQLite support gone, one way to get to this code is if the
1112 // existing file is a SQLite file. Make sure the journal file is 1145 // existing file is a SQLite file. Make sure the journal file is
1113 // also removed. 1146 // also removed.
1114 const base::FilePath journal_filename( 1147 const base::FilePath journal_filename(
1115 basename.value() + FILE_PATH_LITERAL("-journal")); 1148 basename.value() + FILE_PATH_LITERAL("-journal"));
1116 if (base::PathExists(journal_filename)) 1149 if (base::PathExists(journal_filename))
1117 base::DeleteFile(journal_filename, false); 1150 base::DeleteFile(journal_filename, false);
1118 1151
1119 return true; 1152 return true;
1120 } 1153 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698