| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "mojo/edk/system/message_pipe_dispatcher.h" | 5 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "mojo/edk/embedder/embedder_internal.h" | 10 #include "mojo/edk/embedder/embedder_internal.h" |
| 11 #include "mojo/edk/embedder/platform_handle_utils.h" | 11 #include "mojo/edk/embedder/platform_handle_utils.h" |
| 12 #include "mojo/edk/embedder/platform_shared_buffer.h" | 12 #include "mojo/edk/embedder/platform_shared_buffer.h" |
| 13 #include "mojo/edk/embedder/platform_support.h" | 13 #include "mojo/edk/embedder/platform_support.h" |
| 14 #include "mojo/edk/system/configuration.h" | 14 #include "mojo/edk/system/configuration.h" |
| 15 #include "mojo/edk/system/message_in_transit.h" | 15 #include "mojo/edk/system/message_in_transit.h" |
| 16 #include "mojo/edk/system/options_validation.h" | 16 #include "mojo/edk/system/options_validation.h" |
| 17 #include "mojo/edk/system/transport_data.h" | 17 #include "mojo/edk/system/transport_data.h" |
| 18 | 18 |
| 19 #if defined(OS_WIN) |
| 20 #include "mojo/edk/system/token_serializer_win.h" |
| 21 #endif |
| 22 |
| 19 namespace mojo { | 23 namespace mojo { |
| 20 namespace edk { | 24 namespace edk { |
| 21 | 25 |
| 22 // TODO(jam): do more tests on using channel on same thread if it supports it ( | 26 // TODO(jam): do more tests on using channel on same thread if it supports it ( |
| 23 // i.e. with USE_CHROME_EDK and Windows). Also see ipc_channel_mojo.cc | 27 // i.e. with USE_CHROME_EDK and Windows). Also see ipc_channel_mojo.cc |
| 24 bool g_use_channel_on_io_thread_only = true; | 28 bool g_use_channel_on_io_thread_only = true; |
| 25 | 29 |
| 26 namespace { | 30 namespace { |
| 27 | 31 |
| 28 const size_t kInvalidMessagePipeHandleIndex = static_cast<size_t>(-1); | 32 const size_t kInvalidMessagePipeHandleIndex = static_cast<size_t>(-1); |
| 29 | 33 |
| 30 struct MOJO_ALIGNAS(8) SerializedMessagePipeHandleDispatcher { | 34 struct MOJO_ALIGNAS(8) SerializedMessagePipeHandleDispatcher { |
| 31 // Could be |kInvalidMessagePipeHandleIndex| if the other endpoint of the MP | 35 // Could be |kInvalidMessagePipeHandleIndex| if the other endpoint of the MP |
| 32 // was closed. | 36 // was closed. |
| 33 size_t platform_handle_index; | 37 size_t platform_handle_index; |
| 34 bool write_error; | 38 bool write_error; |
| 35 | 39 |
| 36 size_t shared_memory_handle_index; // (Or |kInvalidMessagePipeHandleIndex|.) | 40 size_t shared_memory_handle_index; // (Or |kInvalidMessagePipeHandleIndex|.) |
| 37 uint32_t shared_memory_size; | 41 uint32_t shared_memory_size; |
| 38 | 42 |
| 39 size_t serialized_read_buffer_size; | 43 size_t serialized_read_buffer_size; |
| 40 size_t serialized_write_buffer_size; | 44 size_t serialized_write_buffer_size; |
| 41 size_t serialized_messagage_queue_size; | 45 size_t serialized_message_queue_size; |
| 42 | 46 |
| 43 // These are the FDs required as part of serializing channel_ and | 47 // These are the FDs required as part of serializing channel_ and |
| 44 // message_queue_. This is only used on POSIX. | 48 // message_queue_. This is only used on POSIX. |
| 45 size_t serialized_fds_index; // (Or |kInvalidMessagePipeHandleIndex|.) | 49 size_t serialized_fds_index; // (Or |kInvalidMessagePipeHandleIndex|.) |
| 46 size_t serialized_read_fds_length; | 50 size_t serialized_read_fds_length; |
| 47 size_t serialized_write_fds_length; | 51 size_t serialized_write_fds_length; |
| 48 size_t serialized_message_fds_length; | 52 size_t serialized_message_fds_length; |
| 49 }; | 53 }; |
| 50 | 54 |
| 51 char* SerializeBuffer(char* start, std::vector<char>* buffer) { | 55 char* SerializeBuffer(char* start, std::vector<char>* buffer) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 if (channel_) { | 158 if (channel_) { |
| 155 channel_->Shutdown(); | 159 channel_->Shutdown(); |
| 156 channel_ = nullptr; | 160 channel_ = nullptr; |
| 157 } | 161 } |
| 158 } | 162 } |
| 159 | 163 |
| 160 Dispatcher::Type MessagePipeDispatcher::GetType() const { | 164 Dispatcher::Type MessagePipeDispatcher::GetType() const { |
| 161 return Type::MESSAGE_PIPE; | 165 return Type::MESSAGE_PIPE; |
| 162 } | 166 } |
| 163 | 167 |
| 168 #if defined(OS_WIN) |
| 164 // TODO(jam): this is copied from RawChannelWin till I figure out what's the | 169 // TODO(jam): this is copied from RawChannelWin till I figure out what's the |
| 165 // best way we want to share this. Need to also consider posix which does | 170 // best way we want to share this. |
| 166 // require access to the RawChannel. | |
| 167 // Since this is used for serialization of messages read/written to a MP that | 171 // Since this is used for serialization of messages read/written to a MP that |
| 168 // aren't consumed by Mojo primitives yet, there could be an unbounded number of | 172 // aren't consumed by Mojo primitives yet, there could be an unbounded number of |
| 169 // them when a MP is being sent. As a result, even for POSIX we will probably | 173 // them when a MP is being sent. As a result, even for POSIX we will probably |
| 170 // want to send the handles to the shell process and exchange them for tokens | 174 // want to send the handles to the shell process and exchange them for tokens |
| 171 // (since we can be sure that the shell will respond to our IPCs, compared to | 175 // (since we can be sure that the shell will respond to our IPCs, compared to |
| 172 // the other end where we're sending the MP to, which may not be reading...). | 176 // the other end where we're sending the MP to, which may not be reading...). |
| 173 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | 177 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( |
| 174 size_t num_platform_handles, | 178 size_t num_platform_handles, |
| 175 const void* platform_handle_table) { | 179 const void* platform_handle_table) { |
| 176 // TODO(jam): this code will have to be updated once it's used in a sandbox | |
| 177 // and the receiving process doesn't have duplicate permission for the | |
| 178 // receiver. Once there's a broker and we have a connection to it (possibly | |
| 179 // through ConnectionManager), then we can make a sync IPC to it here to get a | |
| 180 // token for this handle, and it will duplicate the handle to is process. Then | |
| 181 // we pass the token to the receiver, which will then make a sync call to the | |
| 182 // broker to get a duplicated handle. This will also allow us to avoid leaks | |
| 183 // of the handle if the receiver dies, since the broker can notice that. | |
| 184 DCHECK_GT(num_platform_handles, 0u); | |
| 185 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector()); | 180 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector()); |
| 181 rv->resize(num_platform_handles); |
| 186 | 182 |
| 187 #if defined(OS_WIN) | 183 const uint64_t* tokens = |
| 188 const char* serialization_data = | 184 static_cast<const uint64_t*>(platform_handle_table); |
| 189 static_cast<const char*>(platform_handle_table); | 185 internal::g_token_serializer->TokenToHandle( |
| 190 for (size_t i = 0; i < num_platform_handles; i++) { | 186 tokens, num_platform_handles, &rv->at(0)); |
| 191 DWORD pid = *reinterpret_cast<const DWORD*>(serialization_data); | |
| 192 serialization_data += sizeof(DWORD); | |
| 193 HANDLE source_handle = *reinterpret_cast<const HANDLE*>(serialization_data); | |
| 194 serialization_data += sizeof(HANDLE); | |
| 195 base::Process sender = | |
| 196 base::Process::OpenWithAccess(pid, PROCESS_DUP_HANDLE); | |
| 197 DCHECK(sender.IsValid()); | |
| 198 HANDLE target_handle = NULL; | |
| 199 BOOL dup_result = | |
| 200 DuplicateHandle(sender.Handle(), source_handle, | |
| 201 base::GetCurrentProcessHandle(), &target_handle, 0, | |
| 202 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); | |
| 203 DCHECK(dup_result); | |
| 204 rv->push_back(PlatformHandle(target_handle)); | |
| 205 } | |
| 206 #else | |
| 207 NOTREACHED() << "TODO(jam): implement"; | |
| 208 #endif | |
| 209 return rv.Pass(); | 187 return rv.Pass(); |
| 210 } | 188 } |
| 189 #endif |
| 211 | 190 |
| 212 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( | 191 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( |
| 213 const void* source, | 192 const void* source, |
| 214 size_t size, | 193 size_t size, |
| 215 PlatformHandleVector* platform_handles) { | 194 PlatformHandleVector* platform_handles) { |
| 216 if (size != sizeof(SerializedMessagePipeHandleDispatcher)) { | 195 if (size != sizeof(SerializedMessagePipeHandleDispatcher)) { |
| 217 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad size)"; | 196 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad size)"; |
| 218 return nullptr; | 197 return nullptr; |
| 219 } | 198 } |
| 220 | 199 |
| 221 const SerializedMessagePipeHandleDispatcher* serialization = | 200 const SerializedMessagePipeHandleDispatcher* serialization = |
| 222 static_cast<const SerializedMessagePipeHandleDispatcher*>(source); | 201 static_cast<const SerializedMessagePipeHandleDispatcher*>(source); |
| 223 if (serialization->shared_memory_size != | 202 if (serialization->shared_memory_size != |
| 224 (serialization->serialized_read_buffer_size + | 203 (serialization->serialized_read_buffer_size + |
| 225 serialization->serialized_write_buffer_size + | 204 serialization->serialized_write_buffer_size + |
| 226 serialization->serialized_messagage_queue_size)) { | 205 serialization->serialized_message_queue_size)) { |
| 227 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad struct)"; | 206 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad struct)"; |
| 228 return nullptr; | 207 return nullptr; |
| 229 } | 208 } |
| 230 | 209 |
| 231 ScopedPlatformHandle platform_handle, shared_memory_handle; | 210 ScopedPlatformHandle platform_handle, shared_memory_handle; |
| 232 if (!GetHandle(serialization->platform_handle_index, | 211 if (!GetHandle(serialization->platform_handle_index, |
| 233 platform_handles, &platform_handle) || | 212 platform_handles, &platform_handle) || |
| 234 !GetHandle(serialization->shared_memory_handle_index, | 213 !GetHandle(serialization->shared_memory_handle_index, |
| 235 platform_handles, &shared_memory_handle)) { | 214 platform_handles, &shared_memory_handle)) { |
| 236 return nullptr; | 215 return nullptr; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 253 serialized_read_buffer = buffer; | 232 serialized_read_buffer = buffer; |
| 254 serialized_read_buffer_size = serialization->serialized_read_buffer_size; | 233 serialized_read_buffer_size = serialization->serialized_read_buffer_size; |
| 255 buffer += serialized_read_buffer_size; | 234 buffer += serialized_read_buffer_size; |
| 256 } | 235 } |
| 257 if (serialization->serialized_write_buffer_size) { | 236 if (serialization->serialized_write_buffer_size) { |
| 258 serialized_write_buffer = buffer; | 237 serialized_write_buffer = buffer; |
| 259 serialized_write_buffer_size = | 238 serialized_write_buffer_size = |
| 260 serialization->serialized_write_buffer_size; | 239 serialization->serialized_write_buffer_size; |
| 261 buffer += serialized_write_buffer_size; | 240 buffer += serialized_write_buffer_size; |
| 262 } | 241 } |
| 263 if (serialization->serialized_messagage_queue_size) { | 242 if (serialization->serialized_message_queue_size) { |
| 264 message_queue_data = buffer; | 243 message_queue_data = buffer; |
| 265 message_queue_size = serialization->serialized_messagage_queue_size; | 244 message_queue_size = serialization->serialized_message_queue_size; |
| 266 buffer += message_queue_size; | 245 buffer += message_queue_size; |
| 267 } | 246 } |
| 268 } | 247 } |
| 269 | 248 |
| 270 scoped_refptr<MessagePipeDispatcher> rv( | 249 scoped_refptr<MessagePipeDispatcher> rv( |
| 271 Create(MessagePipeDispatcher::kDefaultCreateOptions)); | 250 Create(MessagePipeDispatcher::kDefaultCreateOptions)); |
| 272 rv->write_error_ = serialization->write_error; | 251 rv->write_error_ = serialization->write_error; |
| 273 | 252 |
| 274 std::vector<int> serialized_read_fds; | 253 std::vector<int> serialized_read_fds; |
| 275 std::vector<int> serialized_write_fds; | 254 std::vector<int> serialized_write_fds; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 static_cast<const char*>(message->main_buffer()), | 431 static_cast<const char*>(message->main_buffer()), |
| 453 static_cast<const char*>(message->main_buffer()) + main_buffer_size); | 432 static_cast<const char*>(message->main_buffer()) + main_buffer_size); |
| 454 | 433 |
| 455 // cont'd | 434 // cont'd |
| 456 if (transport_data_buffer_size != 0) { | 435 if (transport_data_buffer_size != 0) { |
| 457 // TODO(jam): copied from RawChannelWin::WriteNoLock( | 436 // TODO(jam): copied from RawChannelWin::WriteNoLock( |
| 458 PlatformHandleVector* all_platform_handles = | 437 PlatformHandleVector* all_platform_handles = |
| 459 message->transport_data()->platform_handles(); | 438 message->transport_data()->platform_handles(); |
| 460 if (all_platform_handles) { | 439 if (all_platform_handles) { |
| 461 #if defined(OS_WIN) | 440 #if defined(OS_WIN) |
| 462 char* serialization_data = | 441 uint64_t* tokens = reinterpret_cast<uint64_t*>( |
| 463 static_cast<char*>(message->transport_data()->buffer()) + | 442 static_cast<char*>(message->transport_data()->buffer()) + |
| 464 message->transport_data()->platform_handle_table_offset(); | 443 message->transport_data()->platform_handle_table_offset()); |
| 465 DWORD current_process_id = base::GetCurrentProcId(); | 444 internal::g_token_serializer->HandleToToken( |
| 466 for (size_t i = 0; i < all_platform_handles->size(); i++) { | 445 &all_platform_handles->at(0), all_platform_handles->size(), tokens); |
| 467 *reinterpret_cast<DWORD*>(serialization_data) = current_process_id; | 446 for (size_t i = 0; i < all_platform_handles->size(); i++) |
| 468 serialization_data += sizeof(DWORD); | |
| 469 *reinterpret_cast<HANDLE*>(serialization_data) = | |
| 470 all_platform_handles->at(i).handle; | |
| 471 serialization_data += sizeof(HANDLE); | |
| 472 all_platform_handles->at(i) = PlatformHandle(); | 447 all_platform_handles->at(i) = PlatformHandle(); |
| 473 } | |
| 474 #else | 448 #else |
| 475 for (size_t i = 0; i < all_platform_handles->size(); i++) { | 449 for (size_t i = 0; i < all_platform_handles->size(); i++) { |
| 476 serialized_fds_.push_back(all_platform_handles->at(i).fd); | 450 serialized_fds_.push_back(all_platform_handles->at(i).fd); |
| 477 serialized_message_fds_length_++; | 451 serialized_message_fds_length_++; |
| 478 all_platform_handles->at(i) = PlatformHandle(); | 452 all_platform_handles->at(i) = PlatformHandle(); |
| 479 } | 453 } |
| 480 #endif | 454 #endif |
| 481 | 455 |
| 482 serialized_message_queue_.insert( | 456 serialized_message_queue_.insert( |
| 483 serialized_message_queue_.end(), | 457 serialized_message_queue_.end(), |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 if (serialized_platform_handle_.is_valid()) { | 667 if (serialized_platform_handle_.is_valid()) { |
| 694 serialization->platform_handle_index = platform_handles->size(); | 668 serialization->platform_handle_index = platform_handles->size(); |
| 695 platform_handles->push_back(serialized_platform_handle_.release()); | 669 platform_handles->push_back(serialized_platform_handle_.release()); |
| 696 } else { | 670 } else { |
| 697 serialization->platform_handle_index = kInvalidMessagePipeHandleIndex; | 671 serialization->platform_handle_index = kInvalidMessagePipeHandleIndex; |
| 698 } | 672 } |
| 699 | 673 |
| 700 serialization->write_error = write_error_; | 674 serialization->write_error = write_error_; |
| 701 serialization->serialized_read_buffer_size = serialized_read_buffer_.size(); | 675 serialization->serialized_read_buffer_size = serialized_read_buffer_.size(); |
| 702 serialization->serialized_write_buffer_size = serialized_write_buffer_.size(); | 676 serialization->serialized_write_buffer_size = serialized_write_buffer_.size(); |
| 703 serialization->serialized_messagage_queue_size = | 677 serialization->serialized_message_queue_size = |
| 704 serialized_message_queue_.size(); | 678 serialized_message_queue_.size(); |
| 705 | 679 |
| 706 serialization->shared_memory_size = static_cast<uint32_t>( | 680 serialization->shared_memory_size = static_cast<uint32_t>( |
| 707 serialization->serialized_read_buffer_size + | 681 serialization->serialized_read_buffer_size + |
| 708 serialization->serialized_write_buffer_size + | 682 serialization->serialized_write_buffer_size + |
| 709 serialization->serialized_messagage_queue_size); | 683 serialization->serialized_message_queue_size); |
| 710 if (serialization->shared_memory_size) { | 684 if (serialization->shared_memory_size) { |
| 711 scoped_refptr<PlatformSharedBuffer> shared_buffer( | 685 scoped_refptr<PlatformSharedBuffer> shared_buffer( |
| 712 internal::g_platform_support->CreateSharedBuffer( | 686 internal::g_platform_support->CreateSharedBuffer( |
| 713 serialization->shared_memory_size)); | 687 serialization->shared_memory_size)); |
| 714 scoped_ptr<PlatformSharedBufferMapping> mapping( | 688 scoped_ptr<PlatformSharedBufferMapping> mapping( |
| 715 shared_buffer->Map(0, serialization->shared_memory_size)); | 689 shared_buffer->Map(0, serialization->shared_memory_size)); |
| 716 char* start = static_cast<char*>(mapping->GetBase()); | 690 char* start = static_cast<char*>(mapping->GetBase()); |
| 717 start = SerializeBuffer(start, &serialized_read_buffer_); | 691 start = SerializeBuffer(start, &serialized_read_buffer_); |
| 718 start = SerializeBuffer(start, &serialized_write_buffer_); | 692 start = SerializeBuffer(start, &serialized_write_buffer_); |
| 719 start = SerializeBuffer(start, &serialized_message_queue_); | 693 start = SerializeBuffer(start, &serialized_message_queue_); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 LOG(WARNING) << "Enqueueing null dispatcher"; | 855 LOG(WARNING) << "Enqueueing null dispatcher"; |
| 882 dispatchers->push_back(nullptr); | 856 dispatchers->push_back(nullptr); |
| 883 } | 857 } |
| 884 } | 858 } |
| 885 message->SetDispatchers(dispatchers.Pass()); | 859 message->SetDispatchers(dispatchers.Pass()); |
| 886 return MOJO_RESULT_OK; | 860 return MOJO_RESULT_OK; |
| 887 } | 861 } |
| 888 | 862 |
| 889 } // namespace edk | 863 } // namespace edk |
| 890 } // namespace mojo | 864 } // namespace mojo |
| OLD | NEW |