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 |