OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/nacl/nacl_ipc_adapter.h" | 5 #include "chrome/nacl/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/shared_memory.h" | 14 #include "base/shared_memory.h" |
15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
16 #include "ipc/ipc_channel.h" | 16 #include "ipc/ipc_channel.h" |
17 #include "ipc/ipc_platform_file.h" | 17 #include "ipc/ipc_platform_file.h" |
18 #include "native_client/src/trusted/desc/nacl_desc_custom.h" | 18 #include "native_client/src/trusted/desc/nacl_desc_custom.h" |
19 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 19 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h" |
| 20 #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h" |
20 #include "ppapi/proxy/ppapi_messages.h" | 21 #include "ppapi/proxy/ppapi_messages.h" |
21 #include "ppapi/proxy/serialized_handle.h" | 22 #include "ppapi/proxy/serialized_handle.h" |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 enum BufferSizeStatus { | 26 enum BufferSizeStatus { |
26 // The buffer contains a full message with no extra bytes. | 27 // The buffer contains a full message with no extra bytes. |
27 MESSAGE_IS_COMPLETE, | 28 MESSAGE_IS_COMPLETE, |
28 | 29 |
29 // The message doesn't fit and the buffer contains only some of it. | 30 // The message doesn't fit and the buffer contains only some of it. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 funcs.SendMsg = NaClDescCustomSendMsg; | 84 funcs.SendMsg = NaClDescCustomSendMsg; |
84 funcs.RecvMsg = NaClDescCustomRecvMsg; | 85 funcs.RecvMsg = NaClDescCustomRecvMsg; |
85 // NaClDescMakeCustomDesc gives us a reference on the returned NaClDesc. | 86 // NaClDescMakeCustomDesc gives us a reference on the returned NaClDesc. |
86 return NaClDescMakeCustomDesc(new DescThunker(adapter), &funcs); | 87 return NaClDescMakeCustomDesc(new DescThunker(adapter), &funcs); |
87 } | 88 } |
88 | 89 |
89 void DeleteChannel(IPC::Channel* channel) { | 90 void DeleteChannel(IPC::Channel* channel) { |
90 delete channel; | 91 delete channel; |
91 } | 92 } |
92 | 93 |
| 94 class NaClDescWrapper { |
| 95 public: |
| 96 explicit NaClDescWrapper(NaClDesc* desc): desc_(desc) {} |
| 97 ~NaClDescWrapper() { |
| 98 NaClDescUnref(desc_); |
| 99 } |
| 100 |
| 101 NaClDesc* desc() { return desc_; } |
| 102 |
| 103 private: |
| 104 NaClDesc* desc_; |
| 105 DISALLOW_COPY_AND_ASSIGN(NaClDescWrapper); |
| 106 }; |
| 107 |
93 } // namespace | 108 } // namespace |
94 | 109 |
95 class NaClIPCAdapter::RewrittenMessage | 110 class NaClIPCAdapter::RewrittenMessage |
96 : public base::RefCounted<RewrittenMessage> { | 111 : public base::RefCounted<RewrittenMessage> { |
97 public: | 112 public: |
98 RewrittenMessage(); | 113 RewrittenMessage(); |
99 | 114 |
100 bool is_consumed() const { return data_read_cursor_ == data_len_; } | 115 bool is_consumed() const { return data_read_cursor_ == data_len_; } |
101 | 116 |
102 void SetData(const NaClIPCAdapter::NaClMessageHeader& header, | 117 void SetData(const NaClIPCAdapter::NaClMessageHeader& header, |
103 const void* payload, size_t payload_length); | 118 const void* payload, size_t payload_length); |
104 | 119 |
105 int Read(NaClImcTypedMsgHdr* msg); | 120 int Read(NaClImcTypedMsgHdr* msg); |
106 | 121 |
107 void AddDescriptor(nacl::DescWrapper* desc) { descs_.push_back(desc); } | 122 void AddDescriptor(NaClDescWrapper* desc) { descs_.push_back(desc); } |
108 | 123 |
109 size_t desc_count() const { return descs_.size(); } | 124 size_t desc_count() const { return descs_.size(); } |
110 | 125 |
111 private: | 126 private: |
112 friend class base::RefCounted<RewrittenMessage>; | 127 friend class base::RefCounted<RewrittenMessage>; |
113 ~RewrittenMessage() {} | 128 ~RewrittenMessage() {} |
114 | 129 |
115 scoped_array<char> data_; | 130 scoped_array<char> data_; |
116 size_t data_len_; | 131 size_t data_len_; |
117 | 132 |
118 // Offset into data where the next read will happen. This will be equal to | 133 // Offset into data where the next read will happen. This will be equal to |
119 // data_len_ when all data has been consumed. | 134 // data_len_ when all data has been consumed. |
120 size_t data_read_cursor_; | 135 size_t data_read_cursor_; |
121 | 136 |
122 // Wrapped descriptors for transfer to untrusted code. | 137 // Wrapped descriptors for transfer to untrusted code. |
123 ScopedVector<nacl::DescWrapper> descs_; | 138 ScopedVector<NaClDescWrapper> descs_; |
124 }; | 139 }; |
125 | 140 |
126 NaClIPCAdapter::RewrittenMessage::RewrittenMessage() | 141 NaClIPCAdapter::RewrittenMessage::RewrittenMessage() |
127 : data_len_(0), | 142 : data_len_(0), |
128 data_read_cursor_(0) { | 143 data_read_cursor_(0) { |
129 } | 144 } |
130 | 145 |
131 void NaClIPCAdapter::RewrittenMessage::SetData( | 146 void NaClIPCAdapter::RewrittenMessage::SetData( |
132 const NaClIPCAdapter::NaClMessageHeader& header, | 147 const NaClIPCAdapter::NaClMessageHeader& header, |
133 const void* payload, | 148 const void* payload, |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; | 349 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; |
335 Handles handles; | 350 Handles handles; |
336 scoped_ptr<IPC::Message> new_msg_ptr; | 351 scoped_ptr<IPC::Message> new_msg_ptr; |
337 bool success = locked_data_.handle_converter_.ConvertNativeHandlesToPosix( | 352 bool success = locked_data_.handle_converter_.ConvertNativeHandlesToPosix( |
338 msg, &handles, &new_msg_ptr); | 353 msg, &handles, &new_msg_ptr); |
339 if (!success) | 354 if (!success) |
340 return false; | 355 return false; |
341 | 356 |
342 // Now add any descriptors we found to rewritten_msg. |handles| is usually | 357 // Now add any descriptors we found to rewritten_msg. |handles| is usually |
343 // empty, unless we read a message containing a FD or handle. | 358 // empty, unless we read a message containing a FD or handle. |
344 nacl::DescWrapperFactory factory; | |
345 for (Handles::const_iterator iter = handles.begin(); | 359 for (Handles::const_iterator iter = handles.begin(); |
346 iter != handles.end(); | 360 iter != handles.end(); |
347 ++iter) { | 361 ++iter) { |
348 scoped_ptr<nacl::DescWrapper> nacl_desc; | 362 scoped_ptr<NaClDescWrapper> nacl_desc; |
349 switch (iter->type()) { | 363 switch (iter->type()) { |
350 case ppapi::proxy::SerializedHandle::SHARED_MEMORY: { | 364 case ppapi::proxy::SerializedHandle::SHARED_MEMORY: { |
351 const base::SharedMemoryHandle& shm_handle = iter->shmem(); | 365 const base::SharedMemoryHandle& shm_handle = iter->shmem(); |
352 uint32_t size = iter->size(); | 366 uint32_t size = iter->size(); |
353 nacl_desc.reset(factory.ImportShmHandle( | 367 nacl_desc.reset(new NaClDescWrapper(NaClDescImcShmMake( |
354 #if defined(OS_WIN) | 368 #if defined(OS_WIN) |
355 reinterpret_cast<const NaClHandle>(shm_handle), | 369 reinterpret_cast<const NaClHandle>(shm_handle), |
356 #else | 370 #else |
357 shm_handle.fd, | 371 shm_handle.fd, |
358 #endif | 372 #endif |
359 static_cast<size_t>(size))); | 373 static_cast<size_t>(size)))); |
360 break; | 374 break; |
361 } | 375 } |
362 case ppapi::proxy::SerializedHandle::SOCKET: { | 376 case ppapi::proxy::SerializedHandle::SOCKET: { |
363 nacl_desc.reset(factory.ImportSyncSocketHandle( | 377 nacl_desc.reset(new NaClDescWrapper(NaClDescSyncSocketMake( |
364 #if defined(OS_WIN) | 378 #if defined(OS_WIN) |
365 reinterpret_cast<const NaClHandle>(iter->descriptor()) | 379 reinterpret_cast<const NaClHandle>(iter->descriptor()) |
366 #else | 380 #else |
367 iter->descriptor().fd | 381 iter->descriptor().fd |
368 #endif | 382 #endif |
369 )); | 383 ))); |
370 break; | 384 break; |
371 } | 385 } |
372 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: { | 386 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: { |
373 // Check that this came from a PpapiMsg_CreateNaClChannel message. | 387 // Check that this came from a PpapiMsg_CreateNaClChannel message. |
374 // This code here is only appropriate for that message. | 388 // This code here is only appropriate for that message. |
375 DCHECK(msg.type() == PpapiMsg_CreateNaClChannel::ID); | 389 DCHECK(msg.type() == PpapiMsg_CreateNaClChannel::ID); |
376 IPC::ChannelHandle channel_handle = | 390 IPC::ChannelHandle channel_handle = |
377 IPC::Channel::GenerateVerifiedChannelID("nacl"); | 391 IPC::Channel::GenerateVerifiedChannelID("nacl"); |
378 scoped_refptr<NaClIPCAdapter> ipc_adapter( | 392 scoped_refptr<NaClIPCAdapter> ipc_adapter( |
379 new NaClIPCAdapter(channel_handle, task_runner_)); | 393 new NaClIPCAdapter(channel_handle, task_runner_)); |
380 ipc_adapter->ConnectChannel(); | 394 ipc_adapter->ConnectChannel(); |
381 #if defined(OS_POSIX) | 395 #if defined(OS_POSIX) |
382 channel_handle.socket = base::FileDescriptor( | 396 channel_handle.socket = base::FileDescriptor( |
383 ipc_adapter->TakeClientFileDescriptor(), true); | 397 ipc_adapter->TakeClientFileDescriptor(), true); |
384 #endif | 398 #endif |
385 nacl_desc.reset(factory.MakeGeneric(ipc_adapter->MakeNaClDesc())); | 399 nacl_desc.reset(new NaClDescWrapper(ipc_adapter->MakeNaClDesc())); |
386 // Send back a message that the channel was created. | 400 // Send back a message that the channel was created. |
387 scoped_ptr<IPC::Message> response( | 401 scoped_ptr<IPC::Message> response( |
388 new PpapiHostMsg_ChannelCreated(channel_handle)); | 402 new PpapiHostMsg_ChannelCreated(channel_handle)); |
389 task_runner_->PostTask(FROM_HERE, | 403 task_runner_->PostTask(FROM_HERE, |
390 base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this, | 404 base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this, |
391 base::Passed(&response))); | 405 base::Passed(&response))); |
392 break; | 406 break; |
393 } | 407 } |
394 case ppapi::proxy::SerializedHandle::FILE: | 408 case ppapi::proxy::SerializedHandle::FILE: |
395 // TODO(raymes): Handle file handles for NaCl. | 409 // TODO(raymes): Handle file handles for NaCl. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 header.payload_size = static_cast<uint32>(msg.payload_size()); | 539 header.payload_size = static_cast<uint32>(msg.payload_size()); |
526 header.routing = msg.routing_id(); | 540 header.routing = msg.routing_id(); |
527 header.type = msg.type(); | 541 header.type = msg.type(); |
528 header.flags = msg.flags(); | 542 header.flags = msg.flags(); |
529 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); | 543 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); |
530 | 544 |
531 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); | 545 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); |
532 locked_data_.to_be_received_.push(rewritten_msg); | 546 locked_data_.to_be_received_.push(rewritten_msg); |
533 } | 547 } |
534 | 548 |
OLD | NEW |