OLD | NEW |
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 "base/files/file.h" | 5 #include "base/files/file.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 return FILE_ERROR_NOT_A_DIRECTORY; | 476 return FILE_ERROR_NOT_A_DIRECTORY; |
477 default: | 477 default: |
478 #if !defined(OS_NACL) // NaCl build has no metrics code. | 478 #if !defined(OS_NACL) // NaCl build has no metrics code. |
479 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", | 479 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", |
480 saved_errno); | 480 saved_errno); |
481 #endif | 481 #endif |
482 return FILE_ERROR_FAILED; | 482 return FILE_ERROR_FAILED; |
483 } | 483 } |
484 } | 484 } |
485 | 485 |
| 486 File::MemoryCheckingScopedFD::MemoryCheckingScopedFD() { |
| 487 UpdateChecksum(); |
| 488 } |
| 489 |
| 490 File::MemoryCheckingScopedFD::MemoryCheckingScopedFD(int fd) : file_(fd) { |
| 491 UpdateChecksum(); |
| 492 } |
| 493 |
| 494 File::MemoryCheckingScopedFD::~MemoryCheckingScopedFD() {} |
| 495 |
| 496 // static |
| 497 void File::MemoryCheckingScopedFD::ComputeMemoryChecksum( |
| 498 unsigned int* out_checksum) const { |
| 499 // Use a single iteration of a linear congruentional generator (lcg) to |
| 500 // provide a cheap checksum unlikely to be accidentally matched by a random |
| 501 // memory corruption. |
| 502 |
| 503 // By choosing constants that satisfy the Hull-Duebell Theorem on lcg cycle |
| 504 // length, we insure that each distinct fd value maps to a distinct checksum, |
| 505 // which maximises the utility of our checksum. |
| 506 |
| 507 // This code uses "unsigned int" throughout for its defined modular semantics, |
| 508 // which implicitly gives us a divisor that is a power of two. |
| 509 |
| 510 const unsigned int kMultiplier = 13035 * 4 + 1; |
| 511 COMPILE_ASSERT(((kMultiplier - 1) & 3) == 0, pred_must_be_multiple_of_four); |
| 512 const unsigned int kIncrement = 1595649551; |
| 513 COMPILE_ASSERT(kIncrement & 1, must_be_coprime_to_powers_of_two); |
| 514 |
| 515 *out_checksum = |
| 516 static_cast<unsigned int>(file_.get()) * kMultiplier + kIncrement; |
| 517 } |
| 518 |
| 519 void File::MemoryCheckingScopedFD::Check() const { |
| 520 unsigned int computed_checksum; |
| 521 ComputeMemoryChecksum(&computed_checksum); |
| 522 CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; |
| 523 } |
| 524 |
| 525 void File::MemoryCheckingScopedFD::UpdateChecksum() { |
| 526 ComputeMemoryChecksum(&file_memory_checksum_); |
| 527 } |
| 528 |
486 void File::SetPlatformFile(PlatformFile file) { | 529 void File::SetPlatformFile(PlatformFile file) { |
487 DCHECK(!file_.is_valid()); | 530 DCHECK(!file_.is_valid()); |
488 file_.reset(file); | 531 file_.reset(file); |
489 } | 532 } |
490 | 533 |
491 } // namespace base | 534 } // namespace base |
OLD | NEW |