OLD | NEW |
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_unprivileged_mac.h" | 5 #include "ipc/attachment_broker_unprivileged_mac.h" |
6 | 6 |
7 #include <mach/mach.h> | 7 #include <mach/mach.h> |
8 | 8 |
| 9 #include "base/mac/mach_port_util.h" |
9 #include "base/mac/scoped_mach_port.h" | 10 #include "base/mac/scoped_mach_port.h" |
10 #include "base/process/process.h" | 11 #include "base/process/process.h" |
11 #include "ipc/attachment_broker_messages.h" | 12 #include "ipc/attachment_broker_messages.h" |
12 #include "ipc/brokerable_attachment.h" | 13 #include "ipc/brokerable_attachment.h" |
13 #include "ipc/ipc_sender.h" | 14 #include "ipc/ipc_sender.h" |
14 #include "ipc/mach_port_attachment_mac.h" | 15 #include "ipc/mach_port_attachment_mac.h" |
15 | 16 |
16 namespace { | |
17 | |
18 // Struct for receiving a complex message. | |
19 struct MachReceiveComplexMessage { | |
20 mach_msg_header_t header; | |
21 mach_msg_body_t body; | |
22 mach_msg_port_descriptor_t data; | |
23 mach_msg_trailer_t trailer; | |
24 }; | |
25 | |
26 // Receives a Mach port from |port_to_listen_on|, which should have exactly one | |
27 // queued message. Returns |MACH_PORT_NULL| on any error. | |
28 base::mac::ScopedMachSendRight ReceiveMachPort(mach_port_t port_to_listen_on) { | |
29 MachReceiveComplexMessage recv_msg; | |
30 mach_msg_header_t* recv_hdr = &recv_msg.header; | |
31 recv_hdr->msgh_local_port = port_to_listen_on; | |
32 recv_hdr->msgh_size = sizeof(recv_msg); | |
33 | |
34 kern_return_t kr = | |
35 mach_msg(recv_hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, | |
36 recv_hdr->msgh_size, port_to_listen_on, 0, MACH_PORT_NULL); | |
37 if (kr != KERN_SUCCESS) | |
38 return base::mac::ScopedMachSendRight(MACH_PORT_NULL); | |
39 if (recv_msg.header.msgh_id != 0) | |
40 return base::mac::ScopedMachSendRight(MACH_PORT_NULL); | |
41 return base::mac::ScopedMachSendRight(recv_msg.data.name); | |
42 } | |
43 | |
44 } // namespace | |
45 | |
46 namespace IPC { | 17 namespace IPC { |
47 | 18 |
48 AttachmentBrokerUnprivilegedMac::AttachmentBrokerUnprivilegedMac() {} | 19 AttachmentBrokerUnprivilegedMac::AttachmentBrokerUnprivilegedMac() {} |
49 | 20 |
50 AttachmentBrokerUnprivilegedMac::~AttachmentBrokerUnprivilegedMac() {} | 21 AttachmentBrokerUnprivilegedMac::~AttachmentBrokerUnprivilegedMac() {} |
51 | 22 |
52 bool AttachmentBrokerUnprivilegedMac::SendAttachmentToProcess( | 23 bool AttachmentBrokerUnprivilegedMac::SendAttachmentToProcess( |
53 const scoped_refptr<IPC::BrokerableAttachment>& attachment, | 24 const scoped_refptr<IPC::BrokerableAttachment>& attachment, |
54 base::ProcessId destination_process) { | 25 base::ProcessId destination_process) { |
55 switch (attachment->GetBrokerableType()) { | 26 switch (attachment->GetBrokerableType()) { |
(...skipping 30 matching lines...) Expand all Loading... |
86 // The IPC message was intended for a different process. Ignore it. | 57 // The IPC message was intended for a different process. Ignore it. |
87 if (wire_format.destination_process != base::Process::Current().Pid()) { | 58 if (wire_format.destination_process != base::Process::Current().Pid()) { |
88 // If everything is functioning correctly, this path should not be taken. | 59 // If everything is functioning correctly, this path should not be taken. |
89 // However, it's still important to validate all fields of the IPC message. | 60 // However, it's still important to validate all fields of the IPC message. |
90 LogError(WRONG_DESTINATION); | 61 LogError(WRONG_DESTINATION); |
91 return; | 62 return; |
92 } | 63 } |
93 | 64 |
94 base::mac::ScopedMachReceiveRight message_port(wire_format.mach_port); | 65 base::mac::ScopedMachReceiveRight message_port(wire_format.mach_port); |
95 base::mac::ScopedMachSendRight memory_object( | 66 base::mac::ScopedMachSendRight memory_object( |
96 ReceiveMachPort(message_port.get())); | 67 base::ReceiveMachPort(message_port.get())); |
97 | 68 |
98 LogError(memory_object.get() == MACH_PORT_NULL ? ERR_RECEIVE_MACH_MESSAGE | 69 LogError(memory_object.get() == MACH_PORT_NULL ? ERR_RECEIVE_MACH_MESSAGE |
99 : SUCCESS); | 70 : SUCCESS); |
100 | 71 |
101 IPC::internal::MachPortAttachmentMac::WireFormat translated_wire_format( | 72 IPC::internal::MachPortAttachmentMac::WireFormat translated_wire_format( |
102 memory_object.release(), wire_format.destination_process, | 73 memory_object.release(), wire_format.destination_process, |
103 wire_format.attachment_id); | 74 wire_format.attachment_id); |
104 | 75 |
105 scoped_refptr<BrokerableAttachment> attachment( | 76 scoped_refptr<BrokerableAttachment> attachment( |
106 new IPC::internal::MachPortAttachmentMac(translated_wire_format)); | 77 new IPC::internal::MachPortAttachmentMac(translated_wire_format)); |
107 HandleReceivedAttachment(attachment); | 78 HandleReceivedAttachment(attachment); |
108 } | 79 } |
109 | 80 |
110 } // namespace IPC | 81 } // namespace IPC |
OLD | NEW |