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 |