#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"
#include "base/win/scoped_handle.h"
#endif
+FORWARD_DECLARE_TEST(FileTest, MemoryCorruption);
+
namespace base {
class FilePath;
// doesn't exist, |false| is returned.
bool SetLength(int64 length);
- // Flushes the buffers.
+ // Instructs the filesystem to flush the file to disk. (POSIX: fsync, Windows:
+ // FlushFileBuffers).
bool Flush();
// Updates the file times.
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_;