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 --- webkit/plugins/ppapi/ppb_file_io_impl.cc | 36 +++++++++++++++++++++++++------- webkit/plugins/ppapi/ppb_file_io_impl.h | 8 +++++-- 2 files changed, 35 insertions(+), 9 deletions(-) (limited to 'webkit/plugins/ppapi') diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.cc b/webkit/plugins/ppapi/ppb_file_io_impl.cc index ac8004b..fab8c7b 100644 --- a/webkit/plugins/ppapi/ppb_file_io_impl.cc +++ b/webkit/plugins/ppapi/ppb_file_io_impl.cc @@ -205,7 +205,8 @@ PPB_FileIO_Impl::PPB_FileIO_Impl(PluginInstance* instance) ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), file_(base::kInvalidPlatformFileValue), callback_(), - info_(NULL) { + info_(NULL), + read_buffer_(NULL) { } PPB_FileIO_Impl::~PPB_FileIO_Impl() { @@ -311,10 +312,14 @@ int32_t PPB_FileIO_Impl::Read(int64_t offset, if (rv != PP_OK) return rv; + // If |read_buffer__|, a callback should be pending (caught above). + DCHECK(!read_buffer_); + read_buffer_ = buffer; + if (!base::FileUtilProxy::Read( instance()->delegate()->GetFileThreadMessageLoopProxy(), - file_, offset, buffer, bytes_to_read, - callback_factory_.NewCallback(&PPB_FileIO_Impl::ReadWriteCallback))) + file_, offset, bytes_to_read, + callback_factory_.NewCallback(&PPB_FileIO_Impl::ReadCallback))) return PP_ERROR_FAILED; RegisterCallback(callback); @@ -332,7 +337,7 @@ int32_t PPB_FileIO_Impl::Write(int64_t offset, if (!base::FileUtilProxy::Write( instance()->delegate()->GetFileThreadMessageLoopProxy(), file_, offset, buffer, bytes_to_write, - callback_factory_.NewCallback(&PPB_FileIO_Impl::ReadWriteCallback))) + callback_factory_.NewCallback(&PPB_FileIO_Impl::WriteCallback))) return PP_ERROR_FAILED; RegisterCallback(callback); @@ -469,12 +474,29 @@ void PPB_FileIO_Impl::QueryInfoCallback( RunPendingCallback(PlatformFileErrorToPepperError(error_code)); } -void PPB_FileIO_Impl::ReadWriteCallback(base::PlatformFileError error_code, - int bytes_read_or_written) { +void PPB_FileIO_Impl::ReadCallback(base::PlatformFileError error_code, + const char* data, int bytes_read) { + DCHECK(data); + DCHECK(read_buffer_); + + int rv; + if (error_code == base::PLATFORM_FILE_OK) { + rv = bytes_read; + if (file_ != base::kInvalidPlatformFileValue) + memcpy(read_buffer_, data, bytes_read); + } else + rv = PlatformFileErrorToPepperError(error_code); + + read_buffer_ = NULL; + RunPendingCallback(rv); +} + +void PPB_FileIO_Impl::WriteCallback(base::PlatformFileError error_code, + int bytes_written) { if (error_code != base::PLATFORM_FILE_OK) RunPendingCallback(PlatformFileErrorToPepperError(error_code)); else - RunPendingCallback(bytes_read_or_written); + RunPendingCallback(bytes_written); } } // namespace ppapi diff --git a/webkit/plugins/ppapi/ppb_file_io_impl.h b/webkit/plugins/ppapi/ppb_file_io_impl.h index 3786540..3bc2742 100644 --- a/webkit/plugins/ppapi/ppb_file_io_impl.h +++ b/webkit/plugins/ppapi/ppb_file_io_impl.h @@ -95,8 +95,9 @@ class PPB_FileIO_Impl : public Resource { base::PlatformFile file); void QueryInfoCallback(base::PlatformFileError error_code, const base::PlatformFileInfo& file_info); - void ReadWriteCallback(base::PlatformFileError error_code, - int bytes_read_or_written); + void ReadCallback(base::PlatformFileError error_code, + const char* data, int bytes_read); + void WriteCallback(base::PlatformFileError error_code, int bytes_written); base::ScopedCallbackFactory callback_factory_; @@ -110,6 +111,9 @@ class PPB_FileIO_Impl : public Resource { // pending for it. PP_FileInfo_Dev* info_; + // Pointer back to the caller's read buffer; used by |Read()|. Not owned. + char* read_buffer_; + DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Impl); }; -- cgit v1.1