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

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: rebased 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 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
646 NaClDescIoDescFromHandleAllocCtor(
647 #if defined(OS_WIN)
648 sh.descriptor(),
649 #else
650 sh.descriptor().fd,
651 #endif
652 NACL_ABI_O_RDONLY)));
653
654 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
655 rewritten_msg->AddDescriptor(desc_wrapper.release());
656 {
657 base::AutoLock lock(lock_);
658 SaveMessage(*new_msg, rewritten_msg.get());
659 cond_var_.Signal();
660 }
661 return;
662 }
663
664 // The file token was sucessfully resolved.
665 std::string file_path_str = file_path.AsUTF8Unsafe();
666 base::PlatformFile handle =
667 IPC::PlatformFileForTransitToPlatformFile(ipc_fd);
668 // The file token was resolved successfully, so we populate the new
669 // NaClDesc with that information.
670 char* alloc_file_path = static_cast<char*>(
671 malloc(file_path_str.length() + 1));
672 strcpy(alloc_file_path, file_path_str.c_str());
673 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
674 NaClDescIoDescFromHandleAllocCtor(handle, NACL_ABI_O_RDONLY)));
675
676 // Mark the desc as OK for mapping as executable memory.
677 NaClDescMarkSafeForMmap(desc_wrapper->desc());
678
679 // Provide metadata for validation.
680 struct NaClRichFileInfo info;
681 NaClRichFileInfoCtor(&info);
682 info.known_file = 1;
683 info.file_path = alloc_file_path; // Takes ownership.
684 info.file_path_length =
685 static_cast<uint32_t>(file_path_str.length());
686 NaClSetFileOriginInfo(desc_wrapper->desc(), &info);
687 NaClRichFileInfoDtor(&info);
688
689 ppapi::proxy::SerializedHandle sh;
690 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0);
691 scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh);
692 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
693
694 rewritten_msg->AddDescriptor(desc_wrapper.release());
695 {
696 base::AutoLock lock(lock_);
697 SaveMessage(*new_msg, rewritten_msg.get());
698 cond_var_.Signal();
699 }
700 }
701
559 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 702 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
560 } 703 }
561 704
562 void NaClIPCAdapter::OnChannelError() { 705 void NaClIPCAdapter::OnChannelError() {
563 CloseChannel(); 706 CloseChannel();
564 } 707 }
565 708
566 NaClIPCAdapter::~NaClIPCAdapter() { 709 NaClIPCAdapter::~NaClIPCAdapter() {
567 // Make sure the channel is deleted on the IO thread. 710 // Make sure the channel is deleted on the IO thread.
568 task_runner_->PostTask(FROM_HERE, 711 task_runner_->PostTask(FROM_HERE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 header.flags = msg.flags(); 826 header.flags = msg.flags();
684 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); 827 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
685 828
686 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); 829 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
687 locked_data_.to_be_received_.push(rewritten_msg); 830 locked_data_.to_be_received_.push(rewritten_msg);
688 } 831 }
689 832
690 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { 833 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) {
691 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); 834 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags);
692 } 835 }
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