Chromium Code Reviews| Index: base/files/file_posix.cc |
| diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc |
| index 43684b5dabfe3df9b2a6907cd5dfbecb8e3582c3..9fad64344d486accda992d55b34fe1baccf0b7e6 100644 |
| --- a/base/files/file_posix.cc |
| +++ b/base/files/file_posix.cc |
| @@ -483,6 +483,49 @@ File::Error File::OSErrorToFileError(int saved_errno) { |
| } |
| } |
| +File::MemoryCheckingScopedFD::MemoryCheckingScopedFD() { |
| + UpdateChecksum(); |
| +} |
| + |
| +File::MemoryCheckingScopedFD::MemoryCheckingScopedFD(int fd) : file_(fd) { |
| + UpdateChecksum(); |
| +} |
| + |
| +File::MemoryCheckingScopedFD::~MemoryCheckingScopedFD() {} |
| + |
| +// static |
| +void File::MemoryCheckingScopedFD::ComputeMemoryChecksum( |
| + unsigned int* out_checksum) const { |
| + // Use a single iteration of a linear congruentional generator (lcg) to |
| + // provide a cheap checksum unlikely to be accidentally matched by a random |
| + // memory corruption. |
| + |
| + // By choosing constants that satisfy the Hull-Duebell Theorem on lcg cycle |
| + // length, we insure that each distinct fd value maps to a distinct checksum, |
| + // which maximises the utility of our checksum. |
| + |
| + // This code uses "unsigned int" throughout for its defined modular semantics, |
| + // which implicitly gives us a divisor of 2**32 or 2**64, depending. |
|
Nico
2014/11/07 00:12:08
(I think unsigneds are 32bit on all platforms we s
gavinp
2014/11/07 00:37:36
Good point. I've updated the comment to just say "
|
| + |
| + const unsigned int kMultiplier = 13035 * 4 + 1; |
| + COMPILE_ASSERT(((kMultiplier - 1) & 3) == 0, pred_must_be_multiple_of_four); |
| + const unsigned int kIncrement = 1595649551; |
| + COMPILE_ASSERT(kIncrement & 1, must_be_coprime_to_powers_of_two); |
| + |
| + *out_checksum = |
| + static_cast<unsigned int>(file_.get()) * kMultiplier + kIncrement; |
| +} |
| + |
| +void File::MemoryCheckingScopedFD::Check() const { |
| + unsigned int computed_checksum; |
| + ComputeMemoryChecksum(&computed_checksum); |
| + CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; |
| +} |
| + |
| +void File::MemoryCheckingScopedFD::UpdateChecksum() { |
| + ComputeMemoryChecksum(&file_memory_checksum_); |
| +} |
| + |
| void File::SetPlatformFile(PlatformFile file) { |
| DCHECK(!file_.is_valid()); |
| file_.reset(file); |