diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-28 06:00:57 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-28 06:00:57 +0000 |
commit | f5f22386b9413ce39b7e3cc7e718f652969f01e2 (patch) | |
tree | e6c22a764514c091e0b8cd89e86633e39150cd40 /ppapi | |
parent | 99c1289d8b178ffd9f0599306ce2b7a2b6e51907 (diff) | |
download | chromium_src-f5f22386b9413ce39b7e3cc7e718f652969f01e2.zip chromium_src-f5f22386b9413ce39b7e3cc7e718f652969f01e2.tar.gz chromium_src-f5f22386b9413ce39b7e3cc7e718f652969f01e2.tar.bz2 |
Revert 242659 "Do PPB_FileIO Write on the plugin side."
This seems to have introduced a static initializer on Mac:
http://build.chromium.org/p/chromium/builders/Mac/builds/24153/steps/sizes/logs/stdio
It identifies one in:
../../components/nacl/loader/nacl_ipc_adapter.cc
/Volumes/data/b/build/slave/Mac/build/src/out/Release/libnacl.a(nacl.nacl_ipc_adapter.o)
> Do PPB_FileIO Write on the plugin side.
>
> This eliminates IPC for FileIO.Write, instead using the plugin's file descriptor.
> Performs the file op on the plugin's thread if blocking, otherwise on the file
> thread.
>
> FileIOResources know their maximum written offset after they are opened.
> They can thus calculate whether a Write or SetLength operation will extend
> this max offset. If so, they call FileSystemResource::RequestQuota. This can
> return synchronously or asynchronously, and either returns the requested
> amount or 0 in case it can't be satisfied.
>
> FileSystemResource will request a quota reservation from the host, queuing
> up unsatisfied requests. The quota reservation will be at least 1MB with this
> CL. The main point of a quota reservation is to reduce the number of times
> we query the quota system.
>
> Both the FileSystemResource and the host maintain a collection of open files
> that are subject to quota. These are kept in sync. Maps that take PP_Resource
> to resource or host are used to ensure good performance and make it easier
> to keep the resource and host collections synced.
>
> SetLength uses the plugin side machinery to request quota. When its request
> is granted, it calls over to the host side as before. This is because of OS X
> sandbox restrictions.
>
> For trusted plugins, I assume that this plugin / host checking is sufficient. In
> particular, SetLength is performed in the browser process without checking
> the length against quota restrictions. We're essentially assuming trusted
> plugins don't cheat.
>
> For untrusted plugins, this approach isn't sufficient. NaClMessageScanner
> audits the FIleSystem and FileIO message traffic to maintain a parallel
> accounting of quota reservation and current file sizes. In addition, we wrap
> the native file handle in a NaClDescQuota for files that need quota checking.
> This NaClDescQuota uses NaClMessageScanner information to determine
> whether or not to allow a Write. We must check at the descriptor level since
> the untrusted plugin may bypass our proxy code and use the file handle
> directly to Write. We must also fail any attempt to call ftruncate directly.
>
> BUG=194304
>
> Review URL: https://codereview.chromium.org/100703004
TBR=bbudge@chromium.org
Review URL: https://codereview.chromium.org/122013002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242670 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/ppapi_tests.gypi | 3 | ||||
-rw-r--r-- | ppapi/proxy/file_io_resource.cc | 231 | ||||
-rw-r--r-- | ppapi/proxy/file_io_resource.h | 53 | ||||
-rw-r--r-- | ppapi/proxy/file_system_resource.cc | 109 | ||||
-rw-r--r-- | ppapi/proxy/file_system_resource.h | 28 | ||||
-rw-r--r-- | ppapi/proxy/nacl_message_scanner.cc | 269 | ||||
-rw-r--r-- | ppapi/proxy/nacl_message_scanner.h | 66 | ||||
-rw-r--r-- | ppapi/proxy/nacl_message_scanner_unittest.cc | 293 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 20 | ||||
-rw-r--r-- | ppapi/thunk/ppb_file_io_api.h | 2 | ||||
-rw-r--r-- | ppapi/thunk/ppb_file_system_api.h | 6 |
11 files changed, 48 insertions, 1032 deletions
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 9a4dd52..0b4570a 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -174,7 +174,6 @@ 'proxy/interface_list_unittest.cc', 'proxy/mock_resource.cc', 'proxy/mock_resource.h', - 'proxy/nacl_message_scanner_unittest.cc', 'proxy/pdf_resource_unittest.cc', 'proxy/plugin_dispatcher_unittest.cc', 'proxy/plugin_resource_tracker_unittest.cc', @@ -208,7 +207,7 @@ }], ], # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - 'msvs_disabled_warnings': [ 4267, ], + 'msvs_disabled_warnings': [ 4267, ], }, { 'target_name': 'ppapi_example_skeleton', diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc index e86c321..ad07187 100644 --- a/ppapi/proxy/file_io_resource.cc +++ b/ppapi/proxy/file_io_resource.cc @@ -80,39 +80,9 @@ int32_t FileIOResource::ReadOp::DoWork() { file_handle_->raw_handle(), offset_, buffer_.get(), bytes_to_read_); } -FileIOResource::WriteOp::WriteOp(scoped_refptr<FileHandleHolder> file_handle, - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - bool append) - : file_handle_(file_handle), - offset_(offset), - buffer_(buffer), - bytes_to_write_(bytes_to_write), - append_(append) { -} - -FileIOResource::WriteOp::~WriteOp() { -} - -int32_t FileIOResource::WriteOp::DoWork() { - // We can't just call WritePlatformFile in append mode, since NaCl doesn't - // implement fcntl, causing the function to call pwrite, which is incorrect. - if (append_) { - return base::WritePlatformFileAtCurrentPos( - file_handle_->raw_handle(), buffer_, bytes_to_write_); - } else { - return base::WritePlatformFile( - file_handle_->raw_handle(), offset_, buffer_, bytes_to_write_); - } -} - FileIOResource::FileIOResource(Connection connection, PP_Instance instance) : PluginResource(connection, instance), file_system_type_(PP_FILESYSTEMTYPE_INVALID), - open_flags_(0), - max_written_offset_(0), - check_quota_(false), called_close_(false) { SendCreate(BROWSER, PpapiHostMsg_FileIO_Create()); } @@ -143,7 +113,6 @@ int32_t FileIOResource::Open(PP_Resource file_ref, if (rv != PP_OK) return rv; - open_flags_ = open_flags; file_system_type_ = create_info.file_system_type; if (create_info.file_system_plugin_resource) { @@ -270,42 +239,22 @@ int32_t FileIOResource::Write(int64_t offset, const char* buffer, int32_t bytes_to_write, scoped_refptr<TrackedCallback> callback) { - if (!buffer) - return PP_ERROR_FAILED; - if (bytes_to_write < 0) - return PP_ERROR_FAILED; - if (!FileHandleHolder::IsValid(file_handle_)) - return PP_ERROR_FAILED; - int32_t rv = state_manager_.CheckOperationState( FileIOStateManager::OPERATION_WRITE, true); if (rv != PP_OK) return rv; - state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); + // TODO(brettw) it would be nice to use a shared memory buffer for large + // writes rather than having to copy to a string (which will involve a number + // of extra copies to serialize over IPC). + bytes_to_write = std::min(bytes_to_write, kMaxReadWriteSize); + Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, + PpapiHostMsg_FileIO_Write(offset, std::string(buffer, bytes_to_write)), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); - if (check_quota_) { - int64_t actual_offset = - (open_flags_ & PP_FILEOPENFLAG_APPEND) ? max_written_offset_ : offset; - - uint64_t max_offset = actual_offset + bytes_to_write; - if (max_offset > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) - return PP_ERROR_FAILED; // amount calculation would overflow. - int64_t increase = static_cast<int64_t>(max_offset) - max_written_offset_; - if (increase > 0) { - int64_t result = - file_system_resource_->AsPPB_FileSystem_API()->RequestQuota( - increase, - base::Bind(&FileIOResource::OnRequestWriteQuotaComplete, - this, - offset, buffer, bytes_to_write, callback)); - if (result == PP_OK_COMPLETIONPENDING) - return PP_OK_COMPLETIONPENDING; - DCHECK(result == increase); - max_written_offset_ = max_offset; - } - } - return WriteValidated(offset, buffer, bytes_to_write, callback); + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE); + return PP_OK_COMPLETIONPENDING; } int32_t FileIOResource::SetLength(int64_t length, @@ -314,30 +263,13 @@ int32_t FileIOResource::SetLength(int64_t length, FileIOStateManager::OPERATION_EXCLUSIVE, true); if (rv != PP_OK) return rv; - if (length < 0) - return PP_ERROR_FAILED; - if (check_quota_) { - int64_t increase = length - max_written_offset_; - if (increase > 0) { - int32_t result = - file_system_resource_->AsPPB_FileSystem_API()->RequestQuota( - increase, - base::Bind(&FileIOResource::OnRequestSetLengthQuotaComplete, - this, - length, callback)); - if (result == PP_OK_COMPLETIONPENDING) { - state_manager_.SetPendingOperation( - FileIOStateManager::OPERATION_EXCLUSIVE); - return PP_OK_COMPLETIONPENDING; - } - DCHECK(result == increase); - max_written_offset_ = length; - } - } + Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, + PpapiHostMsg_FileIO_SetLength(length), + base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, + callback)); state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); - SetLengthValidated(length, callback); return PP_OK_COMPLETIONPENDING; } @@ -356,29 +288,15 @@ int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { return PP_OK_COMPLETIONPENDING; } -int64_t FileIOResource::GetMaxWrittenOffset() const { - return max_written_offset_; -} - -void FileIOResource::SetMaxWrittenOffset(int64_t max_written_offset) { - max_written_offset_ = max_written_offset; -} - void FileIOResource::Close() { if (called_close_) return; called_close_ = true; - if (check_quota_) { - check_quota_ = false; - file_system_resource_->AsPPB_FileSystem_API()->CloseQuotaFile( - pp_resource()); - } - if (file_handle_) file_handle_ = NULL; - Post(BROWSER, PpapiHostMsg_FileIO_Close(max_written_offset_)); + Post(BROWSER, PpapiHostMsg_FileIO_Close()); } int32_t FileIOResource::RequestOSFileHandle( @@ -462,57 +380,6 @@ int32_t FileIOResource::ReadValidated(int64_t offset, return PP_OK_COMPLETIONPENDING; } -int32_t FileIOResource::WriteValidated( - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - bool append = (open_flags_ & PP_FILEOPENFLAG_APPEND) != 0; - if (callback->is_blocking()) { - int32_t result; - { - // Release the proxy lock while making a potentially slow file call. - ProxyAutoUnlock unlock; - if (append) { - result = base::WritePlatformFileAtCurrentPos( - file_handle_->raw_handle(), buffer, bytes_to_write); - } else { - result = base::WritePlatformFile( - file_handle_->raw_handle(), offset, buffer, bytes_to_write); - } - } - if (result < 0) - result = PP_ERROR_FAILED; - - state_manager_.SetOperationFinished(); - return result; - } - - // For the non-blocking case, post a task to the file thread. - scoped_refptr<WriteOp> write_op( - new WriteOp(file_handle_, offset, buffer, bytes_to_write, append)); - base::PostTaskAndReplyWithResult( - PpapiGlobals::Get()->GetFileTaskRunner(), - FROM_HERE, - Bind(&FileIOResource::WriteOp::DoWork, write_op), - RunWhileLocked(Bind(&TrackedCallback::Run, callback))); - callback->set_completion_task( - Bind(&FileIOResource::OnWriteComplete, this, write_op)); - - return PP_OK_COMPLETIONPENDING; -} - -void FileIOResource::SetLengthValidated( - int64_t length, - scoped_refptr<TrackedCallback> callback) { - Call<PpapiPluginMsg_FileIO_GeneralReply>(BROWSER, - PpapiHostMsg_FileIO_SetLength(length), - base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, - callback)); - - max_written_offset_ = length; -} - int32_t FileIOResource::OnQueryComplete(scoped_refptr<QueryOp> query_op, PP_FileInfo* info, int32_t result) { @@ -549,49 +416,6 @@ int32_t FileIOResource::OnReadComplete(scoped_refptr<ReadOp> read_op, return result; } -void FileIOResource::OnRequestWriteQuotaComplete( - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback, - int64_t granted) { - DCHECK(granted >= 0); - if (granted == 0) { - callback->Run(PP_ERROR_NOQUOTA); - return; - } - max_written_offset_ += granted; - int32_t result = WriteValidated(offset, buffer, bytes_to_write, callback); - if (result != PP_OK_COMPLETIONPENDING) - callback->Run(result); -} - -void FileIOResource::OnRequestSetLengthQuotaComplete( - int64_t length, - scoped_refptr<TrackedCallback> callback, - int64_t granted) { - DCHECK(granted >= 0); - if (granted == 0) { - callback->Run(PP_ERROR_NOQUOTA); - return; - } - - max_written_offset_ = length; - SetLengthValidated(length, callback); -} - -int32_t FileIOResource::OnWriteComplete(scoped_refptr<WriteOp> write_op, - int32_t result) { - DCHECK(state_manager_.get_pending_operation() == - FileIOStateManager::OPERATION_WRITE); - // |result| is the return value of WritePlatformFile; -1 indicates failure. - if (result < 0) - result = PP_ERROR_FAILED; - - state_manager_.SetOperationFinished(); - return result; -} - void FileIOResource::OnPluginMsgGeneralComplete( scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params) { @@ -607,31 +431,20 @@ void FileIOResource::OnPluginMsgGeneralComplete( void FileIOResource::OnPluginMsgOpenFileComplete( scoped_refptr<TrackedCallback> callback, - const ResourceMessageReplyParams& params, - PP_Resource quota_file_system, - int64_t max_written_offset) { + const ResourceMessageReplyParams& params) { DCHECK(state_manager_.get_pending_operation() == FileIOStateManager::OPERATION_EXCLUSIVE); // Release the FileRef resource. file_ref_ = NULL; - int32_t result = params.result(); - if (result == PP_OK) { + if (params.result() == PP_OK) state_manager_.SetOpenSucceed(); - if (quota_file_system) { - DCHECK(quota_file_system == file_system_resource_->pp_resource()); - check_quota_ = true; - max_written_offset_ = max_written_offset; - file_system_resource_->AsPPB_FileSystem_API()->OpenQuotaFile( - pp_resource()); - } - - IPC::PlatformFileForTransit transit_file; - if (params.TakeFileHandleAtIndex(0, &transit_file)) { - file_handle_ = new FileHandleHolder( - IPC::PlatformFileForTransitToPlatformFile(transit_file)); - } + int32_t result = params.result(); + IPC::PlatformFileForTransit transit_file; + if ((result == PP_OK) && params.TakeFileHandleAtIndex(0, &transit_file)) { + file_handle_ = new FileHandleHolder( + IPC::PlatformFileForTransitToPlatformFile(transit_file)); } // End this operation now, so the user's callback can execute another FileIO // operation, assuming there are no other pending operations. diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h index 23df0e6..bfdf24f 100644 --- a/ppapi/proxy/file_io_resource.h +++ b/ppapi/proxy/file_io_resource.h @@ -57,8 +57,6 @@ class PPAPI_PROXY_EXPORT FileIOResource scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual int32_t SetLength(int64_t length, scoped_refptr<TrackedCallback> callback) OVERRIDE; - virtual int64_t GetMaxWrittenOffset() const OVERRIDE; - virtual void SetMaxWrittenOffset(int64_t max_written_offset) OVERRIDE; virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual void Close() OVERRIDE; virtual int32_t RequestOSFileHandle( @@ -141,49 +139,10 @@ class PPAPI_PROXY_EXPORT FileIOResource scoped_ptr<char[]> buffer_; }; - // Class to perform file write operations across multiple threads. - class WriteOp : public base::RefCountedThreadSafe<WriteOp> { - public: - WriteOp(scoped_refptr<FileHandleHolder> file_handle, - int64_t offset, - const char* buffer, - int32_t bytes_to_write, - bool append); - - // Writes the file. Called on the file thread (non-blocking) or the plugin - // thread (blocking). This should not be called when we hold the proxy lock. - int32_t DoWork(); - - private: - friend class base::RefCountedThreadSafe<WriteOp>; - ~WriteOp(); - - scoped_refptr<FileHandleHolder> file_handle_; - int64_t offset_; - const char* buffer_; - int32_t bytes_to_write_; - bool append_; - }; - - void OnRequestWriteQuotaComplete(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback, - int64_t granted); - void OnRequestSetLengthQuotaComplete(int64_t length, - scoped_refptr<TrackedCallback> callback, - int64_t granted); - int32_t ReadValidated(int64_t offset, int32_t bytes_to_read, const PP_ArrayOutput& array_output, scoped_refptr<TrackedCallback> callback); - int32_t WriteValidated(int64_t offset, - const char* buffer, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback); - void SetLengthValidated(int64_t length, - scoped_refptr<TrackedCallback> callback); // Completion tasks for file operations that are done in the plugin. int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op, @@ -192,16 +151,12 @@ class PPAPI_PROXY_EXPORT FileIOResource int32_t OnReadComplete(scoped_refptr<ReadOp> read_op, PP_ArrayOutput array_output, int32_t result); - int32_t OnWriteComplete(scoped_refptr<WriteOp> write_op, - int32_t result); // Reply message handlers for operations that are done in the host. void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params); void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback, - const ResourceMessageReplyParams& params, - PP_Resource quota_file_system, - int64_t max_written_offset); + const ResourceMessageReplyParams& params); void OnPluginMsgRequestOSFileHandleComplete( scoped_refptr<TrackedCallback> callback, PP_FileHandle* output_handle, @@ -210,15 +165,11 @@ class PPAPI_PROXY_EXPORT FileIOResource scoped_refptr<FileHandleHolder> file_handle_; PP_FileSystemType file_system_type_; scoped_refptr<Resource> file_system_resource_; + bool called_close_; FileIOStateManager state_manager_; scoped_refptr<Resource> file_ref_; - int32_t open_flags_; - int64_t max_written_offset_; - bool check_quota_; - bool called_close_; - DISALLOW_COPY_AND_ASSIGN(FileIOResource); }; diff --git a/ppapi/proxy/file_system_resource.cc b/ppapi/proxy/file_system_resource.cc index 8061189..df8c390 100644 --- a/ppapi/proxy/file_system_resource.cc +++ b/ppapi/proxy/file_system_resource.cc @@ -9,26 +9,12 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/tracked_callback.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_file_io_api.h" -using ppapi::thunk::EnterResourceNoLock; -using ppapi::thunk::PPB_FileIO_API; using ppapi::thunk::PPB_FileSystem_API; namespace ppapi { namespace proxy { -FileSystemResource::QuotaRequest::QuotaRequest( - int64_t amount_arg, - const RequestQuotaCallback& callback_arg) - : amount(amount_arg), - callback(callback_arg) { -} - -FileSystemResource::QuotaRequest::~QuotaRequest() { -} - FileSystemResource::FileSystemResource(Connection connection, PP_Instance instance, PP_FileSystemType type) @@ -36,9 +22,7 @@ FileSystemResource::FileSystemResource(Connection connection, type_(type), called_open_(false), callback_count_(0), - callback_result_(PP_OK), - reserved_quota_(0), - reserving_quota_(false) { + callback_result_(PP_OK) { DCHECK(type_ != PP_FILESYSTEMTYPE_INVALID); SendCreate(RENDERER, PpapiHostMsg_FileSystem_Create(type_)); SendCreate(BROWSER, PpapiHostMsg_FileSystem_Create(type_)); @@ -53,9 +37,7 @@ FileSystemResource::FileSystemResource(Connection connection, type_(type), called_open_(true), callback_count_(0), - callback_result_(PP_OK), - reserved_quota_(0), - reserving_quota_(false) { + callback_result_(PP_OK) { DCHECK(type_ != PP_FILESYSTEMTYPE_INVALID); AttachToPendingHost(RENDERER, pending_renderer_id); AttachToPendingHost(BROWSER, pending_browser_id); @@ -92,39 +74,6 @@ PP_FileSystemType FileSystemResource::GetType() { return type_; } -void FileSystemResource::OpenQuotaFile(PP_Resource file_io) { - DCHECK(max_written_offsets_.find(file_io) == max_written_offsets_.end()); - EnterResourceNoLock<PPB_FileIO_API> enter(file_io, true); - DCHECK(!enter.failed()); - PPB_FileIO_API* file_io_api = enter.object(); - max_written_offsets_[file_io] = file_io_api->GetMaxWrittenOffset(); -} - -void FileSystemResource::CloseQuotaFile(PP_Resource file_io) { - OffsetMap::iterator it = max_written_offsets_.find(file_io); - DCHECK(it != max_written_offsets_.end()); - max_written_offsets_.erase(it); -} - -int64_t FileSystemResource::RequestQuota( - int64_t amount, - const RequestQuotaCallback& callback) { - DCHECK(amount >= 0); - if (!reserving_quota_ && reserved_quota_ >= amount) { - reserved_quota_ -= amount; - return amount; - } - - // Queue up a pending quota request. - pending_quota_requests_.push(QuotaRequest(amount, callback)); - - // Reserve more quota if we haven't already. - if (!reserving_quota_) - ReserveQuota(amount); - - return PP_OK_COMPLETIONPENDING; -} - int32_t FileSystemResource::InitIsolatedFileSystem( const std::string& fsid, PP_IsolatedFileSystemType_Private type, @@ -173,59 +122,5 @@ void FileSystemResource::InitIsolatedFileSystemComplete( callback.Run(callback_result_); } -void FileSystemResource::ReserveQuota(int64_t amount) { - DCHECK(!reserving_quota_); - reserving_quota_ = true; - for (OffsetMap::iterator it = max_written_offsets_.begin(); - it != max_written_offsets_.end(); ++it) { - EnterResourceNoLock<PPB_FileIO_API> enter(it->first, true); - DCHECK(!enter.failed()); - PPB_FileIO_API* file_io_api = enter.object(); - it->second = file_io_api->GetMaxWrittenOffset(); - } - Call<PpapiPluginMsg_FileSystem_ReserveQuotaReply>(BROWSER, - PpapiHostMsg_FileSystem_ReserveQuota(amount, max_written_offsets_), - base::Bind(&FileSystemResource::ReserveQuotaComplete, - this)); -} - -void FileSystemResource::ReserveQuotaComplete( - const ResourceMessageReplyParams& params, - int64_t amount, - const OffsetMap& max_written_offsets) { - DCHECK(reserving_quota_); - reserving_quota_ = false; - reserved_quota_ = amount; - - for (OffsetMap::const_iterator it = max_written_offsets.begin(); - it != max_written_offsets.end(); ++it) { - EnterResourceNoLock<PPB_FileIO_API> enter(it->first, true); - DCHECK(!enter.failed()); - PPB_FileIO_API* file_io_api = enter.object(); - file_io_api->SetMaxWrittenOffset(it->second); - } - - DCHECK(!pending_quota_requests_.empty()); - // If we can't grant the first request after refreshing reserved_quota_, then - // fail all pending quota requests to avoid an infinite refresh/fail loop. - bool fail_all = reserved_quota_ < pending_quota_requests_.front().amount; - while (!pending_quota_requests_.empty()) { - QuotaRequest& request = pending_quota_requests_.front(); - if (fail_all) { - request.callback.Run(0); - pending_quota_requests_.pop(); - } else if (reserved_quota_ >= request.amount) { - reserved_quota_ -= request.amount; - request.callback.Run(request.amount); - pending_quota_requests_.pop(); - } else { - // Refresh the quota reservation for the first pending request that we - // can't satisfy. - ReserveQuota(request.amount); - break; - } - } -} - } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/file_system_resource.h b/ppapi/proxy/file_system_resource.h index e3e22b1..9029583 100644 --- a/ppapi/proxy/file_system_resource.h +++ b/ppapi/proxy/file_system_resource.h @@ -5,13 +5,10 @@ #ifndef PPAPI_PROXY_FILE_SYSTEM_RESOURCE_H_ #define PPAPI_PROXY_FILE_SYSTEM_RESOURCE_H_ -#include <map> -#include <queue> #include <string> #include "base/memory/ref_counted.h" #include "ppapi/c/pp_file_info.h" -#include "ppapi/c/pp_resource.h" #include "ppapi/c/private/ppb_isolated_file_system_private.h" #include "ppapi/proxy/connection.h" #include "ppapi/proxy/plugin_resource.h" @@ -51,25 +48,11 @@ class PPAPI_PROXY_EXPORT FileSystemResource virtual int32_t Open(int64_t expected_size, scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual PP_FileSystemType GetType() OVERRIDE; - virtual void OpenQuotaFile(PP_Resource file_io) OVERRIDE; - virtual void CloseQuotaFile(PP_Resource file_io) OVERRIDE; - typedef base::Callback<void(int64_t)> RequestQuotaCallback; - virtual int64_t RequestQuota(int64_t amount, - const RequestQuotaCallback& callback) OVERRIDE; int32_t InitIsolatedFileSystem(const std::string& fsid, PP_IsolatedFileSystemType_Private type, const base::Callback<void(int32_t)>& callback); private: - struct QuotaRequest { - QuotaRequest(int64_t amount, - const RequestQuotaCallback& callback); - ~QuotaRequest(); - - int64_t amount; - RequestQuotaCallback callback; - }; - // Called when the host has responded to our open request. void OpenComplete(scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params); @@ -79,22 +62,11 @@ class PPAPI_PROXY_EXPORT FileSystemResource const base::Callback<void(int32_t)>& callback, const ResourceMessageReplyParams& params); - void ReserveQuota(int64_t amount); - typedef std::map<int32_t, int64_t> OffsetMap; - void ReserveQuotaComplete(const ResourceMessageReplyParams& params, - int64_t amount, - const OffsetMap& max_written_offsets); - PP_FileSystemType type_; bool called_open_; uint32_t callback_count_; int32_t callback_result_; - OffsetMap max_written_offsets_; - std::queue<QuotaRequest> pending_quota_requests_; - int64_t reserved_quota_; - bool reserving_quota_; - DISALLOW_COPY_AND_ASSIGN(FileSystemResource); }; diff --git a/ppapi/proxy/nacl_message_scanner.cc b/ppapi/proxy/nacl_message_scanner.cc index 3c2b45f8..602b18e 100644 --- a/ppapi/proxy/nacl_message_scanner.cc +++ b/ppapi/proxy/nacl_message_scanner.cc @@ -19,16 +19,12 @@ namespace IPC { class Message; } -using ppapi::proxy::ResourceMessageReplyParams; -using ppapi::proxy::SerializedHandle; -using ppapi::proxy::SerializedVar; - namespace { -typedef std::vector<SerializedHandle> Handles; +typedef std::vector<ppapi::proxy::SerializedHandle> Handles; struct ScanningResults { - ScanningResults() : handle_index(0), pp_resource(0) {} + ScanningResults() : handle_index(0) {} // Vector to hold handles found in the message. Handles handles; @@ -40,18 +36,12 @@ struct ScanningResults { // may set this to NULL when it can determine that there are no parameters // that need conversion. (See the ResourceMessageReplyParams overload.) scoped_ptr<IPC::Message> new_msg; - // Resource id for resource messages. Save this when scanning resource replies - // so when we audit the nested message, we know which resource it is for. - PP_Resource pp_resource; - // Callback to receive the nested message in a resource message or reply. - base::Callback<void(PP_Resource, const IPC::Message&, SerializedHandle*)> - nested_msg_callback; }; void WriteHandle(int handle_index, - const SerializedHandle& handle, + const ppapi::proxy::SerializedHandle& handle, IPC::Message* msg) { - SerializedHandle::WriteHeader(handle.header(), msg); + ppapi::proxy::SerializedHandle::WriteHeader(handle.header(), msg); // Now write the handle itself in POSIX style. msg->WriteBool(true); // valid == true @@ -62,7 +52,8 @@ void WriteHandle(int handle_index, // handling. See ScanTuple for how these get used. // Overload to match SerializedHandle. -void ScanParam(const SerializedHandle& handle, ScanningResults* results) { +void ScanParam(const ppapi::proxy::SerializedHandle& handle, + ScanningResults* results) { results->handles.push_back(handle); if (results->new_msg) WriteHandle(results->handle_index++, handle, results->new_msg.get()); @@ -70,13 +61,14 @@ void ScanParam(const SerializedHandle& handle, ScanningResults* results) { void HandleWriter(int* handle_index, IPC::Message* m, - const SerializedHandle& handle) { + const ppapi::proxy::SerializedHandle& handle) { WriteHandle((*handle_index)++, handle, m); } // Overload to match SerializedVar, which can contain handles. -void ScanParam(const SerializedVar& var, ScanningResults* results) { - std::vector<SerializedHandle*> var_handles = var.GetHandles(); +void ScanParam(const ppapi::proxy::SerializedVar& var, + ScanningResults* results) { + std::vector<ppapi::proxy::SerializedHandle*> var_handles = var.GetHandles(); // Copy any handles and then rewrite the message. for (size_t i = 0; i < var_handles.size(); ++i) results->handles.push_back(*var_handles[i]); @@ -90,9 +82,8 @@ void ScanParam(const SerializedVar& var, ScanningResults* results) { // NOTE: We only intercept handles from host->NaCl. The only kind of // ResourceMessageParams that travels this direction is // ResourceMessageReplyParams, so that's the only one we need to handle. -void ScanParam(const ResourceMessageReplyParams& params, +void ScanParam(const ppapi::proxy::ResourceMessageReplyParams& params, ScanningResults* results) { - results->pp_resource = params.pp_resource(); // If the resource reply params don't contain handles, NULL the new message // pointer to cancel further rewriting. // NOTE: This works because only handles currently need rewriting, and we @@ -121,21 +112,8 @@ void ScanParam(const ResourceMessageReplyParams& params, params.ConsumeHandles(); } -// Overload to match nested messages. If we need to rewrite the message, write -// the parameter. -void ScanParam(const IPC::Message& param, ScanningResults* results) { - if (results->pp_resource && !results->nested_msg_callback.is_null()) { - SerializedHandle* handle = NULL; - if (results->handles.size() == 1) - handle = &results->handles[0]; - results->nested_msg_callback.Run(results->pp_resource, param, handle); - } - if (results->new_msg) - IPC::WriteParam(results->new_msg.get(), param); -} - -// Overload to match all other types. If we need to rewrite the message, write -// the parameter. +// Overload to match all other types. If we need to rewrite the message, +// write the parameter. template <class T> void ScanParam(const T& param, ScanningResults* results) { if (results->new_msg) @@ -233,58 +211,9 @@ namespace proxy { class SerializedHandle; -NaClMessageScanner::FileSystem::FileSystem() - : reserved_quota_(0) { -} - -NaClMessageScanner::FileSystem::~FileSystem() { -} - -bool NaClMessageScanner::FileSystem::UpdateReservedQuota(int64_t delta) { - base::AutoLock lock(lock_); - if (std::numeric_limits<int64_t>::max() - reserved_quota_ < delta) - return false; // reserved_quota_ + delta would overflow. - if (reserved_quota_ + delta < 0) - return false; - reserved_quota_ += delta; - return true; -} - -NaClMessageScanner::FileIO::FileIO(FileSystem* file_system, - int64_t max_written_offset) - : file_system_(file_system), - max_written_offset_(max_written_offset) { -} - -NaClMessageScanner::FileIO::~FileIO() { -} - -void NaClMessageScanner::FileIO::SetMaxWrittenOffset( - int64_t max_written_offset) { - base::AutoLock lock(lock_); - max_written_offset_ = max_written_offset; -} - -bool NaClMessageScanner::FileIO::Grow(int64_t amount) { - base::AutoLock lock(lock_); - DCHECK(amount > 0); - if (!file_system_->UpdateReservedQuota(-amount)) - return false; - max_written_offset_ += amount; - return true; -} - NaClMessageScanner::NaClMessageScanner() { } -NaClMessageScanner::~NaClMessageScanner() { - for (FileSystemMap::iterator it = file_systems_.begin(); - it != file_systems_.end(); ++it) - delete it->second; - for (FileIOMap::iterator it = files_.begin(); it != files_.end(); ++it) - delete it->second; -} - // Windows IPC differs from POSIX in that native handles are serialized in the // message body, rather than passed in a separate FileDescriptorSet. Therefore, // on Windows, any message containing handles must be rewritten in the POSIX @@ -310,14 +239,12 @@ bool NaClMessageScanner::ScanMessage( (msg.type() == PpapiMsg_CreateNaClChannel::ID); #endif + // We can't always tell from the message ID if rewriting is needed. Therefore, // scan any message types that might contain a handle. If we later determine // that there are no handles, we can cancel the rewriting by clearing the // results.new_msg pointer. ScanningResults results; - results.nested_msg_callback = - base::Bind(&NaClMessageScanner::AuditNestedMessage, - base::Unretained(this)); switch (msg.type()) { CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel) CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) @@ -363,113 +290,8 @@ void NaClMessageScanner::ScanUntrustedMessage( scoped_ptr<IPC::Message>* new_msg_ptr) { if (untrusted_msg.is_sync()) RegisterSyncMessageForReply(untrusted_msg); - - // Audit FileIO and FileSystem messages to ensure that the plugin doesn't - // exceed its file quota. If we find the message is malformed, just pass it - // through - we only care about well formed messages to the host. - if (untrusted_msg.type() == PpapiHostMsg_ResourceCall::ID) { - ResourceMessageCallParams params; - IPC::Message nested_msg; - if (!UnpackMessage<PpapiHostMsg_ResourceCall>( - untrusted_msg, ¶ms, &nested_msg)) - return; - - switch (nested_msg.type()) { - case PpapiHostMsg_FileIO_Close::ID: { - FileIOMap::iterator it = files_.find(params.pp_resource()); - if (it == files_.end()) - return; - // Audit FileIO Close messages to make sure the plugin reports an - // accurate file size. - int64_t max_written_offset = 0; - if (!UnpackMessage<PpapiHostMsg_FileIO_Close>( - nested_msg, &max_written_offset)) - return; - - int64_t trusted_max_written_offset = it->second->max_written_offset(); - delete it->second; - files_.erase(it); - // If the plugin is under-reporting, rewrite the message with the - // trusted value. - if (trusted_max_written_offset > max_written_offset) { - new_msg_ptr->reset( - new PpapiHostMsg_ResourceCall( - params, - PpapiHostMsg_FileIO_Close(trusted_max_written_offset))); - } - } - case PpapiHostMsg_FileIO_SetLength::ID: { - FileIOMap::iterator it = files_.find(params.pp_resource()); - if (it == files_.end()) - return; - // Audit FileIO SetLength messages to make sure the plugin is within - // the current quota reservation. In addition, deduct the file size - // increase from the quota reservation. - int64_t length = 0; - if (!UnpackMessage<PpapiHostMsg_FileIO_SetLength>( - nested_msg, &length)) - return; - - // Calculate file size increase, taking care to avoid overflows. - if (length < 0) - return; - int64_t trusted_max_written_offset = it->second->max_written_offset(); - int64_t increase = length - trusted_max_written_offset; - if (increase <= 0) - return; - if (!it->second->Grow(increase)) { - new_msg_ptr->reset( - new PpapiHostMsg_ResourceCall( - params, - PpapiHostMsg_FileIO_SetLength(-1))); - } - break; - } - case PpapiHostMsg_FileSystem_ReserveQuota::ID: { - // Audit FileSystem ReserveQuota messages to make sure the plugin - // reports accurate file sizes. - int64_t amount = 0; - FileOffsetMap max_written_offsets; - if (!UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>( - nested_msg, &amount, &max_written_offsets)) - return; - - bool audit_failed = false; - for (FileOffsetMap::iterator it = max_written_offsets.begin(); - it != max_written_offsets.end(); ++it) { - FileIOMap::iterator file_it = files_.find(it->first); - if (file_it == files_.end()) - continue; - int64_t trusted_max_written_offset = - file_it->second->max_written_offset(); - if (trusted_max_written_offset > it->second) { - audit_failed = true; - it->second = trusted_max_written_offset; - } - } - if (audit_failed) { - new_msg_ptr->reset( - new PpapiHostMsg_ResourceCall( - params, - PpapiHostMsg_FileSystem_ReserveQuota( - amount, max_written_offsets))); - } - break; - } - case PpapiHostMsg_ResourceDestroyed::ID: { - // Audit resource destroyed messages to release FileSystems. - PP_Resource resource; - if (!UnpackMessage<PpapiHostMsg_ResourceDestroyed>( - nested_msg, &resource)) - return; - FileSystemMap::iterator fs_it = file_systems_.find(resource); - if (fs_it != file_systems_.end()) { - delete fs_it->second; - file_systems_.erase(fs_it); - } - } - } - } + // TODO(bbudge) Add message auditing for FileSystem and FileIO resources when + // we implement Write on the plugin side of the proxy. See crbug.com/194304. } void NaClMessageScanner::RegisterSyncMessageForReply(const IPC::Message& msg) { @@ -479,64 +301,5 @@ void NaClMessageScanner::RegisterSyncMessageForReply(const IPC::Message& msg) { pending_sync_msgs_[msg_id] = msg.type(); } -NaClMessageScanner::FileIO* NaClMessageScanner::GetFile( - PP_Resource file_io) { - FileIOMap::iterator it = files_.find(file_io); - DCHECK(it != files_.end()); - return it->second; -} - -void NaClMessageScanner::AuditNestedMessage(PP_Resource resource, - const IPC::Message& msg, - SerializedHandle* handle) { - switch (msg.type()) { - case PpapiPluginMsg_FileIO_OpenReply::ID: { - // A file that requires quota checking was opened. - PP_Resource quota_file_system; - int64_t max_written_offset = 0; - if (ppapi::UnpackMessage<PpapiPluginMsg_FileIO_OpenReply>( - msg, "a_file_system, &max_written_offset)) { - if (quota_file_system) { - // Look up the FileSystem by inserting a new one. If it was already - // present, get the existing one, otherwise construct it. - FileSystem* file_system = NULL; - std::pair<FileSystemMap::iterator, bool> insert_result = - file_systems_.insert(std::make_pair(quota_file_system, - file_system)); - if (insert_result.second) - insert_result.first->second = new FileSystem(); - file_system = insert_result.first->second; - // Create the FileIO. - DCHECK(files_.find(resource) == files_.end()); - files_.insert(std::make_pair( - resource, - new FileIO(file_system, max_written_offset))); - } - } - break; - } - case PpapiPluginMsg_FileSystem_ReserveQuotaReply::ID: { - // The amount of reserved quota for a FileSystem was refreshed. - int64_t amount = 0; - FileOffsetMap max_written_offsets; - if (ppapi::UnpackMessage<PpapiPluginMsg_FileSystem_ReserveQuotaReply>( - msg, &amount, &max_written_offsets)) { - FileSystemMap::iterator it = file_systems_.find(resource); - DCHECK(it != file_systems_.end()); - it->second->UpdateReservedQuota(amount); - - FileOffsetMap::const_iterator offset_it = max_written_offsets.begin(); - for (; offset_it != max_written_offsets.end(); ++offset_it) { - FileIOMap::iterator fio_it = files_.find(offset_it->first); - DCHECK(fio_it != files_.end()); - if (fio_it != files_.end()) - fio_it->second->SetMaxWrittenOffset(offset_it->second); - } - } - break; - } - } -} - } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/nacl_message_scanner.h b/ppapi/proxy/nacl_message_scanner.h index d1360b7..8704160 100644 --- a/ppapi/proxy/nacl_message_scanner.h +++ b/ppapi/proxy/nacl_message_scanner.h @@ -10,8 +10,6 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "base/synchronization/lock.h" -#include "ppapi/c/pp_resource.h" #include "ppapi/proxy/ppapi_proxy_export.h" namespace IPC { @@ -26,7 +24,6 @@ class SerializedHandle; class PPAPI_PROXY_EXPORT NaClMessageScanner { public: NaClMessageScanner(); - ~NaClMessageScanner(); // Scans the message for items that require special handling. Copies any // SerializedHandles in the message into |handles| and if the message must be @@ -47,63 +44,8 @@ class PPAPI_PROXY_EXPORT NaClMessageScanner { void ScanUntrustedMessage(const IPC::Message& untrusted_msg, scoped_ptr<IPC::Message>* new_msg_ptr); - // FileSystem information for quota auditing. - class PPAPI_PROXY_EXPORT FileSystem { - public: - FileSystem(); - ~FileSystem(); - - int64_t reserved_quota() const { return reserved_quota_; } - - // Adds amount to reserved quota. Returns true if reserved quota >= 0. - bool UpdateReservedQuota(int64_t delta); - - private: - base::Lock lock_; - // This is the remaining amount of quota reserved for the file system. - // Acquire the lock to modify this field, since it may be used on multiple - // threads. - int64_t reserved_quota_; - - DISALLOW_COPY_AND_ASSIGN(FileSystem); - }; - - // FileIO information for quota auditing. - class PPAPI_PROXY_EXPORT FileIO { - public: - FileIO(FileSystem* file_system, int64_t max_written_offset); - ~FileIO(); - - int64_t max_written_offset() { return max_written_offset_; } - - void SetMaxWrittenOffset(int64_t max_written_offset); - - // Grows file by the given amount. Returns true on success. - bool Grow(int64_t amount); - - private: - base::Lock lock_; - - // The file system that contains this file. - FileSystem* file_system_; - - // The maximum written offset. This is initialized by NaClMessageScanner - // when the file is opened and modified by a NaClDescQuotaInterface when the - // plugin writes to greater maximum offsets. - int64_t max_written_offset_; - - DISALLOW_COPY_AND_ASSIGN(FileIO); - }; - - FileIO* GetFile(PP_Resource file_io); - private: - friend class NaClMessageScannerTest; - void RegisterSyncMessageForReply(const IPC::Message& msg); - void AuditNestedMessage(PP_Resource resource, - const IPC::Message& msg, - SerializedHandle* handle); // When we send a synchronous message (from untrusted to trusted), we store // its type here, so that later we can associate the reply with its type @@ -111,14 +53,6 @@ class PPAPI_PROXY_EXPORT NaClMessageScanner { typedef std::map<int, uint32> PendingSyncMsgMap; PendingSyncMsgMap pending_sync_msgs_; - // We intercept FileSystem and FileIO messages to maintain information about - // file systems and open files. This is used by NaClQuotaDescs to calculate - // quota consumption and check it against the reserved amount. - typedef std::map<int32_t, FileSystem*> FileSystemMap; - FileSystemMap file_systems_; - typedef std::map<int32_t, FileIO*> FileIOMap; - FileIOMap files_; - DISALLOW_COPY_AND_ASSIGN(NaClMessageScanner); }; diff --git a/ppapi/proxy/nacl_message_scanner_unittest.cc b/ppapi/proxy/nacl_message_scanner_unittest.cc deleted file mode 100644 index e0516ff..0000000 --- a/ppapi/proxy/nacl_message_scanner_unittest.cc +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ipc/ipc_message.h" -#include "ppapi/proxy/nacl_message_scanner.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/ppapi_proxy_test.h" -#include "ppapi/proxy/serialized_handle.h" -#include "ppapi/shared_impl/host_resource.h" - -namespace ppapi { -namespace proxy { - -namespace { -const PP_Resource kInvalidResource = 0; -const PP_Resource kFileSystem = 1; -const PP_Resource kFileIO = 2; -const int64_t kQuotaReservationAmount = 100; -} - -class NaClMessageScannerTest : public PluginProxyTest { - public: - NaClMessageScannerTest() {} - - uint32 FindPendingSyncMessage( - const NaClMessageScanner& scanner, - const IPC::Message& msg) { - int msg_id = IPC::SyncMessage::GetMessageId(msg); - std::map<int, uint32>::const_iterator it = - scanner.pending_sync_msgs_.find(msg_id); - // O can signal that no message was found. - return (it != scanner.pending_sync_msgs_.end()) ? it->second : 0; - } - - NaClMessageScanner::FileSystem* FindFileSystem( - const NaClMessageScanner& scanner, - PP_Resource file_system) { - NaClMessageScanner::FileSystemMap::const_iterator it = - scanner.file_systems_.find(file_system); - return (it != scanner.file_systems_.end()) ? it->second : NULL; - } - - NaClMessageScanner::FileIO* FindFileIO( - const NaClMessageScanner& scanner, - PP_Resource file_io) { - NaClMessageScanner::FileIOMap::const_iterator it = - scanner.files_.find(file_io); - return (it != scanner.files_.end()) ? it->second : NULL; - } - - void OpenQuotaFile(NaClMessageScanner* scanner, - PP_Resource file_io, - PP_Resource file_system) { - std::vector<SerializedHandle> unused_handles; - ResourceMessageReplyParams fio_reply_params(file_io, 0); - scoped_ptr<IPC::Message> new_msg_ptr; - scanner->ScanMessage( - PpapiPluginMsg_ResourceReply( - fio_reply_params, - PpapiPluginMsg_FileIO_OpenReply(file_system, 0)), - &unused_handles, - &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - } -}; - -TEST_F(NaClMessageScannerTest, SyncMessageAndReply) { - NaClMessageScanner test; - ppapi::proxy::SerializedHandle handle( - ppapi::proxy::SerializedHandle::SHARED_MEMORY); - IPC::Message msg = - PpapiHostMsg_PPBGraphics3D_GetTransferBuffer( - ppapi::API_ID_PPB_GRAPHICS_3D, - HostResource(), - 0, // id - &handle); - scoped_ptr<IPC::Message> new_msg_ptr; - EXPECT_NE(msg.type(), FindPendingSyncMessage(test, msg)); - test.ScanUntrustedMessage(msg, &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - EXPECT_EQ(msg.type(), FindPendingSyncMessage(test, msg)); - - // TODO(bbudge) Figure out how to put together a sync reply message. -} - -TEST_F(NaClMessageScannerTest, FileOpenClose) { - NaClMessageScanner test; - std::vector<SerializedHandle> unused_handles; - ResourceMessageCallParams fio_call_params(kFileIO, 0); - ResourceMessageCallParams fs_call_params(kFileSystem, 0); - ResourceMessageReplyParams fio_reply_params(kFileIO, 0); - ResourceMessageReplyParams fs_reply_params(kFileSystem, 0); - scoped_ptr<IPC::Message> new_msg_ptr; - - EXPECT_EQ(NULL, FindFileSystem(test, kFileSystem)); - EXPECT_EQ(NULL, FindFileIO(test, kFileIO)); - - // Open a file, not in a quota file system. - test.ScanMessage( - PpapiPluginMsg_ResourceReply( - fio_reply_params, - PpapiPluginMsg_FileIO_OpenReply(kInvalidResource, 0)), - &unused_handles, - &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - EXPECT_FALSE(FindFileSystem(test, kFileSystem)); - EXPECT_FALSE(FindFileIO(test, kFileIO)); - - // Open a file in a quota file system; info objects for it and its file system - // should be created. - OpenQuotaFile(&test, kFileIO, kFileSystem); - NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem); - NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO); - EXPECT_TRUE(fs); - EXPECT_EQ(0, fs->reserved_quota()); - EXPECT_TRUE(fio); - EXPECT_EQ(0, fio->max_written_offset()); - - const int64_t kNewFileSize = 10; - fio->SetMaxWrittenOffset(kNewFileSize); - - // We should not be able to under-report max_written_offset when closing. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fio_call_params, - PpapiHostMsg_FileIO_Close(0)), - &new_msg_ptr); - EXPECT_TRUE(new_msg_ptr); - ResourceMessageCallParams call_params; - IPC::Message nested_msg; - int64_t max_written_offset = 0; - EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>( - *new_msg_ptr, &call_params, &nested_msg) && - UnpackMessage<PpapiHostMsg_FileIO_Close>( - nested_msg, &max_written_offset)); - new_msg_ptr.reset(); - EXPECT_EQ(kNewFileSize, max_written_offset); - EXPECT_FALSE(FindFileIO(test, kFileIO)); - - // Reopen the file. - OpenQuotaFile(&test, kFileIO, kFileSystem); - fio = FindFileIO(test, kFileIO); - fio->SetMaxWrittenOffset(kNewFileSize); - - // Close with correct max_written_offset. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fio_call_params, - PpapiHostMsg_FileIO_Close(kNewFileSize)), - &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - EXPECT_FALSE(FindFileIO(test, kFileIO)); - - // Destroy file system. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fs_call_params, - PpapiHostMsg_ResourceDestroyed(kFileSystem)), - &new_msg_ptr); - EXPECT_FALSE(FindFileSystem(test, kFileSystem)); -} - -TEST_F(NaClMessageScannerTest, QuotaAuditing) { - NaClMessageScanner test; - std::vector<SerializedHandle> unused_handles; - ResourceMessageCallParams fio_call_params(kFileIO, 0); - ResourceMessageCallParams fs_call_params(kFileSystem, 0); - ResourceMessageReplyParams fio_reply_params(kFileIO, 0); - ResourceMessageReplyParams fs_reply_params(kFileSystem, 0); - scoped_ptr<IPC::Message> new_msg_ptr; - - OpenQuotaFile(&test, kFileIO, kFileSystem); - NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem); - NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO); - EXPECT_TRUE(fs); - EXPECT_EQ(0, fs->reserved_quota()); - EXPECT_TRUE(fio); - EXPECT_EQ(0, fio->max_written_offset()); - - // Without reserving quota, we should not be able to grow the file. - EXPECT_FALSE(fio->Grow(1)); - EXPECT_EQ(0, fs->reserved_quota()); - EXPECT_EQ(0, fio->max_written_offset()); - - // Receive reserved quota, and updated file sizes. - const int64_t kNewFileSize = 10; - FileOffsetMap offset_map; - offset_map.insert(std::make_pair(kFileIO, kNewFileSize)); - test.ScanMessage( - PpapiPluginMsg_ResourceReply( - fs_reply_params, - PpapiPluginMsg_FileSystem_ReserveQuotaReply( - kQuotaReservationAmount, - offset_map)), - &unused_handles, - &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - EXPECT_EQ(kQuotaReservationAmount, fs->reserved_quota()); - EXPECT_EQ(kNewFileSize, fio->max_written_offset()); - - // We should be able to grow the file within quota. - EXPECT_TRUE(fio->Grow(1)); - EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota()); - EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset()); - - // We should not be able to grow the file over quota. - EXPECT_FALSE(fio->Grow(kQuotaReservationAmount)); - EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota()); - EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset()); - - // Plugin should not under-report max written offsets when reserving quota. - offset_map[kFileIO] = 0; // should be kNewFileSize + 1. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fio_call_params, - PpapiHostMsg_FileSystem_ReserveQuota( - kQuotaReservationAmount, - offset_map)), - &new_msg_ptr); - EXPECT_TRUE(new_msg_ptr); - ResourceMessageCallParams call_params; - IPC::Message nested_msg; - int64_t amount = 0; - FileOffsetMap new_offset_map; - EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>( - *new_msg_ptr, &call_params, &nested_msg) && - UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>( - nested_msg, &amount, &new_offset_map)); - new_msg_ptr.reset(); - EXPECT_EQ(kQuotaReservationAmount, amount); - EXPECT_EQ(kNewFileSize + 1, new_offset_map[kFileIO]); -} - -TEST_F(NaClMessageScannerTest, SetLength) { - NaClMessageScanner test; - std::vector<SerializedHandle> unused_handles; - ResourceMessageCallParams fio_call_params(kFileIO, 0); - ResourceMessageCallParams fs_call_params(kFileSystem, 0); - ResourceMessageReplyParams fio_reply_params(kFileIO, 0); - ResourceMessageReplyParams fs_reply_params(kFileSystem, 0); - scoped_ptr<IPC::Message> new_msg_ptr; - - OpenQuotaFile(&test, kFileIO, kFileSystem); - NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem); - NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO); - - // Receive reserved quota, and updated file sizes. - const int64_t kNewFileSize = 10; - FileOffsetMap offset_map; - offset_map.insert(std::make_pair(kFileIO, 0)); - test.ScanMessage( - PpapiPluginMsg_ResourceReply( - fs_reply_params, - PpapiPluginMsg_FileSystem_ReserveQuotaReply( - kQuotaReservationAmount, - offset_map)), - &unused_handles, - &new_msg_ptr); - - // We should be able to SetLength within quota. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fio_call_params, - PpapiHostMsg_FileIO_SetLength(kNewFileSize)), - &new_msg_ptr); - EXPECT_FALSE(new_msg_ptr); - EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota()); - EXPECT_EQ(kNewFileSize, fio->max_written_offset()); - - // We shouldn't be able to SetLength beyond quota. The message should be - // rewritten to fail with length == -1. - test.ScanUntrustedMessage( - PpapiHostMsg_ResourceCall( - fio_call_params, - PpapiHostMsg_FileIO_SetLength(kQuotaReservationAmount + 1)), - &new_msg_ptr); - EXPECT_TRUE(new_msg_ptr); - ResourceMessageCallParams call_params; - IPC::Message nested_msg; - int64_t length = 0; - EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>( - *new_msg_ptr, &call_params, &nested_msg) && - UnpackMessage<PpapiHostMsg_FileIO_SetLength>( - nested_msg, &length)); - new_msg_ptr.reset(); - EXPECT_EQ(-1, length); - EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota()); - EXPECT_EQ(kNewFileSize, fio->max_written_offset()); -} - -} // namespace proxy -} // namespace ppapi diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index b2fa2af..ca4ea36 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -3,7 +3,6 @@ // found in the LICENSE file. // Multiply-included message header, no traditional include guard. -#include <map> #include <string> #include <vector> @@ -1225,14 +1224,14 @@ IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Create) IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Open, PP_Resource /* file_ref_resource */, int32_t /* open_flags */) -IPC_MESSAGE_CONTROL2(PpapiPluginMsg_FileIO_OpenReply, - PP_Resource /* quota_file_system */, - int64_t /* max_written_offset */) -IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_Close, - int64_t /* max_written_offset */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_OpenReply) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Close) IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Touch, PP_Time /* last_access_time */, PP_Time /* last_modified_time */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Write, + int64_t /* offset */, + std::string /* data */) IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_SetLength, int64_t /* length */) IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Flush) @@ -1318,15 +1317,6 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileSystem_CreateFromRenderer, // linked to the existing resource host given in the ResourceVar. IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileSystem_CreateFromPendingHost, PP_FileSystemType /* file_system_type */) -// IPC_MESSAGE macros choke on extra , in the std::map, when expanding. We need -// to typedef it to avoid that. -typedef std::map<int32_t, int64_t> FileOffsetMap; -IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileSystem_ReserveQuota, - int64_t /* amount */, - FileOffsetMap /* max_written_offsets */) -IPC_MESSAGE_CONTROL2(PpapiPluginMsg_FileSystem_ReserveQuotaReply, - int64_t /* amount */, - FileOffsetMap /* max_written_offsets */) // Flash DRM ------------------------------------------------------------------ IPC_MESSAGE_CONTROL0(PpapiHostMsg_FlashDRM_Create) diff --git a/ppapi/thunk/ppb_file_io_api.h b/ppapi/thunk/ppb_file_io_api.h index 830b140..b794f1c 100644 --- a/ppapi/thunk/ppb_file_io_api.h +++ b/ppapi/thunk/ppb_file_io_api.h @@ -42,8 +42,6 @@ class PPAPI_THUNK_EXPORT PPB_FileIO_API { scoped_refptr<TrackedCallback> callback) = 0; virtual int32_t SetLength(int64_t length, scoped_refptr<TrackedCallback> callback) = 0; - virtual int64_t GetMaxWrittenOffset() const = 0; - virtual void SetMaxWrittenOffset(int64_t max_written_offset) = 0; virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) = 0; virtual void Close() = 0; diff --git a/ppapi/thunk/ppb_file_system_api.h b/ppapi/thunk/ppb_file_system_api.h index 0351bde..f9524dc 100644 --- a/ppapi/thunk/ppb_file_system_api.h +++ b/ppapi/thunk/ppb_file_system_api.h @@ -5,7 +5,6 @@ #ifndef PPAPI_THUNK_PPB_FILE_SYSTEM_API_H_ #define PPAPI_THUNK_PPB_FILE_SYSTEM_API_H_ -#include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "ppapi/c/ppb_file_system.h" @@ -22,11 +21,6 @@ class PPB_FileSystem_API { virtual int32_t Open(int64_t expected_size, scoped_refptr<TrackedCallback> callback) = 0; virtual PP_FileSystemType GetType() = 0; - virtual void OpenQuotaFile(PP_Resource file_io) = 0; - virtual void CloseQuotaFile(PP_Resource file_io) = 0; - typedef base::Callback<void(int64_t)> RequestQuotaCallback; - virtual int64_t RequestQuota(int64_t amount, - const RequestQuotaCallback& callback) = 0; }; } // namespace thunk |