Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1099)

Side by Side Diff: content/renderer/pepper/pepper_file_io_host.cc

Issue 18063005: Do PPB_FileIO Query and Read in the plugin process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/renderer/pepper/pepper_file_io_host.h ('k') | ppapi/proxy/file_io_resource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/pepper/pepper_file_io_host.h" 5 #include "content/renderer/pepper/pepper_file_io_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // callbacks here. 51 // callbacks here.
52 return pp_error == PP_OK ? byte_number : pp_error; 52 return pp_error == PP_OK ? byte_number : pp_error;
53 } 53 }
54 54
55 } // namespace 55 } // namespace
56 56
57 PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host, 57 PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host,
58 PP_Instance instance, 58 PP_Instance instance,
59 PP_Resource resource) 59 PP_Resource resource)
60 : ResourceHost(host->GetPpapiHost(), instance, resource), 60 : ResourceHost(host->GetPpapiHost(), instance, resource),
61 renderer_ppapi_host_(host),
61 file_(base::kInvalidPlatformFileValue), 62 file_(base::kInvalidPlatformFileValue),
62 file_system_type_(PP_FILESYSTEMTYPE_INVALID), 63 file_system_type_(PP_FILESYSTEMTYPE_INVALID),
63 quota_policy_(quota::kQuotaLimitTypeUnknown), 64 quota_policy_(quota::kQuotaLimitTypeUnknown),
64 is_running_in_process_(host->IsRunningInProcess()), 65 is_running_in_process_(host->IsRunningInProcess()),
65 open_flags_(0), 66 open_flags_(0),
66 weak_factory_(this) { 67 weak_factory_(this) {
67 // TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed. 68 // TODO(victorhsieh): eliminate plugin_delegate_ as it's no longer needed.
68 webkit::ppapi::PluginInstance* plugin_instance = 69 webkit::ppapi::PluginInstance* plugin_instance =
69 webkit::ppapi::HostGlobals::Get()->GetInstance(instance); 70 webkit::ppapi::HostGlobals::Get()->GetInstance(instance);
70 plugin_delegate_ = plugin_instance ? plugin_instance->delegate() : NULL; 71 plugin_delegate_ = plugin_instance ? plugin_instance->delegate() : NULL;
71 } 72 }
72 73
73 PepperFileIOHost::~PepperFileIOHost() { 74 PepperFileIOHost::~PepperFileIOHost() {
74 OnHostMsgClose(NULL); 75 OnHostMsgClose(NULL);
75 } 76 }
76 77
77 int32_t PepperFileIOHost::OnResourceMessageReceived( 78 int32_t PepperFileIOHost::OnResourceMessageReceived(
78 const IPC::Message& msg, 79 const IPC::Message& msg,
79 ppapi::host::HostMessageContext* context) { 80 ppapi::host::HostMessageContext* context) {
80 IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) 81 IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg)
81 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, 82 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open,
82 OnHostMsgOpen) 83 OnHostMsgOpen)
83 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Query,
84 OnHostMsgQuery)
85 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, 84 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch,
86 OnHostMsgTouch) 85 OnHostMsgTouch)
87 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Read,
88 OnHostMsgRead)
89 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write, 86 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write,
90 OnHostMsgWrite) 87 OnHostMsgWrite)
91 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength, 88 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength,
92 OnHostMsgSetLength) 89 OnHostMsgSetLength)
93 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush, 90 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush,
94 OnHostMsgFlush) 91 OnHostMsgFlush)
95 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close, 92 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close,
96 OnHostMsgClose) 93 OnHostMsgClose)
97 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite, 94 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite,
98 OnHostMsgWillWrite) 95 OnHostMsgWillWrite)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, 150 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback,
154 weak_factory_.GetWeakPtr(), 151 weak_factory_.GetWeakPtr(),
155 context->MakeReplyMessageContext()))) 152 context->MakeReplyMessageContext())))
156 return PP_ERROR_FAILED; 153 return PP_ERROR_FAILED;
157 } 154 }
158 155
159 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 156 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
160 return PP_OK_COMPLETIONPENDING; 157 return PP_OK_COMPLETIONPENDING;
161 } 158 }
162 159
163 int32_t PepperFileIOHost::OnHostMsgQuery(
164 ppapi::host::HostMessageContext* context) {
165 int32_t rv = state_manager_.CheckOperationState(
166 FileIOStateManager::OPERATION_EXCLUSIVE, true);
167 if (rv != PP_OK)
168 return rv;
169
170 if (!plugin_delegate_)
171 return PP_ERROR_FAILED;
172
173 if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
174 plugin_delegate_->GetFileThreadMessageLoopProxy().get(),
175 file_,
176 base::Bind(&PepperFileIOHost::ExecutePlatformQueryCallback,
177 weak_factory_.GetWeakPtr(),
178 context->MakeReplyMessageContext())))
179 return PP_ERROR_FAILED;
180
181 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
182 return PP_OK_COMPLETIONPENDING;
183 }
184
185 int32_t PepperFileIOHost::OnHostMsgTouch( 160 int32_t PepperFileIOHost::OnHostMsgTouch(
186 ppapi::host::HostMessageContext* context, 161 ppapi::host::HostMessageContext* context,
187 PP_Time last_access_time, 162 PP_Time last_access_time,
188 PP_Time last_modified_time) { 163 PP_Time last_modified_time) {
189 int32_t rv = state_manager_.CheckOperationState( 164 int32_t rv = state_manager_.CheckOperationState(
190 FileIOStateManager::OPERATION_EXCLUSIVE, true); 165 FileIOStateManager::OPERATION_EXCLUSIVE, true);
191 if (rv != PP_OK) 166 if (rv != PP_OK)
192 return rv; 167 return rv;
193 168
194 if (!plugin_delegate_) 169 if (!plugin_delegate_)
(...skipping 20 matching lines...) Expand all
215 PPTimeToTime(last_modified_time), 190 PPTimeToTime(last_modified_time),
216 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, 191 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
217 weak_factory_.GetWeakPtr(), 192 weak_factory_.GetWeakPtr(),
218 context->MakeReplyMessageContext()))) 193 context->MakeReplyMessageContext())))
219 return PP_ERROR_FAILED; 194 return PP_ERROR_FAILED;
220 195
221 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 196 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
222 return PP_OK_COMPLETIONPENDING; 197 return PP_OK_COMPLETIONPENDING;
223 } 198 }
224 199
225 int32_t PepperFileIOHost::OnHostMsgRead(
226 ppapi::host::HostMessageContext* context,
227 int64_t offset,
228 int32_t max_read_length) {
229 int32_t rv = state_manager_.CheckOperationState(
230 FileIOStateManager::OPERATION_READ, true);
231 if (rv != PP_OK)
232 return rv;
233
234 // Validate max_read_length before allocating below. This value is coming from
235 // the untrusted plugin.
236 if (max_read_length < 0) {
237 ReplyMessageContext reply_context = context->MakeReplyMessageContext();
238 reply_context.params.set_result(PP_ERROR_FAILED);
239 host()->SendReply(reply_context,
240 PpapiPluginMsg_FileIO_ReadReply(std::string()));
241 return PP_OK_COMPLETIONPENDING;
242 }
243
244 if (!plugin_delegate_)
245 return PP_ERROR_FAILED;
246
247 if (!base::FileUtilProxy::Read(
248 plugin_delegate_->GetFileThreadMessageLoopProxy().get(),
249 file_,
250 offset,
251 max_read_length,
252 base::Bind(&PepperFileIOHost::ExecutePlatformReadCallback,
253 weak_factory_.GetWeakPtr(),
254 context->MakeReplyMessageContext())))
255 return PP_ERROR_FAILED;
256
257 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ);
258 return PP_OK_COMPLETIONPENDING;
259 }
260
261 int32_t PepperFileIOHost::OnHostMsgWrite( 200 int32_t PepperFileIOHost::OnHostMsgWrite(
262 ppapi::host::HostMessageContext* context, 201 ppapi::host::HostMessageContext* context,
263 int64_t offset, 202 int64_t offset,
264 const std::string& buffer) { 203 const std::string& buffer) {
265 int32_t rv = state_manager_.CheckOperationState( 204 int32_t rv = state_manager_.CheckOperationState(
266 FileIOStateManager::OPERATION_WRITE, true); 205 FileIOStateManager::OPERATION_WRITE, true);
267 if (rv != PP_OK) 206 if (rv != PP_OK)
268 return rv; 207 return rv;
269 208
270 if (quota_file_io_) { 209 if (quota_file_io_) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 346 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
408 return PP_OK_COMPLETIONPENDING; 347 return PP_OK_COMPLETIONPENDING;
409 } 348 }
410 349
411 int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle( 350 int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
412 ppapi::host::HostMessageContext* context) { 351 ppapi::host::HostMessageContext* context) {
413 if (!is_running_in_process_ && 352 if (!is_running_in_process_ &&
414 quota_policy_ != quota::kQuotaLimitTypeUnlimited) 353 quota_policy_ != quota::kQuotaLimitTypeUnlimited)
415 return PP_ERROR_FAILED; 354 return PP_ERROR_FAILED;
416 355
417 RendererPpapiHost* renderer_ppapi_host =
418 RendererPpapiHost::GetForPPInstance(pp_instance());
419
420 // Whitelist to make it privately accessible. 356 // Whitelist to make it privately accessible.
421 if (!GetContentClient()->renderer()->IsPluginAllowedToCallRequestOSFileHandle( 357 if (!GetContentClient()->renderer()->IsPluginAllowedToCallRequestOSFileHandle(
422 renderer_ppapi_host->GetContainerForInstance(pp_instance()))) 358 renderer_ppapi_host_->GetContainerForInstance(pp_instance())))
423 return PP_ERROR_NOACCESS; 359 return PP_ERROR_NOACCESS;
424 360
425 IPC::PlatformFileForTransit file = 361 IPC::PlatformFileForTransit file =
426 renderer_ppapi_host->ShareHandleWithRemote(file_, false); 362 renderer_ppapi_host_->ShareHandleWithRemote(file_, false);
427 if (file == IPC::InvalidPlatformFileForTransit()) 363 if (file == IPC::InvalidPlatformFileForTransit())
428 return PP_ERROR_FAILED; 364 return PP_ERROR_FAILED;
429 ppapi::host::ReplyMessageContext reply_context = 365 ppapi::host::ReplyMessageContext reply_context =
430 context->MakeReplyMessageContext(); 366 context->MakeReplyMessageContext();
431 ppapi::proxy::SerializedHandle file_handle; 367 ppapi::proxy::SerializedHandle file_handle;
432 file_handle.set_file_handle(file, open_flags_); 368 file_handle.set_file_handle(file, open_flags_);
433 reply_context.params.AppendHandle(file_handle); 369 reply_context.params.AppendHandle(file_handle);
434 host()->SendReply(reply_context, 370 host()->SendReply(reply_context,
435 PpapiPluginMsg_FileIO_RequestOSFileHandleReply()); 371 PpapiPluginMsg_FileIO_RequestOSFileHandleReply());
436 return PP_OK_COMPLETIONPENDING; 372 return PP_OK_COMPLETIONPENDING;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 base::PlatformFileError error_code, 405 base::PlatformFileError error_code,
470 base::PassPlatformFile file) { 406 base::PassPlatformFile file) {
471 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); 407 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
472 if (pp_error == PP_OK) 408 if (pp_error == PP_OK)
473 state_manager_.SetOpenSucceed(); 409 state_manager_.SetOpenSucceed();
474 410
475 DCHECK(file_ == base::kInvalidPlatformFileValue); 411 DCHECK(file_ == base::kInvalidPlatformFileValue);
476 file_ = file.ReleaseValue(); 412 file_ = file.ReleaseValue();
477 413
478 DCHECK(!quota_file_io_.get()); 414 DCHECK(!quota_file_io_.get());
479 if (file_ != base::kInvalidPlatformFileValue && 415 if (file_ != base::kInvalidPlatformFileValue) {
480 (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY || 416 if (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY ||
481 file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) { 417 file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT) {
482 quota_file_io_.reset(new webkit::ppapi::QuotaFileIO( 418 quota_file_io_.reset(new webkit::ppapi::QuotaFileIO(
483 pp_instance(), file_, file_system_url_, file_system_type_)); 419 pp_instance(), file_, file_system_url_, file_system_type_));
420 }
421
422 IPC::PlatformFileForTransit file_for_transit =
423 renderer_ppapi_host_->ShareHandleWithRemote(file_, false);
teravest 2013/07/12 16:07:50 What's your plan for preventing writes to file_ in
bbudge 2013/07/12 17:19:15 Good question! I hadn't dealt with this since I or
bbudge 2013/07/12 18:15:18 I looked through the code and the NaClDesc does ch
teravest 2013/07/15 16:25:12 Cool. I don't see where that's happening now; are
424 if (!(file_for_transit == IPC::InvalidPlatformFileForTransit())) {
425 // Pass a good file descriptor over to the plugin process. This is used
426 // in the plugin for any other file operations that can be done there.
427 ppapi::proxy::SerializedHandle file_handle;
428 file_handle.set_file_handle(file_for_transit, open_flags_);
429 reply_context.params.AppendHandle(file_handle);
430 }
484 } 431 }
485 432
486 reply_context.params.set_result(pp_error); 433 reply_context.params.set_result(pp_error);
487 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply()); 434 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
488 state_manager_.SetOperationFinished(); 435 state_manager_.SetOperationFinished();
489 } 436 }
490 437
491 void PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback( 438 void PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback(
492 ppapi::host::ReplyMessageContext reply_context, 439 ppapi::host::ReplyMessageContext reply_context,
493 base::PlatformFileError error_code, 440 base::PlatformFileError error_code,
494 base::PassPlatformFile file, 441 base::PassPlatformFile file,
495 quota::QuotaLimitType quota_policy, 442 quota::QuotaLimitType quota_policy,
496 const PluginDelegate::NotifyCloseFileCallback& callback) { 443 const PluginDelegate::NotifyCloseFileCallback& callback) {
497 if (error_code == base::PLATFORM_FILE_OK) 444 if (error_code == base::PLATFORM_FILE_OK)
498 notify_close_file_callback_ = callback; 445 notify_close_file_callback_ = callback;
499 quota_policy_ = quota_policy; 446 quota_policy_ = quota_policy;
500 ExecutePlatformOpenFileCallback(reply_context, error_code, file); 447 ExecutePlatformOpenFileCallback(reply_context, error_code, file);
501 } 448 }
502 449
503 void PepperFileIOHost::ExecutePlatformQueryCallback(
504 ppapi::host::ReplyMessageContext reply_context,
505 base::PlatformFileError error_code,
506 const base::PlatformFileInfo& file_info) {
507 PP_FileInfo pp_info;
508 ppapi::PlatformFileInfoToPepperFileInfo(file_info, file_system_type_,
509 &pp_info);
510
511 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
512 reply_context.params.set_result(pp_error);
513 host()->SendReply(reply_context,
514 PpapiPluginMsg_FileIO_QueryReply(pp_info));
515 state_manager_.SetOperationFinished();
516 }
517
518 void PepperFileIOHost::ExecutePlatformReadCallback(
519 ppapi::host::ReplyMessageContext reply_context,
520 base::PlatformFileError error_code,
521 const char* data, int bytes_read) {
522 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
523
524 // Only send the amount of data in the string that was actually read.
525 std::string buffer;
526 if (pp_error == PP_OK)
527 buffer.append(data, bytes_read);
528 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_read));
529 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_ReadReply(buffer));
530 state_manager_.SetOperationFinished();
531 }
532
533 void PepperFileIOHost::ExecutePlatformWriteCallback( 450 void PepperFileIOHost::ExecutePlatformWriteCallback(
534 ppapi::host::ReplyMessageContext reply_context, 451 ppapi::host::ReplyMessageContext reply_context,
535 base::PlatformFileError error_code, 452 base::PlatformFileError error_code,
536 int bytes_written) { 453 int bytes_written) {
537 // On the plugin side, the callback expects a parameter with different meaning 454 // On the plugin side, the callback expects a parameter with different meaning
538 // depends on whether is negative or not. It is the result here. We translate 455 // depends on whether is negative or not. It is the result here. We translate
539 // for the callback. 456 // for the callback.
540 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code); 457 int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
541 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); 458 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written));
542 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); 459 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
543 state_manager_.SetOperationFinished(); 460 state_manager_.SetOperationFinished();
544 } 461 }
545 462
546 } // namespace content 463 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/pepper/pepper_file_io_host.h ('k') | ppapi/proxy/file_io_resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698