OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/channel.h" | 5 #include "mojo/edk/system/channel.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <limits> | 11 #include <limits> |
12 #include <utility> | 12 #include <utility> |
13 | 13 |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/memory/aligned_memory.h" | 15 #include "base/memory/aligned_memory.h" |
16 #include "base/process/process_handle.h" | 16 #include "base/process/process_handle.h" |
17 #include "mojo/edk/embedder/platform_handle.h" | 17 #include "mojo/edk/embedder/platform_handle.h" |
18 | 18 |
19 #if defined(OS_MACOSX) && !defined(OS_IOS) | 19 #if defined(OS_MACOSX) && !defined(OS_IOS) |
20 #include "base/mac/mach_logging.h" | 20 #include "base/mac/mach_logging.h" |
| 21 #elif defined(OS_ANDROID) |
| 22 #include "base/rand_util.h" |
21 #elif defined(OS_WIN) | 23 #elif defined(OS_WIN) |
22 #include "base/win/win_util.h" | 24 #include "base/win/win_util.h" |
23 #endif | 25 #endif |
24 | 26 |
25 namespace mojo { | 27 namespace mojo { |
26 namespace edk { | 28 namespace edk { |
27 | 29 |
28 namespace { | 30 namespace { |
29 | 31 |
30 static_assert( | 32 static_assert( |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 extra_header_size = max_handles_ * sizeof(HandleEntry); | 76 extra_header_size = max_handles_ * sizeof(HandleEntry); |
75 #elif defined(OS_MACOSX) && !defined(OS_IOS) | 77 #elif defined(OS_MACOSX) && !defined(OS_IOS) |
76 // On OSX, some of the platform handles may be mach ports, which are | 78 // On OSX, some of the platform handles may be mach ports, which are |
77 // serialised into the message buffer. Since there could be a mix of fds and | 79 // serialised into the message buffer. Since there could be a mix of fds and |
78 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), | 80 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), |
79 // so that the original ordering of handles can be re-created. | 81 // so that the original ordering of handles can be re-created. |
80 if (max_handles) { | 82 if (max_handles) { |
81 extra_header_size = | 83 extra_header_size = |
82 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); | 84 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); |
83 } | 85 } |
| 86 #elif defined(OS_ANDROID) |
| 87 if (max_handles) { |
| 88 extra_header_size = |
| 89 sizeof(ParcelableExtraHeader) + (max_handles * sizeof(ParcelableEntry)); |
| 90 } |
84 #endif | 91 #endif |
85 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. | 92 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. |
86 if (!IsAlignedForChannelMessage(extra_header_size)) { | 93 if (!IsAlignedForChannelMessage(extra_header_size)) { |
87 extra_header_size += kChannelMessageAlignment - | 94 extra_header_size += kChannelMessageAlignment - |
88 (extra_header_size % kChannelMessageAlignment); | 95 (extra_header_size % kChannelMessageAlignment); |
89 } | 96 } |
90 DCHECK(IsAlignedForChannelMessage(extra_header_size)); | 97 DCHECK(IsAlignedForChannelMessage(extra_header_size)); |
91 const size_t header_size = | 98 const size_t header_size = |
92 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header); | 99 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header); |
93 DCHECK(extra_header_size == 0 || !is_legacy_message); | 100 DCHECK(extra_header_size == 0 || !is_legacy_message); |
(...skipping 30 matching lines...) Expand all Loading... |
124 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); | 131 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); |
125 #elif defined(OS_MACOSX) && !defined(OS_IOS) | 132 #elif defined(OS_MACOSX) && !defined(OS_IOS) |
126 mach_ports_header_ = | 133 mach_ports_header_ = |
127 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); | 134 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); |
128 mach_ports_header_->num_ports = 0; | 135 mach_ports_header_->num_ports = 0; |
129 // Initialize all handles to invalid values. | 136 // Initialize all handles to invalid values. |
130 for (size_t i = 0; i < max_handles_; ++i) { | 137 for (size_t i = 0; i < max_handles_; ++i) { |
131 mach_ports_header_->entries[i] = | 138 mach_ports_header_->entries[i] = |
132 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | 139 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
133 } | 140 } |
| 141 #elif defined(OS_ANDROID) |
| 142 parcelable_header_ = |
| 143 reinterpret_cast<ParcelableExtraHeader*>(mutable_extra_header()); |
| 144 parcelable_header_->num_parcelables = 0; |
| 145 memset(parcelable_header_->entries, 0, |
| 146 sizeof(ParcelableEntry) * max_handles_); |
134 #endif | 147 #endif |
135 } | 148 } |
136 } | 149 } |
137 | 150 |
138 Channel::Message::~Message() { | 151 Channel::Message::~Message() { |
139 base::AlignedFree(data_); | 152 base::AlignedFree(data_); |
140 } | 153 } |
141 | 154 |
142 // static | 155 // static |
143 Channel::MessagePtr Channel::Message::Deserialize(const void* data, | 156 Channel::MessagePtr Channel::Message::Deserialize(const void* data, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 extra_header_size < sizeof(MachPortsExtraHeader)) { | 195 extra_header_size < sizeof(MachPortsExtraHeader)) { |
183 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " | 196 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " |
184 << sizeof(MachPortsExtraHeader); | 197 << sizeof(MachPortsExtraHeader); |
185 return nullptr; | 198 return nullptr; |
186 } | 199 } |
187 uint32_t max_handles = | 200 uint32_t max_handles = |
188 extra_header_size == 0 | 201 extra_header_size == 0 |
189 ? 0 | 202 ? 0 |
190 : (extra_header_size - sizeof(MachPortsExtraHeader)) / | 203 : (extra_header_size - sizeof(MachPortsExtraHeader)) / |
191 sizeof(MachPortsEntry); | 204 sizeof(MachPortsEntry); |
| 205 #elif defined(OS_ANDROID) |
| 206 if (extra_header_size < sizeof(ParcelableExtraHeader)) { |
| 207 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " |
| 208 << sizeof(ParcelableExtraHeader); |
| 209 return nullptr; |
| 210 } |
| 211 uint32_t max_handles = (extra_header_size - sizeof(ParcelableExtraHeader)) / |
| 212 sizeof(ParcelableEntry); |
192 #else | 213 #else |
193 const uint32_t max_handles = 0; | 214 const uint32_t max_handles = 0; |
194 #endif // defined(OS_WIN) | 215 #endif // defined(OS_WIN) |
195 | 216 |
196 const uint16_t num_handles = | 217 const uint16_t num_handles = |
197 header ? header->num_handles : legacy_header->num_handles; | 218 header ? header->num_handles : legacy_header->num_handles; |
198 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) { | 219 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) { |
199 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > " | 220 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > " |
200 << max_handles; | 221 << max_handles; |
201 return nullptr; | 222 return nullptr; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 } | 340 } |
320 | 341 |
321 if (max_handles_ == 0) { | 342 if (max_handles_ == 0) { |
322 CHECK(!new_handles || new_handles->size() == 0); | 343 CHECK(!new_handles || new_handles->size() == 0); |
323 return; | 344 return; |
324 } | 345 } |
325 | 346 |
326 CHECK(new_handles && new_handles->size() <= max_handles_); | 347 CHECK(new_handles && new_handles->size() <= max_handles_); |
327 header()->num_handles = static_cast<uint16_t>(new_handles->size()); | 348 header()->num_handles = static_cast<uint16_t>(new_handles->size()); |
328 std::swap(handle_vector_, new_handles); | 349 std::swap(handle_vector_, new_handles); |
| 350 |
329 #if defined(OS_WIN) | 351 #if defined(OS_WIN) |
330 memset(handles_, 0, extra_header_size()); | 352 memset(handles_, 0, extra_header_size()); |
331 for (size_t i = 0; i < handle_vector_->size(); i++) | 353 for (size_t i = 0; i < handle_vector_->size(); i++) |
332 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); | 354 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); |
333 #endif // defined(OS_WIN) | 355 #endif // defined(OS_WIN) |
334 | 356 |
335 #if defined(OS_MACOSX) && !defined(OS_IOS) | 357 #if defined(OS_MACOSX) && !defined(OS_IOS) |
336 size_t mach_port_index = 0; | 358 size_t mach_port_index = 0; |
337 if (mach_ports_header_) { | 359 if (mach_ports_header_) { |
338 for (size_t i = 0; i < max_handles_; ++i) { | 360 for (size_t i = 0; i < max_handles_; ++i) { |
339 mach_ports_header_->entries[i] = | 361 mach_ports_header_->entries[i] = |
340 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | 362 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
341 } | 363 } |
342 for (size_t i = 0; i < handle_vector_->size(); i++) { | 364 for (size_t i = 0; i < handle_vector_->size(); i++) { |
343 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || | 365 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || |
344 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) { | 366 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) { |
345 mach_port_t port = (*handle_vector_)[i].port; | 367 mach_port_t port = (*handle_vector_)[i].port; |
346 mach_ports_header_->entries[mach_port_index].index = i; | 368 mach_ports_header_->entries[mach_port_index].index = i; |
347 mach_ports_header_->entries[mach_port_index].mach_port = port; | 369 mach_ports_header_->entries[mach_port_index].mach_port = port; |
348 mach_port_index++; | 370 mach_port_index++; |
349 } | 371 } |
350 } | 372 } |
351 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index); | 373 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index); |
352 } | 374 } |
353 #endif | 375 #endif |
| 376 |
| 377 #if defined(OS_ANDROID) |
| 378 size_t parcelable_index = 0; |
| 379 if (parcelable_header_) { |
| 380 memset(parcelable_header_->entries, 0, |
| 381 sizeof(ParcelableEntry) * max_handles_); |
| 382 for (size_t i = 0; i < handle_vector_->size(); i++) { |
| 383 if ((*handle_vector_)[i].type == PlatformHandle::Type::PARCELABLE) { |
| 384 // jobject parcelable = (*handle_vector_)[i].parcelable; |
| 385 // TODO: WHERE DOES THE PARCELABLE GO? |
| 386 parcelable_header_->entries[parcelable_index].index = i; |
| 387 parcelable_header_->entries[parcelable_index].id = i; |
| 388 parcelable_index++; |
| 389 } |
| 390 } |
| 391 parcelable_header_->num_parcelables = |
| 392 static_cast<uint16_t>(parcelable_index); |
| 393 } |
| 394 #endif |
354 } | 395 } |
355 | 396 |
356 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { | 397 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { |
357 #if defined(OS_MACOSX) && !defined(OS_IOS) | 398 #if defined(OS_MACOSX) && !defined(OS_IOS) |
358 if (mach_ports_header_) { | 399 if (mach_ports_header_) { |
359 for (size_t i = 0; i < max_handles_; ++i) { | 400 for (size_t i = 0; i < max_handles_; ++i) { |
360 mach_ports_header_->entries[i] = | 401 mach_ports_header_->entries[i] = |
361 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | 402 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
362 } | 403 } |
363 mach_ports_header_->num_ports = 0; | 404 mach_ports_header_->num_ports = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
382 it->type == PlatformHandle::Type::MACH_NAME) { | 423 it->type == PlatformHandle::Type::MACH_NAME) { |
383 // For Mach port names, we can can just leak them. They're not real | 424 // For Mach port names, we can can just leak them. They're not real |
384 // ports anyways. For real ports, they're leaked because this is a child | 425 // ports anyways. For real ports, they're leaked because this is a child |
385 // process and the remote process will take ownership. | 426 // process and the remote process will take ownership. |
386 it = handle_vector_->erase(it); | 427 it = handle_vector_->erase(it); |
387 } else { | 428 } else { |
388 ++it; | 429 ++it; |
389 } | 430 } |
390 } | 431 } |
391 } | 432 } |
| 433 #elif defined(OS_ANDROID) |
| 434 if (handle_vector_) { |
| 435 for (auto it = handle_vector_->begin(); it != handle_vector_->end();) { |
| 436 if (it->type == PlatformHandle::Type::PARCELABLE) { |
| 437 it = handle_vector_->erase(it); |
| 438 } else { |
| 439 ++it; |
| 440 } |
| 441 } |
| 442 } |
| 443 #endif |
392 return std::move(handle_vector_); | 444 return std::move(handle_vector_); |
393 #else | 445 } |
394 return std::move(handle_vector_); | 446 |
| 447 #if defined(OS_ANDROID) |
| 448 Channel::Message::IDAndParcelableVector |
| 449 Channel::Message::TakeParcelablesForTransport() { |
| 450 IDAndParcelableVector ids_and_parcelables; |
| 451 if (parcelable_header_) { |
| 452 memset(parcelable_header_->entries, 0, |
| 453 sizeof(ParcelableEntry) * max_handles_); |
| 454 size_t parcelable_index = 0; |
| 455 for (auto iter = handle_vector_->begin(); iter != handle_vector_->end(); |
| 456 ++iter) { |
| 457 if (iter->type == PlatformHandle::Type::PARCELABLE) { |
| 458 uint32_t parcelable_id = static_cast<uint32_t>(base::RandUint64()); |
| 459 parcelable_header_->entries[parcelable_index].index = parcelable_index; |
| 460 parcelable_header_->entries[parcelable_index].id = parcelable_id; |
| 461 parcelable_index++; |
| 462 ids_and_parcelables.push_back(std::make_pair( |
| 463 parcelable_id, |
| 464 base::android::ScopedJavaLocalRef<jobject>(iter->parcelable))); |
| 465 } |
| 466 } |
| 467 parcelable_header_->num_parcelables = |
| 468 static_cast<uint16_t>(parcelable_index); |
| 469 } |
| 470 |
| 471 return std::move(ids_and_parcelables); |
| 472 } |
395 #endif | 473 #endif |
396 } | |
397 | 474 |
398 #if defined(OS_WIN) | 475 #if defined(OS_WIN) |
399 // static | 476 // static |
400 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, | 477 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, |
401 base::ProcessHandle to_process, | 478 base::ProcessHandle to_process, |
402 PlatformHandleVector* handles) { | 479 PlatformHandleVector* handles) { |
403 bool success = true; | 480 bool success = true; |
404 for (size_t i = 0; i < handles->size(); ++i) { | 481 for (size_t i = 0; i < handles->size(); ++i) { |
405 if (!(*handles)[i].is_valid()) { | 482 if (!(*handles)[i].is_valid()) { |
406 DLOG(ERROR) << "Refusing to duplicate invalid handle."; | 483 DLOG(ERROR) << "Refusing to duplicate invalid handle."; |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 } | 710 } |
634 | 711 |
635 const uint16_t num_handles = | 712 const uint16_t num_handles = |
636 header ? header->num_handles : legacy_header->num_handles; | 713 header ? header->num_handles : legacy_header->num_handles; |
637 ScopedPlatformHandleVectorPtr handles; | 714 ScopedPlatformHandleVectorPtr handles; |
638 if (num_handles > 0) { | 715 if (num_handles > 0) { |
639 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size, | 716 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size, |
640 &handles)) { | 717 &handles)) { |
641 return false; | 718 return false; |
642 } | 719 } |
643 | |
644 if (!handles) { | 720 if (!handles) { |
645 // Not enough handles available for this message. | 721 // Not enough handles available for this message. |
646 break; | 722 break; |
647 } | 723 } |
648 } | 724 } |
649 | 725 |
650 // We've got a complete message! Dispatch it and try another. | 726 // We've got a complete message! Dispatch it and try another. |
651 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY && | 727 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY && |
652 legacy_header->message_type != Message::MessageType::NORMAL) { | 728 legacy_header->message_type != Message::MessageType::NORMAL) { |
653 if (!OnControlMessage(legacy_header->message_type, payload, payload_size, | 729 if (!OnControlMessage(legacy_header->message_type, payload, payload_size, |
654 std::move(handles))) { | 730 std::move(handles))) { |
655 return false; | 731 return false; |
656 } | 732 } |
657 did_dispatch_message = true; | 733 did_dispatch_message = true; |
658 } else if (delegate_) { | 734 } else if (delegate_) { |
| 735 ((handles) ? handles->size() : 0); |
659 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); | 736 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); |
660 did_dispatch_message = true; | 737 did_dispatch_message = true; |
661 } | 738 } |
662 | 739 |
663 read_buffer_->Discard(legacy_header->num_bytes); | 740 read_buffer_->Discard(legacy_header->num_bytes); |
664 } | 741 } |
665 | 742 |
666 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; | 743 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; |
667 return true; | 744 return true; |
668 } | 745 } |
669 | 746 |
670 void Channel::OnError() { | 747 void Channel::OnError() { |
671 if (delegate_) | 748 if (delegate_) |
672 delegate_->OnChannelError(); | 749 delegate_->OnChannelError(); |
673 } | 750 } |
674 | 751 |
675 bool Channel::OnControlMessage(Message::MessageType message_type, | 752 bool Channel::OnControlMessage(Message::MessageType message_type, |
676 const void* payload, | 753 const void* payload, |
677 size_t payload_size, | 754 size_t payload_size, |
678 ScopedPlatformHandleVectorPtr handles) { | 755 ScopedPlatformHandleVectorPtr handles) { |
679 return false; | 756 return false; |
680 } | 757 } |
681 | 758 |
682 } // namespace edk | 759 } // namespace edk |
683 } // namespace mojo | 760 } // namespace mojo |
OLD | NEW |