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

Unified Diff: chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc

Issue 14167009: chromeos: Check validity of loaded data in DriveResourceMetadataStorageDB::Initialize (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 8 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc
diff --git a/chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc b/chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc
index 17bf4e9224a1f9fc6d7c88ca29dc0f340ed058ed..7546b1c434ebc0652d31e9e31b4fbeb6ed126aef 100644
--- a/chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc
+++ b/chrome/browser/chromeos/drive/drive_resource_metadata_storage.cc
@@ -201,12 +201,10 @@ bool DriveResourceMetadataStorageDB::Initialize() {
if (status.ok())
child_map_.reset(db);
- // Check the version of existing DB.
+ // Check the validity of existing DB.
if (resource_map_ && child_map_) {
- scoped_ptr<DriveResourceMetadataHeader> header = GetHeader();
- if (!header ||
- header->version() != kDBVersion) {
- LOG(ERROR) << "Reject incompatible DB.";
+ if (!CheckValidity()) {
+ LOG(ERROR) << "Reject invalid DB.";
resource_map_.reset();
child_map_.reset();
}
@@ -429,4 +427,72 @@ DriveResourceMetadataStorageDB::GetHeader() {
return header.Pass();
}
+bool DriveResourceMetadataStorageDB::CheckValidity() {
+ base::ThreadRestrictions::AssertIOAllowed();
+
+ // Perform read with checksums verification enalbed.
+ leveldb::ReadOptions options;
+ options.verify_checksums = true;
+
+ scoped_ptr<leveldb::Iterator> it(resource_map_->NewIterator(options));
+ it->SeekToFirst();
+
+ // Check the header.
+ DriveResourceMetadataHeader header;
+ if (!it->Valid() ||
+ it->key() != GetHeaderDBKey() || // Header entry must come first.
+ !header.ParseFromArray(it->value().data(), it->value().size()) ||
+ header.version() != kDBVersion) {
+ DLOG(ERROR) << "Invalid header detected. version = " << header.version();
+ return false;
+ }
+
+ // Check all entires.
+ size_t num_checked_child_map_entries = 0;
+ DriveEntryProto entry;
+ std::string child_resource_id;
+ for (it->Next(); it->Valid(); it->Next()) {
+ // Check if stored data is broken.
+ if (!entry.ParseFromArray(it->value().data(), it->value().size()) ||
+ entry.resource_id() != it->key()) {
+ DLOG(ERROR) << "Broken entry detected";
+ return false;
+ }
+
+ // Check if parent-child relationship is stored correctly.
+ if (!entry.parent_resource_id().empty()) {
+ leveldb::Status status = child_map_->Get(
+ options,
+ leveldb::Slice(GetChildMapKey(entry.parent_resource_id(),
+ entry.base_name())),
+ &child_resource_id);
+ if (!status.ok() || child_resource_id != entry.resource_id()) {
+ DLOG(ERROR) << "Child map is broken. status = " << status.ToString();
+ return false;
+ }
+ ++num_checked_child_map_entries;
+ }
+ }
+ if (!it->status().ok()) {
+ DLOG(ERROR) << "Error during checking resource map. status = "
+ << it->status().ToString();
+ return false;
+ }
+
+ // Check all child map entries are referenced from |resource_map_|.
+ size_t num_child_map_entries = 0;
+ it.reset(child_map_->NewIterator(options));
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
+ ++num_child_map_entries;
+ }
+ if (!it->status().ok() ||
+ num_child_map_entries != num_checked_child_map_entries) {
+ DLOG(ERROR) << "Error during checking child map. status = "
+ << it->status().ToString();
+ return false;
+ }
+
+ return true;
+}
+
} // namespace drive

Powered by Google App Engine
This is Rietveld 408576698