Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: mojo/edk/system/channel.cc

Issue 1712143002: [mojo-edk] Add support for transferring mach ports. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <utility>
11 12
12 #include "base/macros.h" 13 #include "base/macros.h"
13 #include "base/memory/aligned_memory.h" 14 #include "base/memory/aligned_memory.h"
14 #include "mojo/edk/embedder/platform_handle.h" 15 #include "mojo/edk/embedder/platform_handle.h"
15 16
17 #if defined(OS_MACOSX) && !defined(OS_IOS)
18 #include "base/mac/mach_logging.h"
19 #endif
20
16 namespace mojo { 21 namespace mojo {
17 namespace edk { 22 namespace edk {
18 23
19 namespace { 24 namespace {
20 25
21 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 26 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
22 "Invalid Header size."); 27 "Invalid Header size.");
23 28
24 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 29 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
25 static_assert(sizeof(Channel::Message::Header) == 8, 30 static_assert(sizeof(Channel::Message::Header) == 8,
(...skipping 10 matching lines...) Expand all
36 Channel::Message::Message(size_t payload_size, 41 Channel::Message::Message(size_t payload_size,
37 size_t max_handles, 42 size_t max_handles,
38 Header::MessageType message_type) 43 Header::MessageType message_type)
39 : max_handles_(max_handles) { 44 : max_handles_(max_handles) {
40 DCHECK_LE(max_handles_, kMaxAttachedHandles); 45 DCHECK_LE(max_handles_, kMaxAttachedHandles);
41 46
42 size_t extra_header_size = 0; 47 size_t extra_header_size = 0;
43 #if defined(OS_WIN) 48 #if defined(OS_WIN)
44 // On Windows we serialize platform handles into the extra header space. 49 // On Windows we serialize platform handles into the extra header space.
45 extra_header_size = max_handles_ * sizeof(PlatformHandle); 50 extra_header_size = max_handles_ * sizeof(PlatformHandle);
51 #elif defined(OS_MACOSX) && !defined(OS_IOS)
52 // On OSX, some of the platform handles may be mach ports, which are
53 // serialised into the message buffer. Since there could be a mix of fds and
54 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
55 // so that the original ordering of handles can be re-created.
56 extra_header_size = max_handles * sizeof(MachPortsEntry);
46 #endif 57 #endif
47 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. 58 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
48 if (extra_header_size % kChannelMessageAlignment) { 59 if (extra_header_size % kChannelMessageAlignment) {
49 extra_header_size += kChannelMessageAlignment - 60 extra_header_size += kChannelMessageAlignment -
50 (extra_header_size % kChannelMessageAlignment); 61 (extra_header_size % kChannelMessageAlignment);
51 } 62 }
52 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); 63 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment);
53 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 64 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
54 DCHECK_EQ(0u, extra_header_size); 65 DCHECK_EQ(0u, extra_header_size);
55 #endif 66 #endif
(...skipping 15 matching lines...) Expand all
71 DCHECK_LE(sizeof(Header) + extra_header_size, 82 DCHECK_LE(sizeof(Header) + extra_header_size,
72 std::numeric_limits<uint16_t>::max()); 83 std::numeric_limits<uint16_t>::max());
73 header_->message_type = message_type; 84 header_->message_type = message_type;
74 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 85 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
75 header_->num_handles = static_cast<uint16_t>(max_handles); 86 header_->num_handles = static_cast<uint16_t>(max_handles);
76 #else 87 #else
77 header_->num_header_bytes = 88 header_->num_header_bytes =
78 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 89 static_cast<uint16_t>(sizeof(Header) + extra_header_size);
79 #endif 90 #endif
80 91
92 if (max_handles_ > 0) {
81 #if defined(OS_WIN) 93 #if defined(OS_WIN)
82 if (max_handles_ > 0) {
83 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); 94 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header());
84 // Initialize all handles to invalid values. 95 // Initialize all handles to invalid values.
85 for (size_t i = 0; i < max_handles_; ++i) 96 for (size_t i = 0; i < max_handles_; ++i)
86 handles()[i] = PlatformHandle(); 97 handles()[i] = PlatformHandle();
98 #elif defined(OS_MACOSX) && !defined(OS_IOS)
99 mach_ports_ = reinterpret_cast<MachPortsEntry*>(mutable_extra_header());
100 // Initialize all handles to invalid values.
101 for (size_t i = 0; i < max_handles_; ++i)
102 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
103 #endif
87 } 104 }
88 #endif
89 } 105 }
90 106
91 Channel::Message::~Message() { 107 Channel::Message::~Message() {
92 #if defined(OS_WIN) 108 #if defined(OS_WIN)
93 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us. 109 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us.
94 for (size_t i = 0; i < header_->num_handles; ++i) 110 for (size_t i = 0; i < header_->num_handles; ++i)
95 handles()[i].CloseIfNecessary(); 111 handles()[i].CloseIfNecessary();
96 #endif 112 #endif
97 base::AlignedFree(data_); 113 base::AlignedFree(data_);
98 } 114 }
99 115
100 // static 116 // static
101 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 117 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
102 size_t data_num_bytes) { 118 size_t data_num_bytes) {
103 #if !defined(OS_WIN) 119 #if !defined(OS_WIN) && !(defined(OS_MACOSX) && !defined(OS_IOS))
104 // We only serialize messages into other messages when performing message 120 // We only serialize messages into other messages when performing message
105 // relay on Windows. 121 // relay on Windows and OSX.
106 NOTREACHED(); 122 NOTREACHED();
107 return nullptr; 123 return nullptr;
108 #else 124 #else
109 if (data_num_bytes < sizeof(Header)) 125 if (data_num_bytes < sizeof(Header))
110 return nullptr; 126 return nullptr;
111 127
112 const Header* header = reinterpret_cast<const Header*>(data); 128 const Header* header = reinterpret_cast<const Header*>(data);
113 if (header->num_bytes != data_num_bytes) { 129 if (header->num_bytes != data_num_bytes) {
114 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 130 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes
115 << " != " << data_num_bytes; 131 << " != " << data_num_bytes;
116 return nullptr; 132 return nullptr;
117 } 133 }
118 134
119 if (header->num_bytes < header->num_header_bytes) { 135 if (header->num_bytes < header->num_header_bytes) {
120 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 136 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
121 << header->num_header_bytes; 137 << header->num_header_bytes;
122 return nullptr; 138 return nullptr;
123 } 139 }
124 140
125 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 141 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
142 #if defined(OS_WIN)
126 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); 143 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle);
144 #elif defined(OS_MACOSX) && !defined(OS_IOS)
145 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry);
146 #endif
127 if (header->num_handles > max_handles) { 147 if (header->num_handles > max_handles) {
128 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > " 148 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
129 << max_handles; 149 << " > " << max_handles;
130 return nullptr; 150 return nullptr;
131 } 151 }
132 152
133 MessagePtr message( 153 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes,
134 new Message(data_num_bytes - header->num_header_bytes, max_handles)); 154 max_handles));
135
136 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 155 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
137 DCHECK_EQ(message->extra_header_size(), extra_header_size); 156 DCHECK_EQ(message->extra_header_size(), extra_header_size);
138 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 157 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes);
139 158
140 // Copy all payload bytes. 159 // Copy all payload bytes.
141 memcpy(message->mutable_payload(), 160 memcpy(message->mutable_payload(),
142 static_cast<const char*>(data) + header->num_header_bytes, 161 static_cast<const char*>(data) + header->num_header_bytes,
143 data_num_bytes - header->num_header_bytes); 162 data_num_bytes - header->num_header_bytes);
144 // Copy extra header bytes. 163 // Copy extra header bytes.
145 memcpy(message->mutable_extra_header(), 164 memcpy(message->mutable_extra_header(),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 #endif // defined(OS_WIN) 196 #endif // defined(OS_WIN)
178 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) 197 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
179 } 198 }
180 199
181 #if defined(OS_MACOSX) && !defined(OS_IOS) 200 #if defined(OS_MACOSX) && !defined(OS_IOS)
182 bool Channel::Message::has_mach_ports() const { 201 bool Channel::Message::has_mach_ports() const {
183 if (!has_handles()) 202 if (!has_handles())
184 return false; 203 return false;
185 204
186 for (const auto& handle : (*handle_vector_)) { 205 for (const auto& handle : (*handle_vector_)) {
187 if (handle.type == PlatformHandle::Type::MACH) 206 if (handle.type == PlatformHandle::Type::MACH ||
207 handle.type == PlatformHandle::Type::MACH_NAME) {
188 return true; 208 return true;
209 }
189 } 210 }
190 return false; 211 return false;
191 } 212 }
192 #endif 213 #endif
193 214
194 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { 215 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
195 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 216 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
196 // Old semantics for ChromeOS and Android 217 // Old semantics for ChromeOS and Android
197 if (header_->num_handles == 0) { 218 if (header_->num_handles == 0) {
198 CHECK(!new_handles || new_handles->size() == 0); 219 CHECK(!new_handles || new_handles->size() == 0);
(...skipping 11 matching lines...) Expand all
210 CHECK(new_handles && new_handles->size() <= max_handles_); 231 CHECK(new_handles && new_handles->size() <= max_handles_);
211 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 232 header_->num_handles = static_cast<uint16_t>(new_handles->size());
212 #if defined(OS_WIN) 233 #if defined(OS_WIN)
213 memcpy(handles(), new_handles->data(), 234 memcpy(handles(), new_handles->data(),
214 sizeof(PlatformHandle) * new_handles->size()); 235 sizeof(PlatformHandle) * new_handles->size());
215 new_handles->clear(); 236 new_handles->clear();
216 #else 237 #else
217 std::swap(handle_vector_, new_handles); 238 std::swap(handle_vector_, new_handles);
218 #endif // defined(OS_WIN) 239 #endif // defined(OS_WIN)
219 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) 240 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
241
242 #if defined(OS_MACOSX) && !defined(OS_IOS)
243 size_t mach_port_index = 0;
244 for (size_t i = 0; i < max_handles_; ++i)
245 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
246 for (size_t i = 0; i < handle_vector_->size(); i++) {
247 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
248 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) {
249 mach_port_t port = (*handle_vector_)[i].port;
250 mach_ports_[mach_port_index].index = i;
251 mach_ports_[mach_port_index].mach_port = port;
252 mach_port_index++;
253 }
254 }
255 #endif
220 } 256 }
221 257
222 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 258 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
223 #if defined(OS_WIN) 259 #if defined(OS_WIN)
224 if (header_->num_handles == 0) 260 if (header_->num_handles == 0)
225 return ScopedPlatformHandleVectorPtr(); 261 return ScopedPlatformHandleVectorPtr();
226 ScopedPlatformHandleVectorPtr moved_handles( 262 ScopedPlatformHandleVectorPtr moved_handles(
227 new PlatformHandleVector(header_->num_handles)); 263 new PlatformHandleVector(header_->num_handles));
228 for (size_t i = 0; i < header_->num_handles; ++i) 264 for (size_t i = 0; i < header_->num_handles; ++i)
229 std::swap(moved_handles->at(i), handles()[i]); 265 std::swap(moved_handles->at(i), handles()[i]);
266 header_->num_handles = 0;
230 return moved_handles; 267 return moved_handles;
268 #elif defined(OS_MACOSX) && !defined(OS_IOS)
269 for (size_t i = 0; i < max_handles_; ++i)
270 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
271 header_->num_handles = 0;
272 return std::move(handle_vector_);
273 #else
274 header_->num_handles = 0;
275 return std::move(handle_vector_);
276 #endif
277 }
278
279 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
280 #if defined(OS_WIN)
281 // Not necessary on Windows.
282 NOTREACHED();
283 return nullptr;
284 #elif defined(OS_MACOSX) && !defined(OS_IOS)
285 if (handle_vector_) {
286 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) {
287 if (it->type == PlatformHandle::Type::MACH ||
288 it->type == PlatformHandle::Type::MACH_NAME) {
289 // For Mach port names, we can can just leak them. They're not real
290 // ports anyways. For real ports, they're leaked because this is a child
291 // process and the remote process will take ownership.
292 it = handle_vector_->erase(it);
293 } else {
294 ++it;
295 }
296 }
297 }
298 return std::move(handle_vector_);
231 #else 299 #else
232 return std::move(handle_vector_); 300 return std::move(handle_vector_);
233 #endif 301 #endif
234 } 302 }
235 303
236 #if defined(OS_WIN) 304 #if defined(OS_WIN)
237 // static 305 // static
238 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, 306 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process,
239 base::ProcessHandle to_process, 307 base::ProcessHandle to_process,
240 PlatformHandle* handles, 308 PlatformHandle* handles,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 return true; 515 return true;
448 } 516 }
449 517
450 void Channel::OnError() { 518 void Channel::OnError() {
451 if (delegate_) 519 if (delegate_)
452 delegate_->OnChannelError(); 520 delegate_->OnChannelError();
453 } 521 }
454 522
455 } // namespace edk 523 } // namespace edk
456 } // namespace mojo 524 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698