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

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 and dmichael 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.
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 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 589 }
550 if (new_msg) 590 if (new_msg)
551 SaveMessage(*new_msg, rewritten_msg.get()); 591 SaveMessage(*new_msg, rewritten_msg.get());
552 else 592 else
553 SaveMessage(msg, rewritten_msg.get()); 593 SaveMessage(msg, rewritten_msg.get());
554 } 594 }
555 cond_var_.Signal(); 595 cond_var_.Signal();
556 return true; 596 return true;
557 } 597 }
558 598
599 void NaClIPCAdapter::OnFileTokenResolved(const IPC::Message& orig_msg,
600 IPC::PlatformFileForTransit ipc_fd,
601 base::FilePath file_path) {
602 if (ipc_fd == IPC::InvalidPlatformFileForTransit()) {
603 RewriteMessage(orig_msg, PpapiHostMsg_OpenResource::ID);
teravest 2014/09/04 22:22:41 The failure on Windows is that we can't just rewri
Mark Seaborn 2014/09/05 15:43:46 OK, I'll look again after you've done that. BTW,
604 return;
605 }
606
607 // The file token was sucessfully resolved.
608 std::string file_path_str = file_path.AsUTF8Unsafe();
609 base::PlatformFile handle =
610 IPC::PlatformFileForTransitToPlatformFile(ipc_fd);
611 int32_t new_fd;
612 #if defined(OS_WIN)
613 // On Windows, valid handles are 32 bit unsigned integers so this is
614 // safe.
615 new_fd = reinterpret_cast<uintptr_t>(handle);
616 #else
617 new_fd = handle;
618 #endif
619 // The file token was resolved successfully, so we populate the new
620 // NaClDesc with that information.
621 char* alloc_file_path = static_cast<char*>(
622 malloc(file_path_str.length() + 1));
623 strcpy(alloc_file_path, file_path_str.c_str());
624 scoped_ptr<NaClDescWrapper> desc_wrapper(new NaClDescWrapper(
625 NaClDescIoDescFromHandleAllocCtor(
626 (NaClHandle) new_fd, NACL_ABI_O_RDONLY)));
627
628 // Mark the desc as OK for mmapping.
629 NaClDescMarkSafeForMmap(desc_wrapper->desc());
630
631 // Provide metadata for validation.
632 struct NaClRichFileInfo info;
633 NaClRichFileInfoCtor(&info);
634 info.known_file = 1;
635 info.file_path = alloc_file_path; // Takes ownership.
636 info.file_path_length =
637 static_cast<uint32_t>(file_path_str.length());
638 NaClSetFileOriginInfo(desc_wrapper->desc(), &info);
639 NaClRichFileInfoDtor(&info);
640 {
641 scoped_ptr<IPC::Message> new_msg(new IPC::Message(
642 orig_msg.routing_id(),
643 orig_msg.type(),
644 IPC::Message::PRIORITY_NORMAL));
645
646 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage);
647 // We have to rewrite the message a bit here to clear the file token
648 // data.
649 new_msg->set_reply();
650 new_msg->WriteInt(IPC::SyncMessage::GetMessageId(orig_msg));
651
652 // Write the SerializedHandle. There's only ever one in this message, so
653 // we just write an index of zero.
654 ppapi::proxy::SerializedHandle sh;
655 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0);
656 ppapi::proxy::SerializedHandle::WriteHeader(sh.header(),
657 new_msg.get());
658 new_msg->WriteBool(true);
659 new_msg->WriteInt(0);
660
661 // Write empty file tokens.
662 new_msg->WriteUInt64(0);
663 new_msg->WriteUInt64(0);
664
665 rewritten_msg->AddDescriptor(desc_wrapper.release());
666 {
667 base::AutoLock lock(lock_);
668 SaveMessage(*new_msg, rewritten_msg.get());
669 }
670 }
671 cond_var_.Signal();
672 }
673
559 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) { 674 void NaClIPCAdapter::OnChannelConnected(int32 peer_pid) {
560 } 675 }
561 676
562 void NaClIPCAdapter::OnChannelError() { 677 void NaClIPCAdapter::OnChannelError() {
563 CloseChannel(); 678 CloseChannel();
564 } 679 }
565 680
566 NaClIPCAdapter::~NaClIPCAdapter() { 681 NaClIPCAdapter::~NaClIPCAdapter() {
567 // Make sure the channel is deleted on the IO thread. 682 // Make sure the channel is deleted on the IO thread.
568 task_runner_->PostTask(FROM_HERE, 683 task_runner_->PostTask(FROM_HERE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 header.flags = msg.flags(); 798 header.flags = msg.flags();
684 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); 799 header.num_fds = static_cast<int>(rewritten_msg->desc_count());
685 800
686 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); 801 rewritten_msg->SetData(header, msg.payload(), msg.payload_size());
687 locked_data_.to_be_received_.push(rewritten_msg); 802 locked_data_.to_be_received_.push(rewritten_msg);
688 } 803 }
689 804
690 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { 805 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) {
691 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); 806 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags);
692 } 807 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698