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

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: fixes for mseaborn 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
« no previous file with comments | « components/nacl/loader/nacl_ipc_adapter.h ('k') | components/nacl/loader/nacl_listener.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 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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 } 460 }
459 461
460 #if defined(OS_POSIX) 462 #if defined(OS_POSIX)
461 int NaClIPCAdapter::TakeClientFileDescriptor() { 463 int NaClIPCAdapter::TakeClientFileDescriptor() {
462 return io_thread_data_.channel_->TakeClientFileDescriptor(); 464 return io_thread_data_.channel_->TakeClientFileDescriptor();
463 } 465 }
464 #endif 466 #endif
465 467
466 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { 468 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) {
467 uint32_t type = msg.type(); 469 uint32_t type = msg.type();
470
468 if (type == IPC_REPLY_ID) { 471 if (type == IPC_REPLY_ID) {
469 int id = IPC::SyncMessage::GetMessageId(msg); 472 int id = IPC::SyncMessage::GetMessageId(msg);
470 IOThreadData::PendingSyncMsgMap::iterator it = 473 IOThreadData::PendingSyncMsgMap::iterator it =
471 io_thread_data_.pending_sync_msgs_.find(id); 474 io_thread_data_.pending_sync_msgs_.find(id);
472 DCHECK(it != io_thread_data_.pending_sync_msgs_.end()); 475 DCHECK(it != io_thread_data_.pending_sync_msgs_.end());
473 if (it != io_thread_data_.pending_sync_msgs_.end()) { 476 if (it != io_thread_data_.pending_sync_msgs_.end()) {
474 type = it->second; 477 type = it->second;
475 io_thread_data_.pending_sync_msgs_.erase(it); 478 io_thread_data_.pending_sync_msgs_.erase(it);
476 } 479 }
477 } 480 }
481 // Handle PpapiHostMsg_OpenResource outside the lock as it requires sending
482 // IPC to handle properly.
483 if (type == PpapiHostMsg_OpenResource::ID) {
484 PickleIterator iter = IPC::SyncMessage::GetDataIterator(&msg);
485 ppapi::proxy::SerializedHandle sh;
486 uint64_t token_lo;
487 uint64_t token_hi;
488 if (!IPC::ReadParam(&msg, &iter, &sh) ||
489 !IPC::ReadParam(&msg, &iter, &token_lo) ||
490 !IPC::ReadParam(&msg, &iter, &token_hi)) {
491 return false;
492 }
478 493
494 if (sh.IsHandleValid() && (token_lo != 0 || token_hi != 0)) {
495 // We've received a valid file token. Instead of using the file
496 // descriptor received, we send the file token to the browser in
497 // exchange for a new file descriptor and file path information.
498 // That file descriptor can be used to construct a NaClDesc with
499 // identity-based validation caching.
500 //
501 // We do not use file descriptors from the renderer with validation
502 // caching; a compromised renderer should not be able to run
503 // arbitrary code in a plugin process.
504 DCHECK(!resolve_file_token_cb_.is_null());
505
506 // resolve_file_token_cb_ must be invoked from the main thread.
507 resolve_file_token_cb_.Run(
508 token_lo,
509 token_hi,
510 base::Bind(&NaClIPCAdapter::OnFileTokenResolved,
511 this,
512 msg));
513
514 // In this case, we don't release the message to NaCl untrusted code
515 // immediately. We defer it until we get an async message back from the
516 // browser process.
517 return true;
518 }
519 }
520 return RewriteMessage(msg, type);
521 }
522
523 bool NaClIPCAdapter::RewriteMessage(const IPC::Message& msg, uint32_t type) {
479 { 524 {
480 base::AutoLock lock(lock_); 525 base::AutoLock lock(lock_);
481 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); 526 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
482 527
483 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; 528 typedef std::vector<ppapi::proxy::SerializedHandle> Handles;
484 Handles handles; 529 Handles handles;
485 scoped_ptr<IPC::Message> new_msg; 530 scoped_ptr<IPC::Message> new_msg;
486 531
487 if (!locked_data_.nacl_msg_scanner_.ScanMessage( 532 if (!locked_data_.nacl_msg_scanner_.ScanMessage(
488 msg, type, &handles, &new_msg)) 533 msg, type, &handles, &new_msg))
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 desc = MakeNaClDescQuota( 576 desc = MakeNaClDescQuota(
532 locked_data_.nacl_msg_scanner_.GetFile(iter->file_io()), 577 locked_data_.nacl_msg_scanner_.GetFile(iter->file_io()),
533 desc); 578 desc);
534 } 579 }
535 if (desc) 580 if (desc)
536 nacl_desc.reset(new NaClDescWrapper(desc)); 581 nacl_desc.reset(new NaClDescWrapper(desc));
537 break; 582 break;
538 } 583 }
539 584
540 case ppapi::proxy::SerializedHandle::INVALID: { 585 case ppapi::proxy::SerializedHandle::INVALID: {
541 // Nothing to do. TODO(dmichael): Should we log this? Or is it 586 // Nothing to do.
542 // sometimes okay to pass an INVALID handle?
543 break; 587 break;
544 } 588 }
545 // No default, so the compiler will warn us if new types get added. 589 // No default, so the compiler will warn us if new types get added.
546 } 590 }
547 if (nacl_desc.get()) 591 if (nacl_desc.get())
548 rewritten_msg->AddDescriptor(nacl_desc.release()); 592 rewritten_msg->AddDescriptor(nacl_desc.release());
549 } 593 }
550 if (new_msg) 594 if (new_msg)
551 SaveMessage(*new_msg, rewritten_msg.get()); 595 SaveMessage(*new_msg, rewritten_msg.get());
552 else 596 else
553 SaveMessage(msg, rewritten_msg.get()); 597 SaveMessage(msg, rewritten_msg.get());
554 cond_var_.Signal(); 598 cond_var_.Signal();
555 } 599 }
556 return true; 600 return true;
557 } 601 }
558 602
603 scoped_ptr<IPC::Message> CreateOpenResourceReply(
604 const IPC::Message& orig_msg,
605 ppapi::proxy::SerializedHandle sh) {
606 // The creation of new_msg must be kept in sync with
607 // SyncMessage::WriteSyncHeader.
608 scoped_ptr<IPC::Message> new_msg(new IPC::Message(
609 orig_msg.routing_id(),
610 orig_msg.type(),
611 IPC::Message::PRIORITY_NORMAL));
612 new_msg->set_reply();
613 new_msg->WriteInt(IPC::SyncMessage::GetMessageId(orig_msg));
614
615 ppapi::proxy::SerializedHandle::WriteHeader(sh.header(),
616 new_msg.get());
617 new_msg->WriteBool(true); // valid == true
618 // The file descriptor is at index 0. There's only ever one file
619 // descriptor provided for this message type, so this will be correct.
620 new_msg->WriteInt(0);
621
622 // Write empty file tokens.
623 new_msg->WriteUInt64(0); // token_lo
624 new_msg->WriteUInt64(0); // token_hi
625 return new_msg.Pass();
626 }
627
628 void NaClIPCAdapter::OnFileTokenResolved(const IPC::Message& orig_msg,
629 IPC::PlatformFileForTransit ipc_fd,
630 base::FilePath file_path) {
631 // The path where an invalid ipc_fd is returned isn't currently
632 // covered by any tests.
633 if (ipc_fd == IPC::InvalidPlatformFileForTransit()) {
634 // The file token didn't resolve successfully, so we give the
635 // original FD to the client without making a validated NaClDesc.
636 // However, we must rewrite the message to clear the file tokens.
637 PickleIterator iter = IPC::SyncMessage::GetDataIterator(&orig_msg);
638 ppapi::proxy::SerializedHandle sh;
639
640 // We know that this can be read safely; see the original read in
641 // OnMessageReceived().
642 CHECK(IPC::ReadParam(&orig_msg, &iter, &sh));
643 scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh);
644
645 // TODO(teravest): Clean up NaClHandle casting throughout this file.
646 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
647 NaClDescIoDescFromHandleAllocCtor(
648 #if defined(OS_WIN)
649 (NaClHandle) sh.descriptor(),
650 #else
651 (NaClHandle) sh.descriptor().fd,
dmichael (off chromium) 2014/09/09 19:19:44 We don't cast at all on 570 and 572; are you sure
652 #endif
653 NACL_ABI_O_RDONLY)));
654
655 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
656 rewritten_msg->AddDescriptor(desc_wrapper.release());
657 {
658 base::AutoLock lock(lock_);
659 SaveMessage(*new_msg, rewritten_msg.get());
660 cond_var_.Signal();
661 }
662 return;
663 }
664
665 // The file token was sucessfully resolved.
666 std::string file_path_str = file_path.AsUTF8Unsafe();
667 base::PlatformFile handle =
668 IPC::PlatformFileForTransitToPlatformFile(ipc_fd);
669 int32_t new_fd;
670 #if defined(OS_WIN)
671 // On Windows, valid handles are 32 bit unsigned integers so this is
672 // safe.
673 new_fd = reinterpret_cast<uintptr_t>(handle);
674 #else
675 new_fd = handle;
dmichael (off chromium) 2014/09/09 19:19:44 Why do you need to do this stuff? Could you just p
676 #endif
677 // The file token was resolved successfully, so we populate the new
678 // NaClDesc with that information.
679 char* alloc_file_path = static_cast<char*>(
680 malloc(file_path_str.length() + 1));
681 strcpy(alloc_file_path, file_path_str.c_str());
682 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
683 NaClDescIoDescFromHandleAllocCtor(
684 (NaClHandle) new_fd, NACL_ABI_O_RDONLY)));
685
686 // Mark the desc as OK for mmapping.
dmichael (off chromium) 2014/09/09 19:19:43 I think this *really* marks it as safe for mapping
687 NaClDescMarkSafeForMmap(desc_wrapper->desc());
688
689 // Provide metadata for validation.
690 struct NaClRichFileInfo info;
691 NaClRichFileInfoCtor(&info);
692 info.known_file = 1;
693 info.file_path = alloc_file_path; // Takes ownership.
694 info.file_path_length =
695 static_cast<uint32_t>(file_path_str.length());
696 NaClSetFileOriginInfo(desc_wrapper->desc(), &info);
697 NaClRichFileInfoDtor(&info);
698
699 ppapi::proxy::SerializedHandle sh;
700 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0);
701 scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh);
702 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
703
704 rewritten_msg->AddDescriptor(desc_wrapper.release());
705 {
706 base::AutoLock lock(lock_);
707 SaveMessage(*new_msg, rewritten_msg.get());
708 cond_var_.Signal();
709 }
710 }
711
559 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 712 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
560 } 713 }
561 714
562 void NaClIPCAdapter::OnChannelError() { 715 void NaClIPCAdapter::OnChannelError() {
563 CloseChannel(); 716 CloseChannel();
564 } 717 }
565 718
566 NaClIPCAdapter::~NaClIPCAdapter() { 719 NaClIPCAdapter::~NaClIPCAdapter() {
567 // Make sure the channel is deleted on the IO thread. 720 // Make sure the channel is deleted on the IO thread.
568 task_runner_->PostTask(FROM_HERE, 721 task_runner_->PostTask(FROM_HERE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 header.flags = msg.flags(); 836 header.flags = msg.flags();
684 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); 837 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
685 838
686 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); 839 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
687 locked_data_.to_be_received_.push(rewritten_msg); 840 locked_data_.to_be_received_.push(rewritten_msg);
688 } 841 }
689 842
690 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { 843 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) {
691 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); 844 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags);
692 } 845 }
OLDNEW
« no previous file with comments | « components/nacl/loader/nacl_ipc_adapter.h ('k') | components/nacl/loader/nacl_listener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698