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" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 funcs.SendMsg = NaClDescCustomSendMsg; | 82 funcs.SendMsg = NaClDescCustomSendMsg; |
83 funcs.RecvMsg = NaClDescCustomRecvMsg; | 83 funcs.RecvMsg = NaClDescCustomRecvMsg; |
84 // NaClDescMakeCustomDesc gives us a reference on the returned NaClDesc. | 84 // NaClDescMakeCustomDesc gives us a reference on the returned NaClDesc. |
85 return NaClDescMakeCustomDesc(new DescThunker(adapter), &funcs); | 85 return NaClDescMakeCustomDesc(new DescThunker(adapter), &funcs); |
86 } | 86 } |
87 | 87 |
88 void DeleteChannel(IPC::Channel* channel) { | 88 void DeleteChannel(IPC::Channel* channel) { |
89 delete channel; | 89 delete channel; |
90 } | 90 } |
91 | 91 |
92 void WriteFileDescriptor(int handle_index, | 92 void WriteHandle(int handle_index, |
93 const ppapi::proxy::SerializedHandle& handle, | 93 const ppapi::proxy::SerializedHandle& handle, |
94 IPC::Message* message) { | 94 IPC::Message* message) { |
95 ppapi::proxy::SerializedHandle::WriteHeader(handle.header(), message); | 95 ppapi::proxy::SerializedHandle::WriteHeader(handle.header(), message); |
96 | 96 |
97 // Now write the handle itself in POSIX style. | 97 // Now write the handle itself in POSIX style. |
98 message->WriteBool(true); // valid == true | 98 message->WriteBool(true); // valid == true |
99 message->WriteInt(handle_index); | 99 message->WriteInt(handle_index); |
100 } | 100 } |
101 | 101 |
102 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; | 102 typedef std::vector<ppapi::proxy::SerializedHandle> Handles; |
103 | 103 |
104 // We define one overload for catching SerializedHandles, so that we can share | 104 // We define one overload for catching SerializedHandles, so that we can share |
105 // them correctly to the untrusted side, and another for handling all other | 105 // them correctly to the untrusted side, and another for handling all other |
106 // parameters. See ConvertHandlesImpl for how these get used. | 106 // parameters. See ConvertHandlesImpl for how these get used. |
107 void ConvertHandle(const ppapi::proxy::SerializedHandle& handle, | 107 void ConvertHandle(const ppapi::proxy::SerializedHandle& handle, |
108 Handles* handles, IPC::Message* msg, int* handle_index) { | 108 Handles* handles, IPC::Message* msg, int* handle_index) { |
109 handles->push_back(handle); | 109 handles->push_back(handle); |
110 if (msg) | 110 if (msg) |
111 WriteFileDescriptor((*handle_index)++, handle, msg); | 111 WriteHandle((*handle_index)++, handle, msg); |
112 } | 112 } |
113 | 113 |
114 // This overload is to catch all types other than SerializedHandle. On Windows, | 114 // This overload is to catch all types other than SerializedHandle. On Windows, |
115 // |msg| will be a valid pointer, and we must write |param| to it | 115 // |msg| will be a valid pointer, and we must write |param| to it |
116 template <class T> | 116 template <class T> |
117 void ConvertHandle(const T& param, Handles* /* handles */, IPC::Message* msg, | 117 void ConvertHandle(const T& param, Handles* /* handles */, IPC::Message* msg, |
118 int* /* handle_index */) { | 118 int* /* handle_index */) { |
119 // It's not a handle, so just write to the output message, if necessary. | 119 // It's not a handle, so just write to the output message, if necessary. |
120 if (msg) | 120 if (msg) |
121 IPC::WriteParam(msg, param); | 121 IPC::WriteParam(msg, param); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 } | 427 } |
428 #define CASE_FOR_REPLY(MESSAGE_TYPE) \ | 428 #define CASE_FOR_REPLY(MESSAGE_TYPE) \ |
429 case MESSAGE_TYPE::ID: { \ | 429 case MESSAGE_TYPE::ID: { \ |
430 HandleConverter<MESSAGE_TYPE> extractor(&msg); \ | 430 HandleConverter<MESSAGE_TYPE> extractor(&msg); \ |
431 if (!extractor.ConvertReply( \ | 431 if (!extractor.ConvertReply( \ |
432 &handles, \ | 432 &handles, \ |
433 static_cast<IPC::SyncMessage*>(new_msg_ptr))) \ | 433 static_cast<IPC::SyncMessage*>(new_msg_ptr))) \ |
434 return false; \ | 434 return false; \ |
435 break; \ | 435 break; \ |
436 } | 436 } |
| 437 |
437 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { | 438 bool NaClIPCAdapter::OnMessageReceived(const IPC::Message& msg) { |
438 { | 439 { |
439 base::AutoLock lock(lock_); | 440 base::AutoLock lock(lock_); |
440 | 441 |
441 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); | 442 scoped_refptr<RewrittenMessage> rewritten_msg(new RewrittenMessage); |
442 | 443 |
443 // Pointer to the "new" message we will rewrite on Windows. On posix, this | 444 // Pointer to the "new" message we will rewrite on Windows. On posix, this |
444 // isn't necessary, so it will stay NULL. | 445 // isn't necessary, so it will stay NULL. |
445 IPC::Message* new_msg_ptr = NULL; | 446 IPC::Message* new_msg_ptr = NULL; |
| 447 IPC::Message new_msg(msg.routing_id(), msg.type(), msg.priority()); |
446 #if defined(OS_WIN) | 448 #if defined(OS_WIN) |
447 IPC::Message new_msg(msg.routing_id(), msg.type(), msg.priority()); | |
448 new_msg_ptr = &new_msg; | 449 new_msg_ptr = &new_msg; |
| 450 #else |
| 451 // Even on POSIX, we have to rewrite messages to create channels, because |
| 452 // these contain a handle with an invalid (place holder) descriptor. The |
| 453 // message sending code sees this and doesn't pass the descriptor over |
| 454 // correctly. |
| 455 if (msg.type() == PpapiMsg_CreateNaClChannel::ID) |
| 456 new_msg_ptr = &new_msg; |
449 #endif | 457 #endif |
| 458 |
450 Handles handles; | 459 Handles handles; |
451 switch (msg.type()) { | 460 switch (msg.type()) { |
| 461 CASE_FOR_MESSAGE(PpapiMsg_CreateNaClChannel) |
452 CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) | 462 CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) |
453 CASE_FOR_MESSAGE(PpapiMsg_PPBAudioInput_OpenACK) | 463 CASE_FOR_MESSAGE(PpapiMsg_PPBAudioInput_OpenACK) |
454 case IPC_REPLY_ID: { | 464 case IPC_REPLY_ID: { |
455 int id = IPC::SyncMessage::GetMessageId(msg); | 465 int id = IPC::SyncMessage::GetMessageId(msg); |
456 LockedData::PendingSyncMsgMap::iterator iter( | 466 LockedData::PendingSyncMsgMap::iterator iter( |
457 locked_data_.pending_sync_msgs_.find(id)); | 467 locked_data_.pending_sync_msgs_.find(id)); |
458 if (iter == locked_data_.pending_sync_msgs_.end()) { | 468 if (iter == locked_data_.pending_sync_msgs_.end()) { |
459 NOTREACHED(); | 469 NOTREACHED(); |
460 return false; | 470 return false; |
461 } | 471 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 break; | 505 break; |
496 } | 506 } |
497 case ppapi::proxy::SerializedHandle::SOCKET: { | 507 case ppapi::proxy::SerializedHandle::SOCKET: { |
498 nacl_desc.reset(factory.ImportSyncSocketHandle( | 508 nacl_desc.reset(factory.ImportSyncSocketHandle( |
499 #if defined(OS_WIN) | 509 #if defined(OS_WIN) |
500 reinterpret_cast<const NaClHandle>(iter->descriptor()) | 510 reinterpret_cast<const NaClHandle>(iter->descriptor()) |
501 #else | 511 #else |
502 iter->descriptor().fd | 512 iter->descriptor().fd |
503 #endif | 513 #endif |
504 )); | 514 )); |
| 515 break; |
| 516 } |
| 517 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: { |
| 518 // Check that this came from a PpapiMsg_CreateNaClChannel message. |
| 519 // This code here is only appropriate for that message. |
| 520 DCHECK(msg.type() == PpapiMsg_CreateNaClChannel::ID); |
| 521 IPC::ChannelHandle channel_handle = |
| 522 IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 523 scoped_refptr<NaClIPCAdapter> ipc_adapter( |
| 524 new NaClIPCAdapter(channel_handle, task_runner_)); |
| 525 #if defined(OS_POSIX) |
| 526 channel_handle.socket = base::FileDescriptor( |
| 527 ipc_adapter->TakeClientFileDescriptor(), true); |
| 528 #endif |
| 529 nacl_desc.reset(factory.MakeGeneric(ipc_adapter->MakeNaClDesc())); |
| 530 // Send back a message that the channel was created. |
| 531 scoped_ptr<IPC::Message> response( |
| 532 new PpapiHostMsg_ChannelCreated(channel_handle)); |
| 533 task_runner_->PostTask(FROM_HERE, |
| 534 base::Bind(&NaClIPCAdapter::SendMessageOnIOThread, this, |
| 535 base::Passed(&response))); |
| 536 break; |
505 } | 537 } |
506 case ppapi::proxy::SerializedHandle::INVALID: { | 538 case ppapi::proxy::SerializedHandle::INVALID: { |
507 // Nothing to do. TODO(dmichael): Should we log this? Or is it | 539 // Nothing to do. TODO(dmichael): Should we log this? Or is it |
508 // sometimes okay to pass an INVALID handle? | 540 // sometimes okay to pass an INVALID handle? |
| 541 break; |
509 } | 542 } |
510 // No default, so the compiler will warn us if new types get added. | 543 // No default, so the compiler will warn us if new types get added. |
511 } | 544 } |
512 if (nacl_desc.get()) | 545 if (nacl_desc.get()) |
513 rewritten_msg->AddDescriptor(nacl_desc.release()); | 546 rewritten_msg->AddDescriptor(nacl_desc.release()); |
514 } | 547 } |
515 if (new_msg_ptr && !handles.empty()) | 548 if (new_msg_ptr && !handles.empty()) |
516 SaveMessage(*new_msg_ptr, rewritten_msg.get()); | 549 SaveMessage(*new_msg_ptr, rewritten_msg.get()); |
517 else | 550 else |
518 SaveMessage(msg, rewritten_msg.get()); | 551 SaveMessage(msg, rewritten_msg.get()); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 header.payload_size = static_cast<uint32>(msg.payload_size()); | 668 header.payload_size = static_cast<uint32>(msg.payload_size()); |
636 header.routing = msg.routing_id(); | 669 header.routing = msg.routing_id(); |
637 header.type = msg.type(); | 670 header.type = msg.type(); |
638 header.flags = msg.flags(); | 671 header.flags = msg.flags(); |
639 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); | 672 header.num_fds = static_cast<int>(rewritten_msg->desc_count()); |
640 | 673 |
641 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); | 674 rewritten_msg->SetData(header, msg.payload(), msg.payload_size()); |
642 locked_data_.to_be_received_.push(rewritten_msg); | 675 locked_data_.to_be_received_.push(rewritten_msg); |
643 } | 676 } |
644 | 677 |
OLD | NEW |