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

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

Issue 10093004: Double-check safe-browsing database validity on update failure. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Unittest, simplify checksum-checker. Created 8 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
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 #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/md5.h" 7 #include "base/md5.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 9
10 namespace { 10 namespace {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 // existing file is a SQLite file. Make sure the journal file is 236 // existing file is a SQLite file. Make sure the journal file is
237 // also removed. 237 // also removed.
238 const FilePath journal_filename( 238 const FilePath journal_filename(
239 filename_.value() + FILE_PATH_LITERAL("-journal")); 239 filename_.value() + FILE_PATH_LITERAL("-journal"));
240 if (file_util::PathExists(journal_filename)) 240 if (file_util::PathExists(journal_filename))
241 file_util::Delete(journal_filename, false); 241 file_util::Delete(journal_filename, false);
242 242
243 return true; 243 return true;
244 } 244 }
245 245
246 bool SafeBrowsingStoreFile::CheckValidity() {
247 if (empty_)
248 return true;
249
250 // If the file was not empty, it should be open.
251 DCHECK(file_.get());
252
253 if (!FileRewind(file_.get()))
254 return OnCorruptDatabase();
255
256 int64 size = 0;
257 if (!file_util::GetFileSize(filename_, &size))
258 return OnCorruptDatabase();
259
260 base::MD5Context context;
261 base::MD5Init(&context);
262
263 // Read everything except the final digest.
264 size_t bytes_left = static_cast<size_t>(size);
265 CHECK(size == static_cast<int64>(bytes_left));
266 bytes_left -= sizeof(base::MD5Digest);
mattm 2012/04/23 23:47:48 if the file size is < sizeof(base::MD5Digest) this
Scott Hess - ex-Googler 2012/04/24 01:37:21 Whoa, totally valid, thanks for catching that!
267
268 // Fold the contents of the file into the checksum.
269 while (bytes_left > 0) {
270 char buf[4096];
271 const size_t c = std::min(sizeof(buf), bytes_left);
272 const size_t ret = fread(buf, 1, c, file_.get());
273
274 // The file's size changed while reading, give up.
275 if (ret != c)
276 return OnCorruptDatabase();
277 base::MD5Update(&context, base::StringPiece(buf, c));
278 bytes_left -= c;
279 }
280
281 // Calculate the digest to this point.
282 base::MD5Digest calculated_digest;
283 base::MD5Final(&calculated_digest, &context);
284
285 // Read the stored digest and verify it.
286 base::MD5Digest file_digest;
287 if (!ReadItem(&file_digest, file_.get(), NULL))
Scott Hess - ex-Googler 2012/04/23 22:29:28 |calculated_digest| was from |file|, while |file_d
288 return OnCorruptDatabase();
289 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) {
290 RecordFormatEvent(FORMAT_EVENT_VALIDITY_CHECKSUM_FAILURE);
291 return OnCorruptDatabase();
292 }
293
294 return true;
295 }
296
246 void SafeBrowsingStoreFile::Init( 297 void SafeBrowsingStoreFile::Init(
247 const FilePath& filename, 298 const FilePath& filename,
248 const base::Closure& corruption_callback 299 const base::Closure& corruption_callback
249 ) { 300 ) {
250 filename_ = filename; 301 filename_ = filename;
251 corruption_callback_ = corruption_callback; 302 corruption_callback_ = corruption_callback;
252 } 303 }
253 304
254 bool SafeBrowsingStoreFile::BeginChunk() { 305 bool SafeBrowsingStoreFile::BeginChunk() {
255 return ClearChunkBuffers(); 306 return ClearChunkBuffers();
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 547
497 // Calculate the digest to this point. 548 // Calculate the digest to this point.
498 base::MD5Digest calculated_digest; 549 base::MD5Digest calculated_digest;
499 base::MD5Final(&calculated_digest, &context); 550 base::MD5Final(&calculated_digest, &context);
500 551
501 // Read the stored checksum and verify it. 552 // Read the stored checksum and verify it.
502 base::MD5Digest file_digest; 553 base::MD5Digest file_digest;
503 if (!ReadItem(&file_digest, file_.get(), NULL)) 554 if (!ReadItem(&file_digest, file_.get(), NULL))
504 return OnCorruptDatabase(); 555 return OnCorruptDatabase();
505 556
506 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) 557 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) {
558 RecordFormatEvent(FORMAT_EVENT_UPDATE_CHECKSUM_FAILURE);
507 return OnCorruptDatabase(); 559 return OnCorruptDatabase();
560 }
508 561
509 // Close the file so we can later rename over it. 562 // Close the file so we can later rename over it.
510 file_.reset(); 563 file_.reset();
511 } 564 }
512 DCHECK(!file_.get()); 565 DCHECK(!file_.get());
513 566
514 // Rewind the temporary storage. 567 // Rewind the temporary storage.
515 if (!FileRewind(new_file_.get())) 568 if (!FileRewind(new_file_.get()))
516 return false; 569 return false;
517 570
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end()); 747 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end());
695 } 748 }
696 749
697 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { 750 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) {
698 add_del_cache_.insert(chunk_id); 751 add_del_cache_.insert(chunk_id);
699 } 752 }
700 753
701 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { 754 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) {
702 sub_del_cache_.insert(chunk_id); 755 sub_del_cache_.insert(chunk_id);
703 } 756 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698