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

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

Issue 2008953003: [mojo-edk] Explicitly serialise HANDLEs into messages instead of PlatformHandles. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cast2 Created 4 years, 6 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_win.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 #include <utility>
12 12
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h" 14 #include "base/memory/aligned_memory.h"
15 #include "base/process/process_handle.h" 15 #include "base/process/process_handle.h"
16 #include "mojo/edk/embedder/platform_handle.h" 16 #include "mojo/edk/embedder/platform_handle.h"
17 17
18 #if defined(OS_MACOSX) && !defined(OS_IOS) 18 #if defined(OS_MACOSX) && !defined(OS_IOS)
19 #include "base/mac/mach_logging.h" 19 #include "base/mac/mach_logging.h"
20 #elif defined(OS_WIN)
21 #include "base/win/win_util.h"
20 #endif 22 #endif
21 23
22 namespace mojo { 24 namespace mojo {
23 namespace edk { 25 namespace edk {
24 26
25 namespace { 27 namespace {
26 28
27 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 29 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
28 "Invalid Header size."); 30 "Invalid Header size.");
29 31
(...skipping 10 matching lines...) Expand all
40 const size_t kMaxAttachedHandles = 128; 42 const size_t kMaxAttachedHandles = 128;
41 43
42 Channel::Message::Message(size_t payload_size, 44 Channel::Message::Message(size_t payload_size,
43 size_t max_handles, 45 size_t max_handles,
44 Header::MessageType message_type) 46 Header::MessageType message_type)
45 : max_handles_(max_handles) { 47 : max_handles_(max_handles) {
46 DCHECK_LE(max_handles_, kMaxAttachedHandles); 48 DCHECK_LE(max_handles_, kMaxAttachedHandles);
47 49
48 size_t extra_header_size = 0; 50 size_t extra_header_size = 0;
49 #if defined(OS_WIN) 51 #if defined(OS_WIN)
50 // On Windows we serialize platform handles into the extra header space. 52 // On Windows we serialize HANDLEs into the extra header space.
51 extra_header_size = max_handles_ * sizeof(PlatformHandle); 53 extra_header_size = max_handles_ * sizeof(HandleEntry);
52 #elif defined(OS_MACOSX) && !defined(OS_IOS) 54 #elif defined(OS_MACOSX) && !defined(OS_IOS)
53 // On OSX, some of the platform handles may be mach ports, which are 55 // On OSX, some of the platform handles may be mach ports, which are
54 // serialised into the message buffer. Since there could be a mix of fds and 56 // serialised into the message buffer. Since there could be a mix of fds and
55 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), 57 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
56 // so that the original ordering of handles can be re-created. 58 // so that the original ordering of handles can be re-created.
57 if (max_handles) { 59 if (max_handles) {
58 extra_header_size = 60 extra_header_size =
59 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); 61 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
60 } 62 }
61 #endif 63 #endif
(...skipping 26 matching lines...) Expand all
88 header_->message_type = message_type; 90 header_->message_type = message_type;
89 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 91 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
90 header_->num_handles = static_cast<uint16_t>(max_handles); 92 header_->num_handles = static_cast<uint16_t>(max_handles);
91 #else 93 #else
92 header_->num_header_bytes = 94 header_->num_header_bytes =
93 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 95 static_cast<uint16_t>(sizeof(Header) + extra_header_size);
94 #endif 96 #endif
95 97
96 if (max_handles_ > 0) { 98 if (max_handles_ > 0) {
97 #if defined(OS_WIN) 99 #if defined(OS_WIN)
98 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); 100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header());
99 // Initialize all handles to invalid values. 101 // Initialize all handles to invalid values.
100 for (size_t i = 0; i < max_handles_; ++i) 102 for (size_t i = 0; i < max_handles_; ++i)
101 handles()[i] = PlatformHandle(); 103 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE);
102 #elif defined(OS_MACOSX) && !defined(OS_IOS) 104 #elif defined(OS_MACOSX) && !defined(OS_IOS)
103 mach_ports_header_ = 105 mach_ports_header_ =
104 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 106 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
105 mach_ports_header_->num_ports = 0; 107 mach_ports_header_->num_ports = 0;
106 // Initialize all handles to invalid values. 108 // Initialize all handles to invalid values.
107 for (size_t i = 0; i < max_handles_; ++i) { 109 for (size_t i = 0; i < max_handles_; ++i) {
108 mach_ports_header_->entries[i] = 110 mach_ports_header_->entries[i] =
109 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 111 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
110 } 112 }
111 #endif 113 #endif
112 } 114 }
113 } 115 }
114 116
115 Channel::Message::~Message() { 117 Channel::Message::~Message() {
116 #if defined(OS_WIN)
117 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us.
118 for (size_t i = 0; i < header_->num_handles; ++i)
119 handles()[i].CloseIfNecessary();
120 #endif
121 base::AlignedFree(data_); 118 base::AlignedFree(data_);
122 } 119 }
123 120
124 // static 121 // static
125 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 122 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
126 size_t data_num_bytes) { 123 size_t data_num_bytes) {
127 #if !defined(OS_WIN) && !(defined(OS_MACOSX) && !defined(OS_IOS)) 124 #if !defined(OS_WIN) && !(defined(OS_MACOSX) && !defined(OS_IOS))
128 // We only serialize messages into other messages when performing message 125 // We only serialize messages into other messages when performing message
129 // relay on Windows and OSX. 126 // relay on Windows and OSX.
130 NOTREACHED(); 127 NOTREACHED();
(...skipping 10 matching lines...) Expand all
141 } 138 }
142 139
143 if (header->num_bytes < header->num_header_bytes) { 140 if (header->num_bytes < header->num_header_bytes) {
144 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 141 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
145 << header->num_header_bytes; 142 << header->num_header_bytes;
146 return nullptr; 143 return nullptr;
147 } 144 }
148 145
149 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 146 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
150 #if defined(OS_WIN) 147 #if defined(OS_WIN)
151 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); 148 uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
152 #elif defined(OS_MACOSX) && !defined(OS_IOS) 149 #elif defined(OS_MACOSX) && !defined(OS_IOS)
153 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) / 150 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
154 sizeof(MachPortsEntry); 151 sizeof(MachPortsEntry);
155 #endif 152 #endif
156 if (header->num_handles > max_handles) { 153 if (header->num_handles > max_handles) {
157 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 154 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
158 << " > " << max_handles; 155 << " > " << max_handles;
159 return nullptr; 156 return nullptr;
160 } 157 }
161 158
(...skipping 11 matching lines...) Expand all
173 } 170 }
174 171
175 if (message->extra_header_size()) { 172 if (message->extra_header_size()) {
176 // Copy extra header bytes. 173 // Copy extra header bytes.
177 memcpy(message->mutable_extra_header(), 174 memcpy(message->mutable_extra_header(),
178 static_cast<const char*>(data) + sizeof(Header), 175 static_cast<const char*>(data) + sizeof(Header),
179 message->extra_header_size()); 176 message->extra_header_size());
180 } 177 }
181 178
182 message->header_->num_handles = header->num_handles; 179 message->header_->num_handles = header->num_handles;
180 #if defined(OS_WIN)
181 ScopedPlatformHandleVectorPtr handles(
182 new PlatformHandleVector(header->num_handles));
183 for (size_t i = 0; i < header->num_handles; i++) {
184 (*handles)[i].handle = reinterpret_cast<HANDLE>(
185 static_cast<uintptr_t>(message->handles_[i].handle));
186 }
187 message->SetHandles(std::move(handles));
188 #endif
183 189
184 return message; 190 return message;
185 #endif 191 #endif
186 } 192 }
187 193
188 size_t Channel::Message::payload_size() const { 194 size_t Channel::Message::payload_size() const {
189 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 195 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
190 return header_->num_bytes - sizeof(Header); 196 return header_->num_bytes - sizeof(Header);
191 #else 197 #else
192 return size_ - header_->num_header_bytes; 198 return size_ - header_->num_header_bytes;
193 #endif 199 #endif
194 } 200 }
195 201
196 PlatformHandle* Channel::Message::handles() {
197 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
198 // Old semantics for ChromeOS and Android.
199 if (header_->num_handles == 0)
200 return nullptr;
201 CHECK(handle_vector_);
202 return handle_vector_->data();
203 #else
204 if (max_handles_ == 0)
205 return nullptr;
206 #if defined(OS_WIN)
207 return handles_;
208 #else
209 CHECK(handle_vector_);
210 return handle_vector_->data();
211 #endif // defined(OS_WIN)
212 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
213 }
214
215 #if defined(OS_MACOSX) && !defined(OS_IOS) 202 #if defined(OS_MACOSX) && !defined(OS_IOS)
216 bool Channel::Message::has_mach_ports() const { 203 bool Channel::Message::has_mach_ports() const {
217 if (!has_handles()) 204 if (!has_handles())
218 return false; 205 return false;
219 206
220 for (const auto& handle : (*handle_vector_)) { 207 for (const auto& handle : (*handle_vector_)) {
221 if (handle.type == PlatformHandle::Type::MACH || 208 if (handle.type == PlatformHandle::Type::MACH ||
222 handle.type == PlatformHandle::Type::MACH_NAME) { 209 handle.type == PlatformHandle::Type::MACH_NAME) {
223 return true; 210 return true;
224 } 211 }
(...skipping 13 matching lines...) Expand all
238 std::swap(handle_vector_, new_handles); 225 std::swap(handle_vector_, new_handles);
239 226
240 #else 227 #else
241 if (max_handles_ == 0) { 228 if (max_handles_ == 0) {
242 CHECK(!new_handles || new_handles->size() == 0); 229 CHECK(!new_handles || new_handles->size() == 0);
243 return; 230 return;
244 } 231 }
245 232
246 CHECK(new_handles && new_handles->size() <= max_handles_); 233 CHECK(new_handles && new_handles->size() <= max_handles_);
247 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);
248 #if defined(OS_WIN) 236 #if defined(OS_WIN)
249 memcpy(handles(), new_handles->data(), 237 memset(handles_, 0, extra_header_size());
250 sizeof(PlatformHandle) * new_handles->size()); 238 for (size_t i = 0; i < handle_vector_->size(); i++)
251 new_handles->clear(); 239 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
252 #else
253 std::swap(handle_vector_, new_handles);
254 #endif // defined(OS_WIN) 240 #endif // defined(OS_WIN)
255 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) 241 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
256 242
257 #if defined(OS_MACOSX) && !defined(OS_IOS) 243 #if defined(OS_MACOSX) && !defined(OS_IOS)
258 size_t mach_port_index = 0; 244 size_t mach_port_index = 0;
259 if (mach_ports_header_) { 245 if (mach_ports_header_) {
260 for (size_t i = 0; i < max_handles_; ++i) { 246 for (size_t i = 0; i < max_handles_; ++i) {
261 mach_ports_header_->entries[i] = 247 mach_ports_header_->entries[i] =
262 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 248 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
263 } 249 }
264 for (size_t i = 0; i < handle_vector_->size(); i++) { 250 for (size_t i = 0; i < handle_vector_->size(); i++) {
265 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 251 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
266 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) { 252 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) {
267 mach_port_t port = (*handle_vector_)[i].port; 253 mach_port_t port = (*handle_vector_)[i].port;
268 mach_ports_header_->entries[mach_port_index].index = i; 254 mach_ports_header_->entries[mach_port_index].index = i;
269 mach_ports_header_->entries[mach_port_index].mach_port = port; 255 mach_ports_header_->entries[mach_port_index].mach_port = port;
270 mach_port_index++; 256 mach_port_index++;
271 } 257 }
272 } 258 }
273 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index); 259 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index);
274 } 260 }
275 #endif 261 #endif
276 } 262 }
277 263
278 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 264 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
279 #if defined(OS_WIN) 265 #if defined(OS_MACOSX) && !defined(OS_IOS)
280 if (header_->num_handles == 0)
281 return ScopedPlatformHandleVectorPtr();
282 ScopedPlatformHandleVectorPtr moved_handles(
283 new PlatformHandleVector(header_->num_handles));
284 for (size_t i = 0; i < header_->num_handles; ++i)
285 std::swap(moved_handles->at(i), handles()[i]);
286 header_->num_handles = 0;
287 return moved_handles;
288 #elif defined(OS_MACOSX) && !defined(OS_IOS)
289 if (mach_ports_header_) { 266 if (mach_ports_header_) {
290 for (size_t i = 0; i < max_handles_; ++i) { 267 for (size_t i = 0; i < max_handles_; ++i) {
291 mach_ports_header_->entries[i] = 268 mach_ports_header_->entries[i] =
292 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 269 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
293 } 270 }
294 mach_ports_header_->num_ports = 0; 271 mach_ports_header_->num_ports = 0;
295 } 272 }
296 header_->num_handles = 0; 273 header_->num_handles = 0;
297 return std::move(handle_vector_); 274 return std::move(handle_vector_);
298 #else 275 #else
(...skipping 24 matching lines...) Expand all
323 return std::move(handle_vector_); 300 return std::move(handle_vector_);
324 #else 301 #else
325 return std::move(handle_vector_); 302 return std::move(handle_vector_);
326 #endif 303 #endif
327 } 304 }
328 305
329 #if defined(OS_WIN) 306 #if defined(OS_WIN)
330 // static 307 // static
331 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, 308 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process,
332 base::ProcessHandle to_process, 309 base::ProcessHandle to_process,
333 PlatformHandle* handles, 310 PlatformHandleVector* handles) {
334 size_t num_handles) {
335 bool success = true; 311 bool success = true;
336 for (size_t i = 0; i < num_handles; ++i) { 312 for (size_t i = 0; i < handles->size(); ++i) {
337 if (!handles[i].is_valid()) { 313 if (!(*handles)[i].is_valid()) {
338 DLOG(ERROR) << "Refusing to duplicate invalid handle."; 314 DLOG(ERROR) << "Refusing to duplicate invalid handle.";
339 continue; 315 continue;
340 } 316 }
341 DCHECK_EQ(handles[i].owning_process, from_process); 317 DCHECK_EQ((*handles)[i].owning_process, from_process);
342 BOOL result = DuplicateHandle( 318 BOOL result = DuplicateHandle(
343 from_process, handles[i].handle, to_process, 319 from_process, (*handles)[i].handle, to_process,
344 &handles[i].handle, 0, FALSE, 320 &(*handles)[i].handle, 0, FALSE,
345 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 321 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
346 if (result) { 322 if (result) {
347 handles[i].owning_process = to_process; 323 (*handles)[i].owning_process = to_process;
348 } else { 324 } else {
349 success = false; 325 success = false;
350 326
351 // If handle duplication fails, the source handle will already be closed 327 // If handle duplication fails, the source handle will already be closed
352 // due to DUPLICATE_CLOSE_SOURCE. Replace the handle in the message with 328 // due to DUPLICATE_CLOSE_SOURCE. Replace the handle in the message with
353 // an invalid handle. 329 // an invalid handle.
354 handles[i].handle = INVALID_HANDLE_VALUE; 330 (*handles)[i].handle = INVALID_HANDLE_VALUE;
355 handles[i].owning_process = base::GetCurrentProcessHandle(); 331 (*handles)[i].owning_process = base::GetCurrentProcessHandle();
356 } 332 }
357 } 333 }
358 return success; 334 return success;
359 } 335 }
360 #endif 336 #endif
361 337
362 // Helper class for managing a Channel's read buffer allocations. This maintains 338 // Helper class for managing a Channel's read buffer allocations. This maintains
363 // a single contiguous buffer with the layout: 339 // a single contiguous buffer with the layout:
364 // 340 //
365 // [discarded bytes][occupied bytes][unoccupied bytes] 341 // [discarded bytes][occupied bytes][unoccupied bytes]
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 568
593 bool Channel::OnControlMessage(Message::Header::MessageType message_type, 569 bool Channel::OnControlMessage(Message::Header::MessageType message_type,
594 const void* payload, 570 const void* payload,
595 size_t payload_size, 571 size_t payload_size,
596 ScopedPlatformHandleVectorPtr handles) { 572 ScopedPlatformHandleVectorPtr handles) {
597 return false; 573 return false;
598 } 574 }
599 575
600 } // namespace edk 576 } // namespace edk
601 } // namespace mojo 577 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698