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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/chromeos/drive/drive_resource_metadata_storage.h" 5 #include "chrome/browser/chromeos/drive/drive_resource_metadata_storage.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 194
195 leveldb::Status status = 195 leveldb::Status status =
196 leveldb::DB::Open(options, resource_map_path.value(), &db); 196 leveldb::DB::Open(options, resource_map_path.value(), &db);
197 if (status.ok()) 197 if (status.ok())
198 resource_map_.reset(db); 198 resource_map_.reset(db);
199 199
200 status = leveldb::DB::Open(options, child_map_path.value(), &db); 200 status = leveldb::DB::Open(options, child_map_path.value(), &db);
201 if (status.ok()) 201 if (status.ok())
202 child_map_.reset(db); 202 child_map_.reset(db);
203 203
204 // Check the version of existing DB. 204 // Check the validity of existing DB.
205 if (resource_map_ && child_map_) { 205 if (resource_map_ && child_map_) {
206 scoped_ptr<DriveResourceMetadataHeader> header = GetHeader(); 206 if (!CheckValidity()) {
207 if (!header || 207 LOG(ERROR) << "Reject invalid DB.";
208 header->version() != kDBVersion) {
209 LOG(ERROR) << "Reject incompatible DB.";
210 resource_map_.reset(); 208 resource_map_.reset();
211 child_map_.reset(); 209 child_map_.reset();
212 } 210 }
213 } 211 }
214 212
215 // Failed to open the existing DB, create new DB. 213 // Failed to open the existing DB, create new DB.
216 if (!resource_map_ || !child_map_) { 214 if (!resource_map_ || !child_map_) {
217 resource_map_.reset(); 215 resource_map_.reset();
218 child_map_.reset(); 216 child_map_.reset();
219 217
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (!status.ok()) 420 if (!status.ok())
423 return scoped_ptr<DriveResourceMetadataHeader>(); 421 return scoped_ptr<DriveResourceMetadataHeader>();
424 422
425 scoped_ptr<DriveResourceMetadataHeader> header( 423 scoped_ptr<DriveResourceMetadataHeader> header(
426 new DriveResourceMetadataHeader); 424 new DriveResourceMetadataHeader);
427 if (!header->ParseFromString(serialized_header)) 425 if (!header->ParseFromString(serialized_header))
428 return scoped_ptr<DriveResourceMetadataHeader>(); 426 return scoped_ptr<DriveResourceMetadataHeader>();
429 return header.Pass(); 427 return header.Pass();
430 } 428 }
431 429
430 bool DriveResourceMetadataStorageDB::CheckValidity() {
431 base::ThreadRestrictions::AssertIOAllowed();
432
433 // Perform read with checksums verification enalbed.
434 leveldb::ReadOptions options;
435 options.verify_checksums = true;
436
437 scoped_ptr<leveldb::Iterator> it(resource_map_->NewIterator(options));
438 it->SeekToFirst();
439
440 // Check the header.
441 DriveResourceMetadataHeader header;
442 if (!it->Valid() ||
443 it->key() != GetHeaderDBKey() || // Header entry must come first.
444 !header.ParseFromArray(it->value().data(), it->value().size()) ||
445 header.version() != kDBVersion) {
446 DLOG(ERROR) << "Invalid header detected. version = " << header.version();
447 return false;
448 }
449
450 // Check all entires.
451 size_t num_checked_child_map_entries = 0;
452 DriveEntryProto entry;
453 std::string child_resource_id;
454 for (it->Next(); it->Valid(); it->Next()) {
455 // Check if stored data is broken.
456 if (!entry.ParseFromArray(it->value().data(), it->value().size()) ||
457 entry.resource_id() != it->key()) {
458 DLOG(ERROR) << "Broken entry detected";
459 return false;
460 }
461
462 // Check if parent-child relationship is stored correctly.
463 if (!entry.parent_resource_id().empty()) {
464 leveldb::Status status = child_map_->Get(
465 options,
466 leveldb::Slice(GetChildMapKey(entry.parent_resource_id(),
467 entry.base_name())),
468 &child_resource_id);
469 if (!status.ok() || child_resource_id != entry.resource_id()) {
470 DLOG(ERROR) << "Child map is broken. status = " << status.ToString();
471 return false;
472 }
473 ++num_checked_child_map_entries;
474 }
475 }
476 if (!it->status().ok()) {
477 DLOG(ERROR) << "Error during checking resource map. status = "
478 << it->status().ToString();
479 return false;
480 }
481
482 // Check all child map entries are referenced from |resource_map_|.
483 size_t num_child_map_entries = 0;
484 it.reset(child_map_->NewIterator(options));
485 for (it->SeekToFirst(); it->Valid(); it->Next()) {
486 ++num_child_map_entries;
487 }
488 if (!it->status().ok() ||
489 num_child_map_entries != num_checked_child_map_entries) {
490 DLOG(ERROR) << "Error during checking child map. status = "
491 << it->status().ToString();
492 return false;
493 }
494
495 return true;
496 }
497
432 } // namespace drive 498 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698