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