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

Side by Side Diff: components/nacl/loader/nacl_ipc_adapter.cc

Issue 418423002: Pepper: Stop using SRPC for irt_open_resource(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/nacl/loader/nacl_ipc_adapter.h" 5 #include "components/nacl/loader/nacl_ipc_adapter.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
15 #include "base/task_runner_util.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 #include "ipc/ipc_channel.h" 17 #include "ipc/ipc_channel.h"
17 #include "ipc/ipc_platform_file.h" 18 #include "ipc/ipc_platform_file.h"
18 #include "native_client/src/trusted/desc/nacl_desc_base.h" 19 #include "native_client/src/trusted/desc/nacl_desc_base.h"
19 #include "native_client/src/trusted/desc/nacl_desc_custom.h" 20 #include "native_client/src/trusted/desc/nacl_desc_custom.h"
20 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h" 21 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
21 #include "native_client/src/trusted/desc/nacl_desc_io.h" 22 #include "native_client/src/trusted/desc/nacl_desc_io.h"
22 #include "native_client/src/trusted/desc/nacl_desc_quota.h" 23 #include "native_client/src/trusted/desc/nacl_desc_quota.h"
23 #include "native_client/src/trusted/desc/nacl_desc_quota_interface.h" 24 #include "native_client/src/trusted/desc/nacl_desc_quota_interface.h"
24 #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h" 25 #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
25 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 26 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
26 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" 27 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
28 #include "native_client/src/trusted/validator/rich_file_info.h"
27 #include "ppapi/c/ppb_file_io.h" 29 #include "ppapi/c/ppb_file_io.h"
28 #include "ppapi/proxy/ppapi_messages.h" 30 #include "ppapi/proxy/ppapi_messages.h"
29 #include "ppapi/proxy/serialized_handle.h" 31 #include "ppapi/proxy/serialized_handle.h"
30 32
31 using ppapi::proxy::NaClMessageScanner; 33 using ppapi::proxy::NaClMessageScanner;
32 34
33 namespace { 35 namespace {
34 36
35 enum BufferSizeStatus { 37 enum BufferSizeStatus {
36 // The buffer contains a full message with no extra bytes. 38 // The buffer contains a full message with no extra bytes.
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 324
323 NaClIPCAdapter::IOThreadData::~IOThreadData() { 325 NaClIPCAdapter::IOThreadData::~IOThreadData() {
324 } 326 }
325 327
326 NaClIPCAdapter::NaClIPCAdapter(const IPC::ChannelHandle& handle, 328 NaClIPCAdapter::NaClIPCAdapter(const IPC::ChannelHandle& handle,
327 base::TaskRunner* runner) 329 base::TaskRunner* runner)
328 : lock_(), 330 : lock_(),
329 cond_var_(&lock_), 331 cond_var_(&lock_),
330 task_runner_(runner), 332 task_runner_(runner),
331 locked_data_() { 333 locked_data_() {
334 main_task_runner_ = base::MessageLoop::current()->task_runner();
332 io_thread_data_.channel_ = IPC::Channel::CreateServer(handle, this); 335 io_thread_data_.channel_ = IPC::Channel::CreateServer(handle, this);
333 // Note, we can not PostTask for ConnectChannelOnIOThread here. If we did, 336 // Note, we can not PostTask for ConnectChannelOnIOThread here. If we did,
334 // and that task ran before this constructor completes, the reference count 337 // and that task ran before this constructor completes, the reference count
335 // would go to 1 and then to 0 because of the Task, before we've been returned 338 // would go to 1 and then to 0 because of the Task, before we've been returned
336 // to the owning scoped_refptr, which is supposed to give us our first 339 // to the owning scoped_refptr, which is supposed to give us our first
337 // ref-count. 340 // ref-count.
338 } 341 }
339 342
340 NaClIPCAdapter::NaClIPCAdapter(scoped_ptr<IPC::Channel> channel, 343 NaClIPCAdapter::NaClIPCAdapter(scoped_ptr<IPC::Channel> channel,
341 base::TaskRunner* runner) 344 base::TaskRunner* runner)
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 } 461 }
459 462
460 #if defined(OS_POSIX) 463 #if defined(OS_POSIX)
461 int NaClIPCAdapter::TakeClientFileDescriptor() { 464 int NaClIPCAdapter::TakeClientFileDescriptor() {
462 return io_thread_data_.channel_->TakeClientFileDescriptor(); 465 return io_thread_data_.channel_->TakeClientFileDescriptor();
463 } 466 }
464 #endif 467 #endif
465 468
466 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { 469 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) {
467 uint32_t type = msg.type(); 470 uint32_t type = msg.type();
471
468 if (type == IPC_REPLY_ID) { 472 if (type == IPC_REPLY_ID) {
469 int id = IPC::SyncMessage::GetMessageId(msg); 473 int id = IPC::SyncMessage::GetMessageId(msg);
470 IOThreadData::PendingSyncMsgMap::iterator it = 474 IOThreadData::PendingSyncMsgMap::iterator it =
471 io_thread_data_.pending_sync_msgs_.find(id); 475 io_thread_data_.pending_sync_msgs_.find(id);
472 DCHECK(it != io_thread_data_.pending_sync_msgs_.end()); 476 DCHECK(it != io_thread_data_.pending_sync_msgs_.end());
473 if (it != io_thread_data_.pending_sync_msgs_.end()) { 477 if (it != io_thread_data_.pending_sync_msgs_.end()) {
474 type = it->second; 478 type = it->second;
475 io_thread_data_.pending_sync_msgs_.erase(it); 479 io_thread_data_.pending_sync_msgs_.erase(it);
476 } 480 }
477 } 481 }
482 // Handle PpapiHostMsg_OpenResource outside the lock as it requires sending
483 // IPC to handle properly.
dmichael (off chromium) 2014/08/27 20:49:14 I know Mark strongly preferred knowledge of proxy
Mark Seaborn 2014/08/28 21:33:49 Yeah, open_resource() isn't part of PPAPI, so it's
484 if (type == PpapiHostMsg_OpenResource::ID) {
485 PickleIterator iter = IPC::SyncMessage::GetDataIterator(&msg);
486 ppapi::proxy::SerializedHandle ignore_fd;
487 uint64_t token_lo;
488 uint64_t token_hi;
489 if (!IPC::ReadParam(&msg, &iter, &ignore_fd) ||
490 !IPC::ReadParam(&msg, &iter, &token_lo) ||
491 !IPC::ReadParam(&msg, &iter, &token_hi)) {
492 return false;
493 }
478 494
495 if (token_lo != 0 || token_hi != 0) {
496 // We've received a valid file token, but we have to validate it with the
497 // browser before it can be used. This is to prevent a compromised
498 // renderer from running arbitrary code in the plugin process.
Mark Seaborn 2014/08/28 23:40:22 "plugin process" -> "NaCl process" to clarify
teravest 2014/09/04 22:13:30 Done.
499 DCHECK(!resolve_file_token_cb_.is_null());
500
501 // resolve_file_token_cb_ must be invoked from the main thread.
502 resolve_file_token_cb_.Run(
503 token_lo,
504 token_hi,
505 base::Bind(&NaClIPCAdapter::OnFileTokenResolved,
506 this,
507 msg));
508 return true;
Mark Seaborn 2014/08/28 23:40:22 Maybe comment: We don't release the message to NaC
teravest 2014/09/04 22:13:30 Done.
509 }
510 }
511 return RewriteMessage(msg, type);
512 }
513
514 bool NaClIPCAdapter::RewriteMessage(const IPC::Message& msg, uint32_t type) {
479 { 515 {
480 base::AutoLock lock(lock_); 516 base::AutoLock lock(lock_);
481 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); 517 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
482 518
483 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; 519 typedef std::vector<ppapi::proxy::SerializedHandle> Handles;
484 Handles handles; 520 Handles handles;
485 scoped_ptr<IPC::Message> new_msg; 521 scoped_ptr<IPC::Message> new_msg;
486 522
487 if (!locked_data_.nacl_msg_scanner_.ScanMessage( 523 if (!locked_data_.nacl_msg_scanner_.ScanMessage(
488 msg, type, &handles, &new_msg)) 524 msg, type, &handles, &new_msg))
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 585 }
550 if (new_msg) 586 if (new_msg)
551 SaveMessage(*new_msg, rewritten_msg.get()); 587 SaveMessage(*new_msg, rewritten_msg.get());
552 else 588 else
553 SaveMessage(msg, rewritten_msg.get()); 589 SaveMessage(msg, rewritten_msg.get());
554 } 590 }
555 cond_var_.Signal(); 591 cond_var_.Signal();
556 return true; 592 return true;
557 } 593 }
558 594
595 void NaClIPCAdapter::OnFileTokenResolved(const IPC::Message& orig_msg,
596 IPC::PlatformFileForTransit ipc_fd,
597 base::FilePath file_path) {
598 if (ipc_fd != IPC::InvalidPlatformFileForTransit()) {
Mark Seaborn 2014/08/28 23:40:22 Maybe handle the error case first for readability:
teravest 2014/09/04 22:13:30 Done.
599 // The file token was sucessfully resolved.
600 std::string file_path_str = file_path.AsUTF8Unsafe();
601 base::PlatformFile handle =
602 IPC::PlatformFileForTransitToPlatformFile(ipc_fd);
603 int32_t new_fd;
604 #if defined(OS_WIN)
605 // On Windows, valid handles are 32 bit unsigned integers so this is
606 // safe.
607 new_fd = reinterpret_cast<uintptr_t>(handle);
608 #else
609 new_fd = handle;
610 #endif
611 // The file token was resolved successfully, so we populate the new
612 // NaClDesc with that information.
613 char* alloc_file_path = static_cast<char*>(
614 malloc(file_path_str.length() + 1));
615 strcpy(alloc_file_path, file_path_str.c_str());
616 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
617 NaClDescIoDescFromHandleAllocCtor(
618 (NaClHandle) new_fd, NACL_ABI_O_RDONLY)));
619
620 // Mark the desc as OK for mmapping.
621 NaClDescMarkSafeForMmap(desc_wrapper->desc());
622
623 // Provide metadata for validation.
624 struct NaClRichFileInfo info;
625 NaClRichFileInfoCtor(&info);
626 info.known_file = 1;
627 info.file_path = alloc_file_path; // Takes ownership.
628 info.file_path_length =
629 static_cast<uint32_t>(file_path_str.length());
630 NaClSetFileOriginInfo(desc_wrapper->desc(), &info);
631 NaClRichFileInfoDtor(&info);
632 {
633 scoped_ptr<IPC::Message> new_msg(new IPC::Message(
634 orig_msg.routing_id(),
635 orig_msg.type(),
636 IPC::Message::PRIORITY_NORMAL));
637
638 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
639 // We have to rewrite the message a bit here to clear the file token
640 // data.
641 new_msg->set_reply();
642 new_msg->WriteInt(IPC::SyncMessage::GetMessageId(orig_msg));
643
644 // Write the SerializedHandle. There's only ever one in this message, so
645 // we just write an index of zero.
646 ppapi::proxy::SerializedHandle sh;
647 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0);
648 ppapi::proxy::SerializedHandle::WriteHeader(sh.header(),
649 new_msg.get());
650 new_msg->WriteBool(true);
651 new_msg->WriteInt(0);
652
653 // Write empty file tokens.
654 new_msg->WriteUInt64(0);
655 new_msg->WriteUInt64(0);
656
657 rewritten_msg->AddDescriptor(desc_wrapper.release());
658 {
659 base::AutoLock lock(lock_);
660 SaveMessage(*new_msg, rewritten_msg.get());
661 }
662 }
663 cond_var_.Signal();
664 } else {
665 RewriteMessage(orig_msg, PpapiHostMsg_OpenResource::ID);
666 }
667 }
668
559 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 669 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
560 } 670 }
561 671
562 void NaClIPCAdapter::OnChannelError() { 672 void NaClIPCAdapter::OnChannelError() {
563 CloseChannel(); 673 CloseChannel();
564 } 674 }
565 675
566 NaClIPCAdapter::~NaClIPCAdapter() { 676 NaClIPCAdapter::~NaClIPCAdapter() {
567 // Make sure the channel is deleted on the IO thread. 677 // Make sure the channel is deleted on the IO thread.
568 task_runner_->PostTask(FROM_HERE, 678 task_runner_->PostTask(FROM_HERE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 header.flags = msg.flags(); 793 header.flags = msg.flags();
684 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); 794 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
685 795
686 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); 796 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
687 locked_data_.to_be_received_.push(rewritten_msg); 797 locked_data_.to_be_received_.push(rewritten_msg);
688 } 798 }
689 799
690 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { 800 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) {
691 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); 801 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags);
692 } 802 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698