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

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: remove handles accessor Created 4 years, 7 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
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>
(...skipping 29 matching lines...) Expand all
40 const size_t kMaxAttachedHandles = 128; 40 const size_t kMaxAttachedHandles = 128;
41 41
42 Channel::Message::Message(size_t payload_size, 42 Channel::Message::Message(size_t payload_size,
43 size_t max_handles, 43 size_t max_handles,
44 Header::MessageType message_type) 44 Header::MessageType message_type)
45 : max_handles_(max_handles) { 45 : max_handles_(max_handles) {
46 DCHECK_LE(max_handles_, kMaxAttachedHandles); 46 DCHECK_LE(max_handles_, kMaxAttachedHandles);
47 47
48 size_t extra_header_size = 0; 48 size_t extra_header_size = 0;
49 #if defined(OS_WIN) 49 #if defined(OS_WIN)
50 // On Windows we serialize platform handles into the extra header space. 50 // On Windows we serialize HANDLES into the extra header space.
51 extra_header_size = max_handles_ * sizeof(PlatformHandle); 51 extra_header_size = max_handles_ * sizeof(HANDLE);
52 #elif defined(OS_MACOSX) && !defined(OS_IOS) 52 #elif defined(OS_MACOSX) && !defined(OS_IOS)
53 // On OSX, some of the platform handles may be mach ports, which are 53 // 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 54 // 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), 55 // 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. 56 // so that the original ordering of handles can be re-created.
57 if (max_handles) { 57 if (max_handles) {
58 extra_header_size = 58 extra_header_size =
59 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); 59 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
60 } 60 }
61 #endif 61 #endif
(...skipping 26 matching lines...) Expand all
88 header_->message_type = message_type; 88 header_->message_type = message_type;
89 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 89 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
90 header_->num_handles = static_cast<uint16_t>(max_handles); 90 header_->num_handles = static_cast<uint16_t>(max_handles);
91 #else 91 #else
92 header_->num_header_bytes = 92 header_->num_header_bytes =
93 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 93 static_cast<uint16_t>(sizeof(Header) + extra_header_size);
94 #endif 94 #endif
95 95
96 if (max_handles_ > 0) { 96 if (max_handles_ > 0) {
97 #if defined(OS_WIN) 97 #if defined(OS_WIN)
98 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); 98 handles_ = reinterpret_cast<HANDLE*>(mutable_extra_header());
99 // Initialize all handles to invalid values. 99 // Initialize all handles to invalid values.
100 for (size_t i = 0; i < max_handles_; ++i) 100 for (size_t i = 0; i < max_handles_; ++i)
101 handles()[i] = PlatformHandle(); 101 handles_[i] = INVALID_HANDLE_VALUE;
102 #elif defined(OS_MACOSX) && !defined(OS_IOS) 102 #elif defined(OS_MACOSX) && !defined(OS_IOS)
103 mach_ports_header_ = 103 mach_ports_header_ =
104 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 104 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
105 mach_ports_header_->num_ports = 0; 105 mach_ports_header_->num_ports = 0;
106 // Initialize all handles to invalid values. 106 // Initialize all handles to invalid values.
107 for (size_t i = 0; i < max_handles_; ++i) { 107 for (size_t i = 0; i < max_handles_; ++i) {
108 mach_ports_header_->entries[i] = 108 mach_ports_header_->entries[i] =
109 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 109 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
110 } 110 }
111 #endif 111 #endif
112 } 112 }
113 } 113 }
114 114
115 Channel::Message::~Message() { 115 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_); 116 base::AlignedFree(data_);
122 } 117 }
123 118
124 // static 119 // static
125 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 120 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
126 size_t data_num_bytes) { 121 size_t data_num_bytes) {
127 #if !defined(OS_WIN) && !(defined(OS_MACOSX) && !defined(OS_IOS)) 122 #if !defined(OS_WIN) && !(defined(OS_MACOSX) && !defined(OS_IOS))
128 // We only serialize messages into other messages when performing message 123 // We only serialize messages into other messages when performing message
129 // relay on Windows and OSX. 124 // relay on Windows and OSX.
130 NOTREACHED(); 125 NOTREACHED();
(...skipping 10 matching lines...) Expand all
141 } 136 }
142 137
143 if (header->num_bytes < header->num_header_bytes) { 138 if (header->num_bytes < header->num_header_bytes) {
144 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 139 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
145 << header->num_header_bytes; 140 << header->num_header_bytes;
146 return nullptr; 141 return nullptr;
147 } 142 }
148 143
149 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 144 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
150 #if defined(OS_WIN) 145 #if defined(OS_WIN)
151 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); 146 uint32_t max_handles = extra_header_size / sizeof(HANDLE);
152 #elif defined(OS_MACOSX) && !defined(OS_IOS) 147 #elif defined(OS_MACOSX) && !defined(OS_IOS)
153 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) / 148 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
154 sizeof(MachPortsEntry); 149 sizeof(MachPortsEntry);
155 #endif 150 #endif
156 if (header->num_handles > max_handles) { 151 if (header->num_handles > max_handles) {
157 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 152 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
158 << " > " << max_handles; 153 << " > " << max_handles;
159 return nullptr; 154 return nullptr;
160 } 155 }
161 156
(...skipping 11 matching lines...) Expand all
173 } 168 }
174 169
175 if (message->extra_header_size()) { 170 if (message->extra_header_size()) {
176 // Copy extra header bytes. 171 // Copy extra header bytes.
177 memcpy(message->mutable_extra_header(), 172 memcpy(message->mutable_extra_header(),
178 static_cast<const char*>(data) + sizeof(Header), 173 static_cast<const char*>(data) + sizeof(Header),
179 message->extra_header_size()); 174 message->extra_header_size());
180 } 175 }
181 176
182 message->header_->num_handles = header->num_handles; 177 message->header_->num_handles = header->num_handles;
178 #if defined(OS_WIN)
179 ScopedPlatformHandleVectorPtr handles(
180 new PlatformHandleVector(header->num_handles));
181 for (size_t i = 0; i < header->num_handles; i++)
182 (*handles)[i].handle = message->handles_[i];
183 message->SetHandles(std::move(handles));
184 #endif
183 185
184 return message; 186 return message;
185 #endif 187 #endif
186 } 188 }
187 189
188 size_t Channel::Message::payload_size() const { 190 size_t Channel::Message::payload_size() const {
189 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) 191 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
190 return header_->num_bytes - sizeof(Header); 192 return header_->num_bytes - sizeof(Header);
191 #else 193 #else
192 return size_ - header_->num_header_bytes; 194 return size_ - header_->num_header_bytes;
193 #endif 195 #endif
194 } 196 }
195 197
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) 198 #if defined(OS_MACOSX) && !defined(OS_IOS)
216 bool Channel::Message::has_mach_ports() const { 199 bool Channel::Message::has_mach_ports() const {
217 if (!has_handles()) 200 if (!has_handles())
218 return false; 201 return false;
219 202
220 for (const auto& handle : (*handle_vector_)) { 203 for (const auto& handle : (*handle_vector_)) {
221 if (handle.type == PlatformHandle::Type::MACH || 204 if (handle.type == PlatformHandle::Type::MACH ||
222 handle.type == PlatformHandle::Type::MACH_NAME) { 205 handle.type == PlatformHandle::Type::MACH_NAME) {
223 return true; 206 return true;
224 } 207 }
(...skipping 13 matching lines...) Expand all
238 std::swap(handle_vector_, new_handles); 221 std::swap(handle_vector_, new_handles);
239 222
240 #else 223 #else
241 if (max_handles_ == 0) { 224 if (max_handles_ == 0) {
242 CHECK(!new_handles || new_handles->size() == 0); 225 CHECK(!new_handles || new_handles->size() == 0);
243 return; 226 return;
244 } 227 }
245 228
246 CHECK(new_handles && new_handles->size() <= max_handles_); 229 CHECK(new_handles && new_handles->size() <= max_handles_);
247 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 230 header_->num_handles = static_cast<uint16_t>(new_handles->size());
231 std::swap(handle_vector_, new_handles);
248 #if defined(OS_WIN) 232 #if defined(OS_WIN)
249 memcpy(handles(), new_handles->data(), 233 memset(handles_, 0, extra_header_size());
250 sizeof(PlatformHandle) * new_handles->size()); 234 for (size_t i = 0; i < handle_vector_->size(); i++)
251 new_handles->clear(); 235 handles_[i] = (*handle_vector_)[i].handle;
252 #else
253 std::swap(handle_vector_, new_handles);
254 #endif // defined(OS_WIN) 236 #endif // defined(OS_WIN)
255 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID) 237 #endif // defined(OS_CHROMEOS) || defined(OS_ANDROID)
256 238
257 #if defined(OS_MACOSX) && !defined(OS_IOS) 239 #if defined(OS_MACOSX) && !defined(OS_IOS)
258 size_t mach_port_index = 0; 240 size_t mach_port_index = 0;
259 if (mach_ports_header_) { 241 if (mach_ports_header_) {
260 for (size_t i = 0; i < max_handles_; ++i) { 242 for (size_t i = 0; i < max_handles_; ++i) {
261 mach_ports_header_->entries[i] = 243 mach_ports_header_->entries[i] =
262 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 244 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
263 } 245 }
264 for (size_t i = 0; i < handle_vector_->size(); i++) { 246 for (size_t i = 0; i < handle_vector_->size(); i++) {
265 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 247 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
266 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) { 248 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) {
267 mach_port_t port = (*handle_vector_)[i].port; 249 mach_port_t port = (*handle_vector_)[i].port;
268 mach_ports_header_->entries[mach_port_index].index = i; 250 mach_ports_header_->entries[mach_port_index].index = i;
269 mach_ports_header_->entries[mach_port_index].mach_port = port; 251 mach_ports_header_->entries[mach_port_index].mach_port = port;
270 mach_port_index++; 252 mach_port_index++;
271 } 253 }
272 } 254 }
273 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index); 255 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index);
274 } 256 }
275 #endif 257 #endif
276 } 258 }
277 259
278 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 260 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
279 #if defined(OS_WIN) 261 #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_) { 262 if (mach_ports_header_) {
290 for (size_t i = 0; i < max_handles_; ++i) { 263 for (size_t i = 0; i < max_handles_; ++i) {
291 mach_ports_header_->entries[i] = 264 mach_ports_header_->entries[i] =
292 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 265 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
293 } 266 }
294 mach_ports_header_->num_ports = 0; 267 mach_ports_header_->num_ports = 0;
295 } 268 }
296 header_->num_handles = 0; 269 header_->num_handles = 0;
297 return std::move(handle_vector_); 270 return std::move(handle_vector_);
298 #else 271 #else
(...skipping 24 matching lines...) Expand all
323 return std::move(handle_vector_); 296 return std::move(handle_vector_);
324 #else 297 #else
325 return std::move(handle_vector_); 298 return std::move(handle_vector_);
326 #endif 299 #endif
327 } 300 }
328 301
329 #if defined(OS_WIN) 302 #if defined(OS_WIN)
330 // static 303 // static
331 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, 304 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process,
332 base::ProcessHandle to_process, 305 base::ProcessHandle to_process,
333 PlatformHandle* handles, 306 PlatformHandleVector* handles) {
334 size_t num_handles) {
335 bool success = true; 307 bool success = true;
336 for (size_t i = 0; i < num_handles; ++i) { 308 for (size_t i = 0; i < handles->size(); ++i) {
337 if (!handles[i].is_valid()) { 309 if (!(*handles)[i].is_valid()) {
338 DLOG(ERROR) << "Refusing to duplicate invalid handle."; 310 DLOG(ERROR) << "Refusing to duplicate invalid handle.";
339 continue; 311 continue;
340 } 312 }
341 DCHECK_EQ(handles[i].owning_process, from_process); 313 DCHECK_EQ((*handles)[i].owning_process, from_process);
342 BOOL result = DuplicateHandle( 314 BOOL result = DuplicateHandle(
343 from_process, handles[i].handle, to_process, 315 from_process, (*handles)[i].handle, to_process,
344 &handles[i].handle, 0, FALSE, 316 &(*handles)[i].handle, 0, FALSE,
345 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 317 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
346 if (result) { 318 if (result) {
347 handles[i].owning_process = to_process; 319 (*handles)[i].owning_process = to_process;
348 } else { 320 } else {
349 success = false; 321 success = false;
350 322
351 // If handle duplication fails, the source handle will already be closed 323 // If handle duplication fails, the source handle will already be closed
352 // due to DUPLICATE_CLOSE_SOURCE. Replace the handle in the message with 324 // due to DUPLICATE_CLOSE_SOURCE. Replace the handle in the message with
353 // an invalid handle. 325 // an invalid handle.
354 handles[i].handle = INVALID_HANDLE_VALUE; 326 (*handles)[i].handle = INVALID_HANDLE_VALUE;
355 handles[i].owning_process = base::GetCurrentProcessHandle(); 327 (*handles)[i].owning_process = base::GetCurrentProcessHandle();
356 } 328 }
357 } 329 }
358 return success; 330 return success;
359 } 331 }
360 #endif 332 #endif
361 333
362 // Helper class for managing a Channel's read buffer allocations. This maintains 334 // Helper class for managing a Channel's read buffer allocations. This maintains
363 // a single contiguous buffer with the layout: 335 // a single contiguous buffer with the layout:
364 // 336 //
365 // [discarded bytes][occupied bytes][unoccupied bytes] 337 // [discarded bytes][occupied bytes][unoccupied bytes]
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 564
593 bool Channel::OnControlMessage(Message::Header::MessageType message_type, 565 bool Channel::OnControlMessage(Message::Header::MessageType message_type,
594 const void* payload, 566 const void* payload,
595 size_t payload_size, 567 size_t payload_size,
596 ScopedPlatformHandleVectorPtr handles) { 568 ScopedPlatformHandleVectorPtr handles) {
597 return false; 569 return false;
598 } 570 }
599 571
600 } // namespace edk 572 } // namespace edk
601 } // namespace mojo 573 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698