| 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 |