From 55181778eaf298eb2035f64d20a7ebe4e447a75e Mon Sep 17 00:00:00 2001 From: "darin@chromium.org" Date: Fri, 4 Feb 2011 00:39:34 +0000 Subject: Copy buffers in base::FileUtilProxy::{Read,Write} to avoid memory corruption. If caller has called PPB_FileIO_Impl::Close() while a read or write operation is in flight, and deletes the read or write buffer, we now avoid corrupting memory. For Write, FileUtilProxy::Write simply copies the input buffer before passing control to the FILE thread. For Read, the caller no longer passes a buffer; instead, they are passed a const char* in the ReadCallback. One caller of FileUtilProxy::Read outside of PPAPI was also updated. BUG=70285 R=darin Patch by Adam Klein (adamk@chromium.org) Originally reviewed at http://codereview.chromium.org/6312040/ Review URL: http://codereview.chromium.org/6349090 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73714 0039d316-1c4b-4281-b951-d872f2087c98 --- base/file_util_proxy.cc | 31 +++++++++++++++---------------- base/file_util_proxy.h | 10 ++++++---- 2 files changed, 21 insertions(+), 20 deletions(-) (limited to 'base') diff --git a/base/file_util_proxy.cc b/base/file_util_proxy.cc index b4d0d54..d357e98 100644 --- a/base/file_util_proxy.cc +++ b/base/file_util_proxy.cc @@ -525,12 +525,11 @@ class RelayRead : public MessageLoopRelay { public: RelayRead(base::PlatformFile file, int64 offset, - char* buffer, int bytes_to_read, - base::FileUtilProxy::ReadWriteCallback* callback) + base::FileUtilProxy::ReadCallback* callback) : file_(file), offset_(offset), - buffer_(buffer), + buffer_(new char[bytes_to_read]), bytes_to_read_(bytes_to_read), callback_(callback), bytes_read_(0) { @@ -538,7 +537,7 @@ class RelayRead : public MessageLoopRelay { protected: virtual void RunWork() { - bytes_read_ = base::ReadPlatformFile(file_, offset_, buffer_, + bytes_read_ = base::ReadPlatformFile(file_, offset_, buffer_.get(), bytes_to_read_); if (bytes_read_ < 0) set_error_code(base::PLATFORM_FILE_ERROR_FAILED); @@ -546,7 +545,7 @@ class RelayRead : public MessageLoopRelay { virtual void RunCallback() { if (callback_) { - callback_->Run(error_code(), bytes_read_); + callback_->Run(error_code(), buffer_.get(), bytes_read_); delete callback_; } } @@ -554,9 +553,9 @@ class RelayRead : public MessageLoopRelay { private: base::PlatformFile file_; int64 offset_; - char* buffer_; + scoped_array buffer_; int bytes_to_read_; - base::FileUtilProxy::ReadWriteCallback* callback_; + base::FileUtilProxy::ReadCallback* callback_; int bytes_read_; }; @@ -566,17 +565,18 @@ class RelayWrite : public MessageLoopRelay { int64 offset, const char* buffer, int bytes_to_write, - base::FileUtilProxy::ReadWriteCallback* callback) + base::FileUtilProxy::WriteCallback* callback) : file_(file), offset_(offset), - buffer_(buffer), + buffer_(new char[bytes_to_write]), bytes_to_write_(bytes_to_write), callback_(callback) { + memcpy(buffer_.get(), buffer, bytes_to_write); } protected: virtual void RunWork() { - bytes_written_ = base::WritePlatformFile(file_, offset_, buffer_, + bytes_written_ = base::WritePlatformFile(file_, offset_, buffer_.get(), bytes_to_write_); if (bytes_written_ < 0) set_error_code(base::PLATFORM_FILE_ERROR_FAILED); @@ -592,9 +592,9 @@ class RelayWrite : public MessageLoopRelay { private: base::PlatformFile file_; int64 offset_; - const char* buffer_; + scoped_array buffer_; int bytes_to_write_; - base::FileUtilProxy::ReadWriteCallback* callback_; + base::FileUtilProxy::WriteCallback* callback_; int bytes_written_; }; @@ -843,11 +843,10 @@ bool FileUtilProxy::Read( scoped_refptr message_loop_proxy, PlatformFile file, int64 offset, - char* buffer, int bytes_to_read, - ReadWriteCallback* callback) { + ReadCallback* callback) { return Start(FROM_HERE, message_loop_proxy, - new RelayRead(file, offset, buffer, bytes_to_read, callback)); + new RelayRead(file, offset, bytes_to_read, callback)); } // static @@ -857,7 +856,7 @@ bool FileUtilProxy::Write( int64 offset, const char* buffer, int bytes_to_write, - ReadWriteCallback* callback) { + WriteCallback* callback) { return Start(FROM_HERE, message_loop_proxy, new RelayWrite(file, offset, buffer, bytes_to_write, callback)); } diff --git a/base/file_util_proxy.h b/base/file_util_proxy.h index b5e28c0..f2368cc 100644 --- a/base/file_util_proxy.h +++ b/base/file_util_proxy.h @@ -46,8 +46,11 @@ class FileUtilProxy { >::Type GetFileInfoCallback; typedef Callback2&>::Type ReadDirectoryCallback; + typedef Callback3::Type ReadCallback; typedef Callback2::Type ReadWriteCallback; + int /* bytes written */>::Type WriteCallback; // Creates or opens a file with the given flags. It is invalid to pass NULL // for the callback. @@ -149,9 +152,8 @@ class FileUtilProxy { scoped_refptr message_loop_proxy, PlatformFile file, int64 offset, - char* buffer, int bytes_to_read, - ReadWriteCallback* callback); + ReadCallback* callback); // Writes to a file. If |offset| is greater than the length of the file, // |false| is returned. On success, the file pointer is moved to position @@ -162,7 +164,7 @@ class FileUtilProxy { int64 offset, const char* buffer, int bytes_to_write, - ReadWriteCallback* callback); + WriteCallback* callback); // Touches a file. The callback can be NULL. static bool Touch( -- cgit v1.1