Index: base/files/file.h |
diff --git a/base/files/file.h b/base/files/file.h |
index 4110d51bd8199bde0b1e0f4e79d8fa5c7ae9e51e..7b6366c1c2edaa2c6ccb695f2f075ff83f0d002b 100644 |
--- a/base/files/file.h |
+++ b/base/files/file.h |
@@ -19,6 +19,7 @@ |
#include "base/base_export.h" |
#include "base/basictypes.h" |
#include "base/files/scoped_file.h" |
+#include "base/gtest_prod_util.h" |
#include "base/move.h" |
#include "base/time/time.h" |
@@ -26,6 +27,8 @@ |
#include "base/win/scoped_handle.h" |
#endif |
+FORWARD_DECLARE_TEST(FileTest, MemoryCorruption); |
+ |
namespace base { |
class FilePath; |
@@ -296,12 +299,59 @@ class BASE_EXPORT File { |
static std::string ErrorToString(Error error); |
private: |
+ FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption); |
+ |
+#if defined(OS_POSIX) |
+ // Encloses a single ScopedFD, saving a cheap tamper resistent memory checksum |
+ // alongside it. This checksum is validated at every access, allowing early |
+ // detection of memory corruption. |
+ |
+ // TODO(gavinp): This is in place temporarily to help us debug |
+ // https://crbug.com/424562 , which can't be reproduced in valgrind. Remove |
+ // this code after we have fixed this issue. |
+ class MemoryCheckingScopedFD { |
+ public: |
+ MemoryCheckingScopedFD(); |
+ MemoryCheckingScopedFD(int fd); |
+ ~MemoryCheckingScopedFD(); |
+ |
+ bool is_valid() const { Check(); return file_.is_valid(); } |
+ int get() const { Check(); return file_.get(); } |
+ |
+ void reset() { Check(); file_.reset(); UpdateChecksum(); } |
+ void reset(int fd) { Check(); file_.reset(fd); UpdateChecksum(); } |
+ int release() { |
+ Check(); |
+ int fd = file_.release(); |
+ UpdateChecksum(); |
+ return fd; |
+ } |
+ |
+ private: |
+ FRIEND_TEST_ALL_PREFIXES(::FileTest, MemoryCorruption); |
+ |
+ // Computes the checksum for the current value of |file_|. Returns via an |
+ // out parameter to guard against implicit conversions of unsigned integral |
+ // types. |
+ void ComputeMemoryChecksum(unsigned int* out_checksum) const; |
+ |
+ // Confirms that the current |file_| and |file_memory_checksum_| agree, |
+ // failing a CHECK if they do not. |
+ void Check() const; |
+ |
+ void UpdateChecksum(); |
+ |
+ ScopedFD file_; |
+ unsigned int file_memory_checksum_; |
+ }; |
+#endif |
+ |
void SetPlatformFile(PlatformFile file); |
#if defined(OS_WIN) |
win::ScopedHandle file_; |
#elif defined(OS_POSIX) |
- ScopedFD file_; |
+ MemoryCheckingScopedFD file_; |
#endif |
Error error_details_; |