| OLD | NEW |
| 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 <memory> | 10 #include <memory> |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 handle.GetHandle(), | 243 handle.GetHandle(), |
| 244 #else | 244 #else |
| 245 base::SharedMemory::GetFdFromSharedMemoryHandle(handle), | 245 base::SharedMemory::GetFdFromSharedMemoryHandle(handle), |
| 246 #endif | 246 #endif |
| 247 size))); | 247 size))); |
| 248 #endif | 248 #endif |
| 249 } | 249 } |
| 250 | 250 |
| 251 } // namespace | 251 } // namespace |
| 252 | 252 |
| 253 class NaClIPCAdapter::RewrittenMessage | 253 class NaClIPCAdapter::RewrittenMessage { |
| 254 : public base::RefCounted<RewrittenMessage> { | |
| 255 public: | 254 public: |
| 256 RewrittenMessage(); | 255 RewrittenMessage(); |
| 256 ~RewrittenMessage() {} |
| 257 | 257 |
| 258 bool is_consumed() const { return data_read_cursor_ == data_len_; } | 258 bool is_consumed() const { return data_read_cursor_ == data_len_; } |
| 259 | 259 |
| 260 void SetData(const NaClIPCAdapter::NaClMessageHeader& header, | 260 void SetData(const NaClIPCAdapter::NaClMessageHeader& header, |
| 261 const void* payload, size_t payload_length); | 261 const void* payload, size_t payload_length); |
| 262 | 262 |
| 263 int Read(NaClImcTypedMsgHdr* msg); | 263 int Read(NaClImcTypedMsgHdr* msg); |
| 264 | 264 |
| 265 void AddDescriptor(NaClDescWrapper* desc) { descs_.push_back(desc); } | 265 void AddDescriptor(NaClDescWrapper* desc) { descs_.push_back(desc); } |
| 266 | 266 |
| 267 size_t desc_count() const { return descs_.size(); } | 267 size_t desc_count() const { return descs_.size(); } |
| 268 | 268 |
| 269 private: | 269 private: |
| 270 friend class base::RefCounted<RewrittenMessage>; | |
| 271 ~RewrittenMessage() {} | |
| 272 | |
| 273 std::unique_ptr<char[]> data_; | 270 std::unique_ptr<char[]> data_; |
| 274 size_t data_len_; | 271 size_t data_len_; |
| 275 | 272 |
| 276 // Offset into data where the next read will happen. This will be equal to | 273 // Offset into data where the next read will happen. This will be equal to |
| 277 // data_len_ when all data has been consumed. | 274 // data_len_ when all data has been consumed. |
| 278 size_t data_read_cursor_; | 275 size_t data_read_cursor_; |
| 279 | 276 |
| 280 // Wrapped descriptors for transfer to untrusted code. | 277 // Wrapped descriptors for transfer to untrusted code. |
| 281 ScopedVector<NaClDescWrapper> descs_; | 278 ScopedVector<NaClDescWrapper> descs_; |
| 282 }; | 279 }; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // browser process. | 529 // browser process. |
| 533 return true; | 530 return true; |
| 534 } | 531 } |
| 535 } | 532 } |
| 536 return RewriteMessage(msg, type); | 533 return RewriteMessage(msg, type); |
| 537 } | 534 } |
| 538 | 535 |
| 539 bool NaClIPCAdapter::RewriteMessage(const IPC::Message& msg, uint32_t type) { | 536 bool NaClIPCAdapter::RewriteMessage(const IPC::Message& msg, uint32_t type) { |
| 540 { | 537 { |
| 541 base::AutoLock lock(lock_); | 538 base::AutoLock lock(lock_); |
| 542 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); | 539 std::unique_ptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); |
| 543 | 540 |
| 544 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; | 541 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; |
| 545 Handles handles; | 542 Handles handles; |
| 546 std::unique_ptr<IPC::Message> new_msg; | 543 std::unique_ptr<IPC::Message> new_msg; |
| 547 | 544 |
| 548 if (!locked_data_.nacl_msg_scanner_.ScanMessage( | 545 if (!locked_data_.nacl_msg_scanner_.ScanMessage( |
| 549 msg, type, &handles, &new_msg)) | 546 msg, type, &handles, &new_msg)) |
| 550 return false; | 547 return false; |
| 551 | 548 |
| 552 // Now add any descriptors we found to rewritten_msg. |handles| is usually | 549 // Now add any descriptors we found to rewritten_msg. |handles| is usually |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 case ppapi::proxy::SerializedHandle::INVALID: { | 591 case ppapi::proxy::SerializedHandle::INVALID: { |
| 595 // Nothing to do. | 592 // Nothing to do. |
| 596 break; | 593 break; |
| 597 } | 594 } |
| 598 // No default, so the compiler will warn us if new types get added. | 595 // No default, so the compiler will warn us if new types get added. |
| 599 } | 596 } |
| 600 if (nacl_desc.get()) | 597 if (nacl_desc.get()) |
| 601 rewritten_msg->AddDescriptor(nacl_desc.release()); | 598 rewritten_msg->AddDescriptor(nacl_desc.release()); |
| 602 } | 599 } |
| 603 if (new_msg) | 600 if (new_msg) |
| 604 SaveMessage(*new_msg, rewritten_msg.get()); | 601 SaveMessage(*new_msg, std::move(rewritten_msg)); |
| 605 else | 602 else |
| 606 SaveMessage(msg, rewritten_msg.get()); | 603 SaveMessage(msg, std::move(rewritten_msg)); |
| 607 cond_var_.Signal(); | 604 cond_var_.Signal(); |
| 608 } | 605 } |
| 609 return true; | 606 return true; |
| 610 } | 607 } |
| 611 | 608 |
| 612 std::unique_ptr<IPC::Message> CreateOpenResourceReply( | 609 std::unique_ptr<IPC::Message> CreateOpenResourceReply( |
| 613 const IPC::Message& orig_msg, | 610 const IPC::Message& orig_msg, |
| 614 ppapi::proxy::SerializedHandle sh) { | 611 ppapi::proxy::SerializedHandle sh) { |
| 615 // The creation of new_msg must be kept in sync with | 612 // The creation of new_msg must be kept in sync with |
| 616 // SyncMessage::WriteSyncHeader. | 613 // SyncMessage::WriteSyncHeader. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 | 658 |
| 662 std::unique_ptr<NaClDescWrapper> desc_wrapper( | 659 std::unique_ptr<NaClDescWrapper> desc_wrapper( |
| 663 new NaClDescWrapper(NaClDescIoMakeFromHandle( | 660 new NaClDescWrapper(NaClDescIoMakeFromHandle( |
| 664 #if defined(OS_WIN) | 661 #if defined(OS_WIN) |
| 665 orig_sh.descriptor().GetHandle(), | 662 orig_sh.descriptor().GetHandle(), |
| 666 #else | 663 #else |
| 667 orig_sh.descriptor().fd, | 664 orig_sh.descriptor().fd, |
| 668 #endif | 665 #endif |
| 669 NACL_ABI_O_RDONLY))); | 666 NACL_ABI_O_RDONLY))); |
| 670 | 667 |
| 671 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); | 668 std::unique_ptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); |
| 672 rewritten_msg->AddDescriptor(desc_wrapper.release()); | 669 rewritten_msg->AddDescriptor(desc_wrapper.release()); |
| 673 { | 670 { |
| 674 base::AutoLock lock(lock_); | 671 base::AutoLock lock(lock_); |
| 675 SaveMessage(*new_msg, rewritten_msg.get()); | 672 SaveMessage(*new_msg, std::move(rewritten_msg)); |
| 676 cond_var_.Signal(); | 673 cond_var_.Signal(); |
| 677 } | 674 } |
| 678 return; | 675 return; |
| 679 } | 676 } |
| 680 | 677 |
| 681 // The file token was successfully resolved. | 678 // The file token was successfully resolved. |
| 682 std::string file_path_str = file_path.AsUTF8Unsafe(); | 679 std::string file_path_str = file_path.AsUTF8Unsafe(); |
| 683 base::PlatformFile handle = | 680 base::PlatformFile handle = |
| 684 IPC::PlatformFileForTransitToPlatformFile(ipc_fd); | 681 IPC::PlatformFileForTransitToPlatformFile(ipc_fd); |
| 685 | 682 |
| 686 ppapi::proxy::SerializedHandle sh; | 683 ppapi::proxy::SerializedHandle sh; |
| 687 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0); | 684 sh.set_file_handle(ipc_fd, PP_FILEOPENFLAG_READ, 0); |
| 688 std::unique_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh); | 685 std::unique_ptr<IPC::Message> new_msg = CreateOpenResourceReply(orig_msg, sh); |
| 689 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); | 686 std::unique_ptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); |
| 690 | 687 |
| 691 struct NaClDesc* desc = | 688 struct NaClDesc* desc = |
| 692 NaClDescCreateWithFilePathMetadata(handle, file_path_str.c_str()); | 689 NaClDescCreateWithFilePathMetadata(handle, file_path_str.c_str()); |
| 693 rewritten_msg->AddDescriptor(new NaClDescWrapper(desc)); | 690 rewritten_msg->AddDescriptor(new NaClDescWrapper(desc)); |
| 694 { | 691 { |
| 695 base::AutoLock lock(lock_); | 692 base::AutoLock lock(lock_); |
| 696 SaveMessage(*new_msg, rewritten_msg.get()); | 693 SaveMessage(*new_msg, std::move(rewritten_msg)); |
| 697 cond_var_.Signal(); | 694 cond_var_.Signal(); |
| 698 } | 695 } |
| 699 } | 696 } |
| 700 | 697 |
| 701 void NaClIPCAdapter::OnChannelConnected(int32_t peer_pid) {} | 698 void NaClIPCAdapter::OnChannelConnected(int32_t peer_pid) {} |
| 702 | 699 |
| 703 void NaClIPCAdapter::OnChannelError() { | 700 void NaClIPCAdapter::OnChannelError() { |
| 704 CloseChannel(); | 701 CloseChannel(); |
| 705 } | 702 } |
| 706 | 703 |
| 707 NaClIPCAdapter::~NaClIPCAdapter() { | 704 NaClIPCAdapter::~NaClIPCAdapter() { |
| 708 // Make sure the channel is deleted on the IO thread. | 705 // Make sure the channel is deleted on the IO thread. |
| 709 task_runner_->PostTask(FROM_HERE, | 706 task_runner_->PostTask(FROM_HERE, |
| 710 base::Bind(&DeleteChannel, io_thread_data_.channel_.release())); | 707 base::Bind(&DeleteChannel, io_thread_data_.channel_.release())); |
| 711 } | 708 } |
| 712 | 709 |
| 713 int NaClIPCAdapter::LockedReceive(NaClImcTypedMsgHdr* msg) { | 710 int NaClIPCAdapter::LockedReceive(NaClImcTypedMsgHdr* msg) { |
| 714 lock_.AssertAcquired(); | 711 lock_.AssertAcquired(); |
| 715 | 712 |
| 716 if (locked_data_.to_be_received_.empty()) | 713 if (locked_data_.to_be_received_.empty()) |
| 717 return 0; | 714 return 0; |
| 718 scoped_refptr<RewrittenMessage> current = | 715 RewrittenMessage& current = *locked_data_.to_be_received_.front(); |
| 719 locked_data_.to_be_received_.front(); | |
| 720 | 716 |
| 721 int retval = current->Read(msg); | 717 int retval = current.Read(msg); |
| 722 | 718 |
| 723 // When a message is entirely consumed, remove if from the waiting queue. | 719 // When a message is entirely consumed, remove it from the waiting queue. |
| 724 if (current->is_consumed()) | 720 if (current.is_consumed()) |
| 725 locked_data_.to_be_received_.pop(); | 721 locked_data_.to_be_received_.pop(); |
| 726 | 722 |
| 727 return retval; | 723 return retval; |
| 728 } | 724 } |
| 729 | 725 |
| 730 bool NaClIPCAdapter::SendCompleteMessage(const char* buffer, | 726 bool NaClIPCAdapter::SendCompleteMessage(const char* buffer, |
| 731 size_t buffer_len) { | 727 size_t buffer_len) { |
| 732 lock_.AssertAcquired(); | 728 lock_.AssertAcquired(); |
| 733 // The message will have already been validated, so we know it's large enough | 729 // The message will have already been validated, so we know it's large enough |
| 734 // for our header. | 730 // for our header. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 // The callback sent a reply to the untrusted side. | 815 // The callback sent a reply to the untrusted side. |
| 820 return; | 816 return; |
| 821 } | 817 } |
| 822 } | 818 } |
| 823 | 819 |
| 824 if (message->is_sync()) | 820 if (message->is_sync()) |
| 825 io_thread_data_.pending_sync_msgs_[id] = message->type(); | 821 io_thread_data_.pending_sync_msgs_[id] = message->type(); |
| 826 io_thread_data_.channel_->Send(message.release()); | 822 io_thread_data_.channel_->Send(message.release()); |
| 827 } | 823 } |
| 828 | 824 |
| 829 void NaClIPCAdapter::SaveMessage(const IPC::Message& msg, | 825 void NaClIPCAdapter::SaveMessage( |
| 830 RewrittenMessage* rewritten_msg) { | 826 const IPC::Message& msg, |
| 827 std::unique_ptr<RewrittenMessage> rewritten_msg) { |
| 831 lock_.AssertAcquired(); | 828 lock_.AssertAcquired(); |
| 832 // There is some padding in this structure (the "padding" member is 16 | 829 // There is some padding in this structure (the "padding" member is 16 |
| 833 // bits but this then gets padded to 32 bits). We want to be sure not to | 830 // bits but this then gets padded to 32 bits). We want to be sure not to |
| 834 // leak data to the untrusted plugin, so zero everything out first. | 831 // leak data to the untrusted plugin, so zero everything out first. |
| 835 NaClMessageHeader header; | 832 NaClMessageHeader header; |
| 836 memset(&header, 0, sizeof(NaClMessageHeader)); | 833 memset(&header, 0, sizeof(NaClMessageHeader)); |
| 837 | 834 |
| 838 header.payload_size = static_cast<uint32_t>(msg.payload_size()); | 835 header.payload_size = static_cast<uint32_t>(msg.payload_size()); |
| 839 header.routing = msg.routing_id(); | 836 header.routing = msg.routing_id(); |
| 840 header.type = msg.type(); | 837 header.type = msg.type(); |
| 841 header.flags = msg.flags(); | 838 header.flags = msg.flags(); |
| 842 header.num_fds = static_cast<uint16_t>(rewritten_msg->desc_count()); | 839 header.num_fds = static_cast<uint16_t>(rewritten_msg->desc_count()); |
| 843 | 840 |
| 844 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); | 841 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); |
| 845 locked_data_.to_be_received_.push(rewritten_msg); | 842 locked_data_.to_be_received_.push(std::move(rewritten_msg)); |
| 846 } | 843 } |
| 847 | 844 |
| 848 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { | 845 int TranslatePepperFileReadWriteOpenFlagsForTesting(int32_t pp_open_flags) { |
| 849 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); | 846 return TranslatePepperFileReadWriteOpenFlags(pp_open_flags); |
| 850 } | 847 } |
| OLD | NEW |