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

Side by Side Diff: ipc/attachment_broker_privileged_mac.cc

Issue 1778203002: Move mach code shared by Chrome IPC and Mojo to //base/mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: enum for error code 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "ipc/attachment_broker_privileged_mac.h" 5 #include "ipc/attachment_broker_privileged_mac.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <tuple> 9 #include <tuple>
10 10
11 #include "base/mac/mach_port_util.h"
11 #include "base/mac/scoped_mach_port.h" 12 #include "base/mac/scoped_mach_port.h"
12 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
13 #include "base/process/port_provider_mac.h" 14 #include "base/process/port_provider_mac.h"
14 #include "base/process/process.h" 15 #include "base/process/process.h"
15 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
16 #include "ipc/attachment_broker_messages.h" 17 #include "ipc/attachment_broker_messages.h"
17 #include "ipc/brokerable_attachment.h" 18 #include "ipc/brokerable_attachment.h"
18 #include "ipc/ipc_channel.h" 19 #include "ipc/ipc_channel.h"
19 #include "ipc/mach_port_attachment_mac.h" 20 #include "ipc/mach_port_attachment_mac.h"
20 21
21 namespace {
22
23 // Struct for sending a complex Mach message.
24 struct MachSendComplexMessage {
25 mach_msg_header_t header;
26 mach_msg_body_t body;
27 mach_msg_port_descriptor_t data;
28 };
29
30 // Sends a Mach port to |endpoint|. Assumes that |endpoint| is a send once
31 // right. Takes ownership of |endpoint|.
32 kern_return_t SendMachPort(mach_port_t endpoint,
33 mach_port_t port_to_send,
34 int disposition) {
35 MachSendComplexMessage send_msg;
36 send_msg.header.msgh_bits =
37 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0) | MACH_MSGH_BITS_COMPLEX;
38 send_msg.header.msgh_size = sizeof(send_msg);
39 send_msg.header.msgh_remote_port = endpoint;
40 send_msg.header.msgh_local_port = MACH_PORT_NULL;
41 send_msg.header.msgh_reserved = 0;
42 send_msg.header.msgh_id = 0;
43 send_msg.body.msgh_descriptor_count = 1;
44 send_msg.data.name = port_to_send;
45 send_msg.data.disposition = disposition;
46 send_msg.data.type = MACH_MSG_PORT_DESCRIPTOR;
47
48 kern_return_t kr =
49 mach_msg(&send_msg.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
50 send_msg.header.msgh_size,
51 0, // receive limit
52 MACH_PORT_NULL, // receive name
53 0, // timeout
54 MACH_PORT_NULL); // notification port
55
56 if (kr != KERN_SUCCESS)
57 mach_port_deallocate(mach_task_self(), endpoint);
58
59 return kr;
60 }
61
62 } // namespace
63
64 namespace IPC { 22 namespace IPC {
65 23
66 AttachmentBrokerPrivilegedMac::AttachmentBrokerPrivilegedMac( 24 AttachmentBrokerPrivilegedMac::AttachmentBrokerPrivilegedMac(
67 base::PortProvider* port_provider) 25 base::PortProvider* port_provider)
68 : port_provider_(port_provider) { 26 : port_provider_(port_provider) {
69 port_provider_->AddObserver(this); 27 port_provider_->AddObserver(this);
70 } 28 }
71 29
72 AttachmentBrokerPrivilegedMac::~AttachmentBrokerPrivilegedMac() { 30 AttachmentBrokerPrivilegedMac::~AttachmentBrokerPrivilegedMac() {
73 port_provider_->RemoveObserver(this); 31 port_provider_->RemoveObserver(this);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 << dest; 183 << dest;
226 LogError(DESTINATION_NOT_FOUND); 184 LogError(DESTINATION_NOT_FOUND);
227 return false; 185 return false;
228 } 186 }
229 187
230 LogError(DESTINATION_FOUND); 188 LogError(DESTINATION_FOUND);
231 sender->Send(new AttachmentBrokerMsg_MachPortHasBeenDuplicated(wire_format)); 189 sender->Send(new AttachmentBrokerMsg_MachPortHasBeenDuplicated(wire_format));
232 return true; 190 return true;
233 } 191 }
234 192
235 mach_port_name_t AttachmentBrokerPrivilegedMac::CreateIntermediateMachPort(
236 mach_port_t task_port,
237 base::mac::ScopedMachSendRight port_to_insert) {
238 DCHECK_NE(mach_task_self(), task_port);
239 DCHECK_NE(static_cast<mach_port_name_t>(MACH_PORT_NULL), task_port);
240
241 // Make a port with receive rights in the destination task.
242 mach_port_name_t endpoint;
243 kern_return_t kr =
244 mach_port_allocate(task_port, MACH_PORT_RIGHT_RECEIVE, &endpoint);
245 if (kr != KERN_SUCCESS) {
246 LogError(ERROR_MAKE_RECEIVE_PORT);
247 return MACH_PORT_NULL;
248 }
249
250 // Change its message queue limit so that it accepts one message.
251 mach_port_limits limits = {};
252 limits.mpl_qlimit = 1;
253 kr = mach_port_set_attributes(task_port, endpoint, MACH_PORT_LIMITS_INFO,
254 reinterpret_cast<mach_port_info_t>(&limits),
255 MACH_PORT_LIMITS_INFO_COUNT);
256 if (kr != KERN_SUCCESS) {
257 LogError(ERROR_SET_ATTRIBUTES);
258 mach_port_deallocate(task_port, endpoint);
259 return MACH_PORT_NULL;
260 }
261
262 // Get a send right.
263 mach_port_t send_once_right;
264 mach_msg_type_name_t send_right_type;
265 kr =
266 mach_port_extract_right(task_port, endpoint, MACH_MSG_TYPE_MAKE_SEND_ONCE,
267 &send_once_right, &send_right_type);
268 if (kr != KERN_SUCCESS) {
269 LogError(ERROR_EXTRACT_DEST_RIGHT);
270 mach_port_deallocate(task_port, endpoint);
271 return MACH_PORT_NULL;
272 }
273 DCHECK_EQ(static_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND_ONCE),
274 send_right_type);
275
276 // This call takes ownership of |send_once_right|.
277 kr = SendMachPort(
278 send_once_right, port_to_insert.get(), MACH_MSG_TYPE_COPY_SEND);
279 if (kr != KERN_SUCCESS) {
280 LogError(ERROR_SEND_MACH_PORT);
281 mach_port_deallocate(task_port, endpoint);
282 return MACH_PORT_NULL;
283 }
284
285 // Endpoint is intentionally leaked into the destination task. An IPC must be
286 // sent to the destination task so that it can clean up this port.
287 return endpoint;
288 }
289
290 base::mac::ScopedMachSendRight AttachmentBrokerPrivilegedMac::ExtractNamedRight( 193 base::mac::ScopedMachSendRight AttachmentBrokerPrivilegedMac::ExtractNamedRight(
291 mach_port_t task_port, 194 mach_port_t task_port,
292 mach_port_name_t named_right) { 195 mach_port_name_t named_right) {
293 mach_port_t extracted_right = MACH_PORT_NULL; 196 mach_port_t extracted_right = MACH_PORT_NULL;
294 mach_msg_type_name_t extracted_right_type; 197 mach_msg_type_name_t extracted_right_type;
295 kern_return_t kr = 198 kern_return_t kr =
296 mach_port_extract_right(task_port, named_right, MACH_MSG_TYPE_MOVE_SEND, 199 mach_port_extract_right(task_port, named_right, MACH_MSG_TYPE_MOVE_SEND,
297 &extracted_right, &extracted_right_type); 200 &extracted_right, &extracted_right_type);
298 if (kr != KERN_SUCCESS) { 201 if (kr != KERN_SUCCESS) {
299 LogError(ERROR_EXTRACT_SOURCE_RIGHT); 202 LogError(ERROR_EXTRACT_SOURCE_RIGHT);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 263
361 bool AttachmentBrokerPrivilegedMac::SendPrecursor( 264 bool AttachmentBrokerPrivilegedMac::SendPrecursor(
362 AttachmentPrecursor* precursor, 265 AttachmentPrecursor* precursor,
363 mach_port_t task_port) { 266 mach_port_t task_port) {
364 DCHECK(task_port); 267 DCHECK(task_port);
365 internal::MachPortAttachmentMac::WireFormat wire_format( 268 internal::MachPortAttachmentMac::WireFormat wire_format(
366 MACH_PORT_NULL, precursor->pid(), precursor->id()); 269 MACH_PORT_NULL, precursor->pid(), precursor->id());
367 base::mac::ScopedMachSendRight port_to_insert = precursor->TakePort(); 270 base::mac::ScopedMachSendRight port_to_insert = precursor->TakePort();
368 mach_port_name_t intermediate_port = MACH_PORT_NULL; 271 mach_port_name_t intermediate_port = MACH_PORT_NULL;
369 if (port_to_insert.get() != MACH_PORT_NULL) { 272 if (port_to_insert.get() != MACH_PORT_NULL) {
370 intermediate_port = CreateIntermediateMachPort( 273 base::MachCreateError error_code;
371 task_port, base::mac::ScopedMachSendRight(port_to_insert.release())); 274 intermediate_port = base::CreateIntermediateMachPort(
275 task_port, base::mac::ScopedMachSendRight(port_to_insert.release()),
276 &error_code);
277 if (intermediate_port == MACH_PORT_NULL) {
278 UMAError uma_error;
279 switch (error_code) {
280 case base::MachCreateError::ERROR_MAKE_RECEIVE_PORT:
281 uma_error = ERROR_MAKE_RECEIVE_PORT;
282 break;
283 case base::MachCreateError::ERROR_SET_ATTRIBUTES:
284 uma_error = ERROR_SET_ATTRIBUTES;
285 break;
286 case base::MachCreateError::ERROR_EXTRACT_DEST_RIGHT:
287 uma_error = ERROR_EXTRACT_DEST_RIGHT;
288 break;
289 case base::MachCreateError::ERROR_SEND_MACH_PORT:
290 uma_error = ERROR_SEND_MACH_PORT;
291 break;
292 }
293 LogError(uma_error);
294 }
372 } 295 }
373 return RouteWireFormatToAnother( 296 return RouteWireFormatToAnother(
374 CopyWireFormat(wire_format, intermediate_port)); 297 CopyWireFormat(wire_format, intermediate_port));
375 } 298 }
376 299
377 void AttachmentBrokerPrivilegedMac::AddPrecursor( 300 void AttachmentBrokerPrivilegedMac::AddPrecursor(
378 base::ProcessId pid, 301 base::ProcessId pid,
379 base::mac::ScopedMachSendRight port, 302 base::mac::ScopedMachSendRight port,
380 const BrokerableAttachment::AttachmentId& id) { 303 const BrokerableAttachment::AttachmentId& id) {
381 base::AutoLock l(precursors_lock_); 304 base::AutoLock l(precursors_lock_);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 367
445 auto it = extractors_.find(source_pid); 368 auto it = extractors_.find(source_pid);
446 if (it == extractors_.end()) 369 if (it == extractors_.end())
447 extractors_[source_pid] = new ScopedVector<AttachmentExtractor>; 370 extractors_[source_pid] = new ScopedVector<AttachmentExtractor>;
448 371
449 extractors_[source_pid]->push_back( 372 extractors_[source_pid]->push_back(
450 new AttachmentExtractor(source_pid, dest_pid, port, id)); 373 new AttachmentExtractor(source_pid, dest_pid, port, id));
451 } 374 }
452 375
453 } // namespace IPC 376 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/attachment_broker_privileged_mac.h ('k') | ipc/attachment_broker_privileged_mac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698