| 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 <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #endif | 22 #endif |
| 23 | 23 |
| 24 namespace mojo { | 24 namespace mojo { |
| 25 namespace edk { | 25 namespace edk { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, | 29 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, |
| 30 "Invalid Header size."); | 30 "Invalid Header size."); |
| 31 | 31 |
| 32 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 32 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 33 static_assert(sizeof(Channel::Message::Header) == 8, | 33 static_assert(sizeof(Channel::Message::Header) == 8, |
| 34 "Header must be 8 bytes on ChromeOS and Android"); | 34 "Header must be 8 bytes on ChromeOS and Android"); |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 const size_t kReadBufferSize = 4096; | 39 const size_t kReadBufferSize = 4096; |
| 40 const size_t kMaxUnusedReadBufferCapacity = 64 * 1024; | 40 const size_t kMaxUnusedReadBufferCapacity = 64 * 1024; |
| 41 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024; | 41 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024; |
| 42 const size_t kMaxAttachedHandles = 128; | 42 const size_t kMaxAttachedHandles = 128; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 60 extra_header_size = | 60 extra_header_size = |
| 61 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); | 61 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); |
| 62 } | 62 } |
| 63 #endif | 63 #endif |
| 64 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. | 64 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. |
| 65 if (extra_header_size % kChannelMessageAlignment) { | 65 if (extra_header_size % kChannelMessageAlignment) { |
| 66 extra_header_size += kChannelMessageAlignment - | 66 extra_header_size += kChannelMessageAlignment - |
| 67 (extra_header_size % kChannelMessageAlignment); | 67 (extra_header_size % kChannelMessageAlignment); |
| 68 } | 68 } |
| 69 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); | 69 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); |
| 70 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 70 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 71 DCHECK_EQ(0u, extra_header_size); | 71 DCHECK_EQ(0u, extra_header_size); |
| 72 #endif | 72 #endif |
| 73 | 73 |
| 74 size_ = sizeof(Header) + extra_header_size + payload_size; | 74 size_ = sizeof(Header) + extra_header_size + payload_size; |
| 75 data_ = static_cast<char*>(base::AlignedAlloc(size_, | 75 data_ = static_cast<char*>(base::AlignedAlloc(size_, |
| 76 kChannelMessageAlignment)); | 76 kChannelMessageAlignment)); |
| 77 // Only zero out the header and not the payload. Since the payload is going to | 77 // Only zero out the header and not the payload. Since the payload is going to |
| 78 // be memcpy'd, zeroing the payload is unnecessary work and a significant | 78 // be memcpy'd, zeroing the payload is unnecessary work and a significant |
| 79 // performance issue when dealing with large messages. Any sanitizer errors | 79 // performance issue when dealing with large messages. Any sanitizer errors |
| 80 // complaining about an uninitialized read in the payload area should be | 80 // complaining about an uninitialized read in the payload area should be |
| 81 // treated as an error and fixed. | 81 // treated as an error and fixed. |
| 82 memset(data_, 0, sizeof(Header) + extra_header_size); | 82 memset(data_, 0, sizeof(Header) + extra_header_size); |
| 83 header_ = reinterpret_cast<Header*>(data_); | 83 header_ = reinterpret_cast<Header*>(data_); |
| 84 | 84 |
| 85 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); | 85 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); |
| 86 header_->num_bytes = static_cast<uint32_t>(size_); | 86 header_->num_bytes = static_cast<uint32_t>(size_); |
| 87 | 87 |
| 88 DCHECK_LE(sizeof(Header) + extra_header_size, | 88 DCHECK_LE(sizeof(Header) + extra_header_size, |
| 89 std::numeric_limits<uint16_t>::max()); | 89 std::numeric_limits<uint16_t>::max()); |
| 90 header_->message_type = message_type; | 90 header_->message_type = message_type; |
| 91 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 91 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 92 header_->num_handles = static_cast<uint16_t>(max_handles); | 92 header_->num_handles = static_cast<uint16_t>(max_handles); |
| 93 #else | 93 #else |
| 94 header_->num_header_bytes = | 94 header_->num_header_bytes = |
| 95 static_cast<uint16_t>(sizeof(Header) + extra_header_size); | 95 static_cast<uint16_t>(sizeof(Header) + extra_header_size); |
| 96 #endif | 96 #endif |
| 97 | 97 |
| 98 if (max_handles_ > 0) { | 98 if (max_handles_ > 0) { |
| 99 #if defined(OS_WIN) | 99 #if defined(OS_WIN) |
| 100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header()); | 100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header()); |
| 101 // Initialize all handles to invalid values. | 101 // Initialize all handles to invalid values. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 static_cast<uintptr_t>(message->handles_[i].handle)); | 185 static_cast<uintptr_t>(message->handles_[i].handle)); |
| 186 } | 186 } |
| 187 message->SetHandles(std::move(handles)); | 187 message->SetHandles(std::move(handles)); |
| 188 #endif | 188 #endif |
| 189 | 189 |
| 190 return message; | 190 return message; |
| 191 #endif | 191 #endif |
| 192 } | 192 } |
| 193 | 193 |
| 194 size_t Channel::Message::payload_size() const { | 194 size_t Channel::Message::payload_size() const { |
| 195 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 195 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 196 return header_->num_bytes - sizeof(Header); | 196 return header_->num_bytes - sizeof(Header); |
| 197 #else | 197 #else |
| 198 return size_ - header_->num_header_bytes; | 198 return size_ - header_->num_header_bytes; |
| 199 #endif | 199 #endif |
| 200 } | 200 } |
| 201 | 201 |
| 202 #if defined(OS_MACOSX) && !defined(OS_IOS) | 202 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 203 bool Channel::Message::has_mach_ports() const { | 203 bool Channel::Message::has_mach_ports() const { |
| 204 if (!has_handles()) | 204 if (!has_handles()) |
| 205 return false; | 205 return false; |
| 206 | 206 |
| 207 for (const auto& handle : (*handle_vector_)) { | 207 for (const auto& handle : (*handle_vector_)) { |
| 208 if (handle.type == PlatformHandle::Type::MACH || | 208 if (handle.type == PlatformHandle::Type::MACH || |
| 209 handle.type == PlatformHandle::Type::MACH_NAME) { | 209 handle.type == PlatformHandle::Type::MACH_NAME) { |
| 210 return true; | 210 return true; |
| 211 } | 211 } |
| 212 } | 212 } |
| 213 return false; | 213 return false; |
| 214 } | 214 } |
| 215 #endif | 215 #endif |
| 216 | 216 |
| 217 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { | 217 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { |
| 218 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 218 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 219 // Old semantics for ChromeOS and Android | 219 // Old semantics for ChromeOS and Android |
| 220 if (header_->num_handles == 0) { | 220 if (header_->num_handles == 0) { |
| 221 CHECK(!new_handles || new_handles->size() == 0); | 221 CHECK(!new_handles || new_handles->size() == 0); |
| 222 return; | 222 return; |
| 223 } | 223 } |
| 224 CHECK(new_handles && new_handles->size() == header_->num_handles); | 224 CHECK(new_handles && new_handles->size() == header_->num_handles); |
| 225 std::swap(handle_vector_, new_handles); | 225 std::swap(handle_vector_, new_handles); |
| 226 | 226 |
| 227 #else | 227 #else |
| 228 if (max_handles_ == 0) { | 228 if (max_handles_ == 0) { |
| 229 CHECK(!new_handles || new_handles->size() == 0); | 229 CHECK(!new_handles || new_handles->size() == 0); |
| 230 return; | 230 return; |
| 231 } | 231 } |
| 232 | 232 |
| 233 CHECK(new_handles && new_handles->size() <= max_handles_); | 233 CHECK(new_handles && new_handles->size() <= max_handles_); |
| 234 header_->num_handles = static_cast<uint16_t>(new_handles->size()); | 234 header_->num_handles = static_cast<uint16_t>(new_handles->size()); |
| 235 std::swap(handle_vector_, new_handles); | 235 std::swap(handle_vector_, new_handles); |
| 236 #if defined(OS_WIN) | 236 #if defined(OS_WIN) |
| 237 memset(handles_, 0, extra_header_size()); | 237 memset(handles_, 0, extra_header_size()); |
| 238 for (size_t i = 0; i < handle_vector_->size(); i++) | 238 for (size_t i = 0; i < handle_vector_->size(); i++) |
| 239 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); | 239 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); |
| 240 #endif // defined(OS_WIN) | 240 #endif // defined(OS_WIN) |
| 241 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) | 241 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 242 | 242 |
| 243 #if defined(OS_MACOSX) && !defined(OS_IOS) | 243 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 244 size_t mach_port_index = 0; | 244 size_t mach_port_index = 0; |
| 245 if (mach_ports_header_) { | 245 if (mach_ports_header_) { |
| 246 for (size_t i = 0; i < max_handles_; ++i) { | 246 for (size_t i = 0; i < max_handles_; ++i) { |
| 247 mach_ports_header_->entries[i] = | 247 mach_ports_header_->entries[i] = |
| 248 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; | 248 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; |
| 249 } | 249 } |
| 250 for (size_t i = 0; i < handle_vector_->size(); i++) { | 250 for (size_t i = 0; i < handle_vector_->size(); i++) { |
| 251 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || | 251 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 } | 499 } |
| 500 | 500 |
| 501 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { | 501 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { |
| 502 // Not enough data available to read the full message. Hint to the | 502 // Not enough data available to read the full message. Hint to the |
| 503 // implementation that it should try reading the full size of the message. | 503 // implementation that it should try reading the full size of the message. |
| 504 *next_read_size_hint = | 504 *next_read_size_hint = |
| 505 header->num_bytes - read_buffer_->num_occupied_bytes(); | 505 header->num_bytes - read_buffer_->num_occupied_bytes(); |
| 506 return true; | 506 return true; |
| 507 } | 507 } |
| 508 | 508 |
| 509 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | 509 #if defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 510 size_t extra_header_size = 0; | 510 size_t extra_header_size = 0; |
| 511 const void* extra_header = nullptr; | 511 const void* extra_header = nullptr; |
| 512 size_t payload_size = header->num_bytes - sizeof(Message::Header); | 512 size_t payload_size = header->num_bytes - sizeof(Message::Header); |
| 513 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) | 513 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) |
| 514 : nullptr; | 514 : nullptr; |
| 515 #else | 515 #else |
| 516 if (header->num_header_bytes < sizeof(Message::Header) || | 516 if (header->num_header_bytes < sizeof(Message::Header) || |
| 517 header->num_header_bytes > header->num_bytes) { | 517 header->num_header_bytes > header->num_bytes) { |
| 518 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes; | 518 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes; |
| 519 return false; | 519 return false; |
| 520 } | 520 } |
| 521 size_t extra_header_size = | 521 size_t extra_header_size = |
| 522 header->num_header_bytes - sizeof(Message::Header); | 522 header->num_header_bytes - sizeof(Message::Header); |
| 523 const void* extra_header = extra_header_size ? header + 1 : nullptr; | 523 const void* extra_header = extra_header_size ? header + 1 : nullptr; |
| 524 size_t payload_size = header->num_bytes - header->num_header_bytes; | 524 size_t payload_size = header->num_bytes - header->num_header_bytes; |
| 525 void* payload = | 525 void* payload = |
| 526 payload_size ? reinterpret_cast<Message::Header*>( | 526 payload_size ? reinterpret_cast<Message::Header*>( |
| 527 const_cast<char*>(read_buffer_->occupied_bytes()) + | 527 const_cast<char*>(read_buffer_->occupied_bytes()) + |
| 528 header->num_header_bytes) | 528 header->num_header_bytes) |
| 529 : nullptr; | 529 : nullptr; |
| 530 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) | 530 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL) |
| 531 | 531 |
| 532 ScopedPlatformHandleVectorPtr handles; | 532 ScopedPlatformHandleVectorPtr handles; |
| 533 if (header->num_handles > 0) { | 533 if (header->num_handles > 0) { |
| 534 if (!GetReadPlatformHandles(header->num_handles, extra_header, | 534 if (!GetReadPlatformHandles(header->num_handles, extra_header, |
| 535 extra_header_size, &handles)) { | 535 extra_header_size, &handles)) { |
| 536 return false; | 536 return false; |
| 537 } | 537 } |
| 538 | 538 |
| 539 if (!handles) { | 539 if (!handles) { |
| 540 // Not enough handles available for this message. | 540 // Not enough handles available for this message. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 568 | 568 |
| 569 bool Channel::OnControlMessage(Message::Header::MessageType message_type, | 569 bool Channel::OnControlMessage(Message::Header::MessageType message_type, |
| 570 const void* payload, | 570 const void* payload, |
| 571 size_t payload_size, | 571 size_t payload_size, |
| 572 ScopedPlatformHandleVectorPtr handles) { | 572 ScopedPlatformHandleVectorPtr handles) { |
| 573 return false; | 573 return false; |
| 574 } | 574 } |
| 575 | 575 |
| 576 } // namespace edk | 576 } // namespace edk |
| 577 } // namespace mojo | 577 } // namespace mojo |
| OLD | NEW |