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

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: Add comment at WriteHandle 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();
Mark Seaborn 2014/09/09 04:42:30 I can't see any uses of this.
teravest 2014/09/09 16:49:06 Removed.
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.
484 if (type == PpapiHostMsg_OpenResource::ID) {
485 PickleIterator iter = IPC::SyncMessage::GetDataIterator(&msg);
486 ppapi::proxy::SerializedHandle sh;
487 uint64_t token_lo;
488 uint64_t token_hi;
489 if (!IPC::ReadParam(&msg, &iter, &sh) ||
490 !IPC::ReadParam(&msg, &iter, &token_lo) ||
491 !IPC::ReadParam(&msg, &iter, &token_hi)) {
492 return false;
493 }
478 494
495 if (sh.IsHandleValid() && (token_lo != 0 || token_hi != 0)) {
496 // We've received a valid file token, but we have to validate it with the
Mark Seaborn 2014/09/09 04:42:29 This is a little misleading. The token doesn't *h
teravest 2014/09/09 16:49:06 I've reworded this to be more precise, but it's a
497 // browser before it can be used. This is to prevent a compromised
498 // renderer from running arbitrary code in the NaCl process.
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
509 // In this case, we don't release the message to NaCl untrusted code
510 // immediately. We defer it until we get an async message back from the
511 // browser process.
512 return true;
513 }
514 }
515 return RewriteMessage(msg, type);
516 }
517
518 bool NaClIPCAdapter::RewriteMessage(const IPC::Message& msg, uint32_t type) {
479 { 519 {
480 base::AutoLock lock(lock_); 520 base::AutoLock lock(lock_);
481 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); 521 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
482 522
483 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; 523 typedef std::vector<ppapi::proxy::SerializedHandle> Handles;
484 Handles handles; 524 Handles handles;
485 scoped_ptr<IPC::Message> new_msg; 525 scoped_ptr<IPC::Message> new_msg;
486 526
487 if (!locked_data_.nacl_msg_scanner_.ScanMessage( 527 if (!locked_data_.nacl_msg_scanner_.ScanMessage(
488 msg, type, &handles, &new_msg)) 528 msg, type, &handles, &new_msg))
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 desc = MakeNaClDescQuota( 571 desc = MakeNaClDescQuota(
532 locked_data_.nacl_msg_scanner_.GetFile(iter->file_io()), 572 locked_data_.nacl_msg_scanner_.GetFile(iter->file_io()),
533 desc); 573 desc);
534 } 574 }
535 if (desc) 575 if (desc)
536 nacl_desc.reset(new NaClDescWrapper(desc)); 576 nacl_desc.reset(new NaClDescWrapper(desc));
537 break; 577 break;
538 } 578 }
539 579
540 case ppapi::proxy::SerializedHandle::INVALID: { 580 case ppapi::proxy::SerializedHandle::INVALID: {
541 // Nothing to do. TODO(dmichael): Should we log this? Or is it 581 // Nothing to do.
542 // sometimes okay to pass an INVALID handle?
543 break; 582 break;
544 } 583 }
545 // No default, so the compiler will warn us if new types get added. 584 // No default, so the compiler will warn us if new types get added.
546 } 585 }
547 if (nacl_desc.get()) 586 if (nacl_desc.get())
548 rewritten_msg->AddDescriptor(nacl_desc.release()); 587 rewritten_msg->AddDescriptor(nacl_desc.release());
549 } 588 }
550 if (new_msg) 589 if (new_msg)
551 SaveMessage(*new_msg, rewritten_msg.get()); 590 SaveMessage(*new_msg, rewritten_msg.get());
552 else 591 else
553 SaveMessage(msg, rewritten_msg.get()); 592 SaveMessage(msg, rewritten_msg.get());
554 cond_var_.Signal(); 593 cond_var_.Signal();
555 } 594 }
556 return true; 595 return true;
557 } 596 }
558 597
598 scoped_ptr<IPC::Message> CreateOpenResourceReply(
599 const IPC::Message& orig_msg,
600 ppapi::proxy::SerializedHandle sh) {
601 scoped_ptr<IPC::Message> new_msg(new IPC::Message(
602 orig_msg.routing_id(),
603 orig_msg.type(),
604 IPC::Message::PRIORITY_NORMAL));
605
606 // We have to rewrite the message a bit here to clear the file token
607 // data.
608 new_msg->set_reply();
609 new_msg->WriteInt(IPC::SyncMessage::GetMessageId(orig_msg));
Mark Seaborn 2014/09/09 04:42:29 Comment that this needs to be kept in sync with Sy
teravest 2014/09/09 16:49:06 I've added a comment. Nothing ensures that this is
610
611 // Write the SerializedHandle. There's only ever one in this message, so
612 // we just write an index of zero.
613 ppapi::proxy::SerializedHandle::WriteHeader(sh.header(),
614 new_msg.get());
615 new_msg->WriteBool(true);
Mark Seaborn 2014/09/09 04:42:30 Comment that this is the "valid" field here? What
teravest 2014/09/09 16:49:06 I've added a comment. Nothing keeps this in sync,
616 new_msg->WriteInt(0);
Mark Seaborn 2014/09/09 04:42:29 Comment that this is the index into the message's
teravest 2014/09/09 16:49:06 Done.
617
618 // Write empty file tokens.
619 new_msg->WriteUInt64(0);
Mark Seaborn 2014/09/09 04:42:29 Comment "// token_{lo,hi}" here?
teravest 2014/09/09 16:49:06 Done.
620 new_msg->WriteUInt64(0);
621 return new_msg.Pass();
622 }
623
624 void NaClIPCAdapter::OnFileTokenResolved(const IPC::Message& orig_msg,
625 IPC::PlatformFileForTransit ipc_fd,
626 base::FilePath file_path) {
627 if (ipc_fd == IPC::InvalidPlatformFileForTransit()) {
628 // The file token didn't resolve successfully, so we give the
Mark Seaborn 2014/09/09 04:42:29 IIRC, this path only happens when the GetFilePath(
teravest 2014/09/09 16:49:06 I've added a comment.
629 // original FD to the client without making a validated NaClDesc.
630 // However, we must rewrite the message to clear the file tokens.
631 PickleIterator iter = IPC::SyncMessage::GetDataIterator(&orig_msg);
632 ppapi::proxy::SerializedHandle sh;
633
634 // We know that this can be read safely; see the original read in
635 // OnMessageRecieved().
Mark Seaborn 2014/09/09 04:42:30 "Received"
teravest 2014/09/09 16:49:06 Done.
636 CHECK(IPC::ReadParam(&orig_msg, &iter, &sh));
637 scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh);
638
639 // TODO(teravest): Clean up NaClHandle casting throughout this file.
640
641 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
642 NaClDescIoDescFromHandleAllocCtor(
643 #if defined(OS_WIN)
644 (NaClHandle) sh.descriptor(),
645 #else
646 (NaClHandle) sh.descriptor().fd,
647 #endif
648 NACL_ABI_O_RDONLY)));
649
650 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
651 rewritten_msg->AddDescriptor(desc_wrapper.release());
652 {
653 base::AutoLock lock(lock_);
654 SaveMessage(*new_msg, rewritten_msg.get());
655 cond_var_.Signal();
656 }
657 return;
658 }
659
660 // The file token was sucessfully resolved.
661 std::string file_path_str = file_path.AsUTF8Unsafe();
662 base::PlatformFile handle =
663 IPC::PlatformFileForTransitToPlatformFile(ipc_fd);
664 int32_t new_fd;
665 #if defined(OS_WIN)
666 // On Windows, valid handles are 32 bit unsigned integers so this is
667 // safe.
668 new_fd = reinterpret_cast<uintptr_t>(handle);
669 #else
670 new_fd = handle;
671 #endif
672 // The file token was resolved successfully, so we populate the new
673 // NaClDesc with that information.
674 char* alloc_file_path = static_cast<char*>(
675 malloc(file_path_str.length() + 1));
676 strcpy(alloc_file_path, file_path_str.c_str());
677 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
678 NaClDescIoDescFromHandleAllocCtor(
679 (NaClHandle) new_fd, NACL_ABI_O_RDONLY)));
680
681 // Mark the desc as OK for mmapping.
682 NaClDescMarkSafeForMmap(desc_wrapper->desc());
683
684 // Provide metadata for validation.
685 struct NaClRichFileInfo info;
686 NaClRichFileInfoCtor(&info);
687 info.known_file = 1;
688 info.file_path = alloc_file_path; // Takes ownership.
689 info.file_path_length =
690 static_cast<uint32_t>(file_path_str.length());
691 NaClSetFileOriginInfo(desc_wrapper->desc(), &info);
692 NaClRichFileInfoDtor(&info);
693
694 ppapi::proxy::SerializedHandle sh;
695 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0);
696 scoped_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh);
697 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
698
699 rewritten_msg->AddDescriptor(desc_wrapper.release());
700 {
701 base::AutoLock lock(lock_);
702 SaveMessage(*new_msg, rewritten_msg.get());
703 cond_var_.Signal();
704 }
705 }
706
559 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 707 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
560 } 708 }
561 709
562 void NaClIPCAdapter::OnChannelError() { 710 void NaClIPCAdapter::OnChannelError() {
563 CloseChannel(); 711 CloseChannel();
564 } 712 }
565 713
566 NaClIPCAdapter::~NaClIPCAdapter() { 714 NaClIPCAdapter::~NaClIPCAdapter() {
567 // Make sure the channel is deleted on the IO thread. 715 // Make sure the channel is deleted on the IO thread.
568 task_runner_->PostTask(FROM_HERE, 716 task_runner_->PostTask(FROM_HERE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 header.flags = msg.flags(); 831 header.flags = msg.flags();
684 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); 832 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
685 833
686 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); 834 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
687 locked_data_.to_be_received_.push(rewritten_msg); 835 locked_data_.to_be_received_.push(rewritten_msg);
688 } 836 }
689 837
690 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { 838 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) {
691 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); 839 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags);
692 } 840 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698