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_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 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 switch (attachment->GetBrokerableType()) { | 47 switch (attachment->GetBrokerableType()) { |
48 case BrokerableAttachment::MACH_PORT: { | 48 case BrokerableAttachment::MACH_PORT: { |
49 internal::MachPortAttachmentMac* mach_port_attachment = | 49 internal::MachPortAttachmentMac* mach_port_attachment = |
50 static_cast<internal::MachPortAttachmentMac*>(attachment.get()); | 50 static_cast<internal::MachPortAttachmentMac*>(attachment.get()); |
51 MachPortWireFormat wire_format = | 51 MachPortWireFormat wire_format = |
52 mach_port_attachment->GetWireFormat(destination_process); | 52 mach_port_attachment->GetWireFormat(destination_process); |
53 AddPrecursor(wire_format.destination_process, | 53 AddPrecursor(wire_format.destination_process, |
54 base::mac::ScopedMachSendRight(wire_format.mach_port), | 54 base::mac::ScopedMachSendRight(wire_format.mach_port), |
55 wire_format.attachment_id); | 55 wire_format.attachment_id); |
56 mach_port_attachment->reset_mach_port_ownership(); | 56 mach_port_attachment->reset_mach_port_ownership(); |
57 SendPrecursorsForProcess(wire_format.destination_process); | 57 SendPrecursorsForProcess(wire_format.destination_process, true); |
58 return true; | 58 return true; |
59 } | 59 } |
60 default: | 60 default: |
61 NOTREACHED(); | 61 NOTREACHED(); |
62 return false; | 62 return false; |
63 } | 63 } |
64 return false; | 64 return false; |
65 } | 65 } |
66 | 66 |
67 void AttachmentBrokerPrivilegedMac::DeregisterCommunicationChannel( | 67 void AttachmentBrokerPrivilegedMac::DeregisterCommunicationChannel( |
(...skipping 19 matching lines...) Expand all Loading... |
87 { | 87 { |
88 base::AutoLock l(extractors_lock_); | 88 base::AutoLock l(extractors_lock_); |
89 auto it = extractors_.find(pid); | 89 auto it = extractors_.find(pid); |
90 if (it != extractors_.end()) { | 90 if (it != extractors_.end()) { |
91 delete it->second; | 91 delete it->second; |
92 extractors_.erase(pid); | 92 extractors_.erase(pid); |
93 } | 93 } |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
| 97 void AttachmentBrokerPrivilegedMac::ReceivedPeerPid(base::ProcessId peer_pid) { |
| 98 ProcessExtractorsForProcess(peer_pid, false); |
| 99 SendPrecursorsForProcess(peer_pid, false); |
| 100 } |
| 101 |
97 bool AttachmentBrokerPrivilegedMac::OnMessageReceived(const Message& msg) { | 102 bool AttachmentBrokerPrivilegedMac::OnMessageReceived(const Message& msg) { |
98 bool handled = true; | 103 bool handled = true; |
99 switch (msg.type()) { | 104 switch (msg.type()) { |
100 IPC_MESSAGE_HANDLER_GENERIC(AttachmentBrokerMsg_DuplicateMachPort, | 105 IPC_MESSAGE_HANDLER_GENERIC(AttachmentBrokerMsg_DuplicateMachPort, |
101 OnDuplicateMachPort(msg)) | 106 OnDuplicateMachPort(msg)) |
102 IPC_MESSAGE_UNHANDLED(handled = false) | 107 IPC_MESSAGE_UNHANDLED(handled = false) |
103 } | 108 } |
104 return handled; | 109 return handled; |
105 } | 110 } |
106 | 111 |
107 void AttachmentBrokerPrivilegedMac::OnReceivedTaskPort( | 112 void AttachmentBrokerPrivilegedMac::OnReceivedTaskPort( |
108 base::ProcessHandle process) { | 113 base::ProcessHandle process) { |
109 SendPrecursorsForProcess(process); | 114 SendPrecursorsForProcess(process, true); |
110 } | 115 } |
111 | 116 |
112 AttachmentBrokerPrivilegedMac::AttachmentPrecursor::AttachmentPrecursor( | 117 AttachmentBrokerPrivilegedMac::AttachmentPrecursor::AttachmentPrecursor( |
113 const base::ProcessId& pid, | 118 const base::ProcessId& pid, |
114 base::mac::ScopedMachSendRight port, | 119 base::mac::ScopedMachSendRight port, |
115 const BrokerableAttachment::AttachmentId& id) | 120 const BrokerableAttachment::AttachmentId& id) |
116 : pid_(pid), port_(port.release()), id_(id) {} | 121 : pid_(pid), port_(port.release()), id_(id) {} |
117 | 122 |
118 AttachmentBrokerPrivilegedMac::AttachmentPrecursor::~AttachmentPrecursor() {} | 123 AttachmentBrokerPrivilegedMac::AttachmentPrecursor::~AttachmentPrecursor() {} |
119 | 124 |
(...skipping 25 matching lines...) Expand all Loading... |
145 IPC::internal::MachPortAttachmentMac::WireFormat wire_format = | 150 IPC::internal::MachPortAttachmentMac::WireFormat wire_format = |
146 std::get<0>(param); | 151 std::get<0>(param); |
147 | 152 |
148 if (wire_format.destination_process == base::kNullProcessId) { | 153 if (wire_format.destination_process == base::kNullProcessId) { |
149 LogError(NO_DESTINATION); | 154 LogError(NO_DESTINATION); |
150 return; | 155 return; |
151 } | 156 } |
152 | 157 |
153 AddExtractor(message.get_sender_pid(), wire_format.destination_process, | 158 AddExtractor(message.get_sender_pid(), wire_format.destination_process, |
154 wire_format.mach_port, wire_format.attachment_id); | 159 wire_format.mach_port, wire_format.attachment_id); |
155 ProcessExtractorsForProcess(message.get_sender_pid()); | 160 ProcessExtractorsForProcess(message.get_sender_pid(), true); |
156 } | 161 } |
157 | 162 |
158 void AttachmentBrokerPrivilegedMac::RoutePrecursorToSelf( | 163 void AttachmentBrokerPrivilegedMac::RoutePrecursorToSelf( |
159 AttachmentPrecursor* precursor) { | 164 AttachmentPrecursor* precursor) { |
160 DCHECK_EQ(base::Process::Current().Pid(), precursor->pid()); | 165 DCHECK_EQ(base::Process::Current().Pid(), precursor->pid()); |
161 | 166 |
162 // Intentionally leak the port, since the attachment takes ownership. | 167 // Intentionally leak the port, since the attachment takes ownership. |
163 internal::MachPortAttachmentMac::WireFormat wire_format( | 168 internal::MachPortAttachmentMac::WireFormat wire_format( |
164 precursor->TakePort().release(), precursor->pid(), precursor->id()); | 169 precursor->TakePort().release(), precursor->pid(), precursor->id()); |
165 scoped_refptr<BrokerableAttachment> attachment( | 170 scoped_refptr<BrokerableAttachment> attachment( |
166 new internal::MachPortAttachmentMac(wire_format)); | 171 new internal::MachPortAttachmentMac(wire_format)); |
167 HandleReceivedAttachment(attachment); | 172 HandleReceivedAttachment(attachment); |
168 } | 173 } |
169 | 174 |
170 bool AttachmentBrokerPrivilegedMac::RouteWireFormatToAnother( | 175 bool AttachmentBrokerPrivilegedMac::RouteWireFormatToAnother( |
171 const MachPortWireFormat& wire_format) { | 176 const MachPortWireFormat& wire_format) { |
172 DCHECK_NE(wire_format.destination_process, base::Process::Current().Pid()); | 177 DCHECK_NE(wire_format.destination_process, base::Process::Current().Pid()); |
173 | 178 |
174 // Another process is the destination. | 179 // Another process is the destination. |
175 base::ProcessId dest = wire_format.destination_process; | 180 base::ProcessId dest = wire_format.destination_process; |
176 base::AutoLock auto_lock(*get_lock()); | 181 base::AutoLock auto_lock(*get_lock()); |
177 AttachmentBrokerPrivileged::EndpointRunnerPair pair = | 182 AttachmentBrokerPrivileged::EndpointRunnerPair pair = |
178 GetSenderWithProcessId(dest); | 183 GetSenderWithProcessId(dest); |
179 if (!pair.first) { | 184 if (!pair.first) { |
180 // Assuming that this message was not sent from a malicious process, the | 185 // The extractor was successfully processed, which implies that the |
181 // channel endpoint that would have received this message will block | 186 // communication channel was established. This implies that the |
182 // forever. | 187 // communication was taken down in the interim. |
183 LOG(ERROR) << "Failed to deliver brokerable attachment to process with id: " | 188 LOG(ERROR) << "Failed to deliver brokerable attachment to process with id: " |
184 << dest; | 189 << dest; |
185 LogError(DESTINATION_NOT_FOUND); | 190 LogError(DESTINATION_NOT_FOUND); |
186 return false; | 191 return false; |
187 } | 192 } |
188 | 193 |
189 LogError(DESTINATION_FOUND); | 194 LogError(DESTINATION_FOUND); |
190 SendMessageToEndpoint( | 195 SendMessageToEndpoint( |
191 pair, new AttachmentBrokerMsg_MachPortHasBeenDuplicated(wire_format)); | 196 pair, new AttachmentBrokerMsg_MachPortHasBeenDuplicated(wire_format)); |
192 return true; | 197 return true; |
(...skipping 23 matching lines...) Expand all Loading... |
216 | 221 |
217 AttachmentBrokerPrivilegedMac::MachPortWireFormat | 222 AttachmentBrokerPrivilegedMac::MachPortWireFormat |
218 AttachmentBrokerPrivilegedMac::CopyWireFormat( | 223 AttachmentBrokerPrivilegedMac::CopyWireFormat( |
219 const MachPortWireFormat& wire_format, | 224 const MachPortWireFormat& wire_format, |
220 uint32_t mach_port) { | 225 uint32_t mach_port) { |
221 return MachPortWireFormat(mach_port, wire_format.destination_process, | 226 return MachPortWireFormat(mach_port, wire_format.destination_process, |
222 wire_format.attachment_id); | 227 wire_format.attachment_id); |
223 } | 228 } |
224 | 229 |
225 void AttachmentBrokerPrivilegedMac::SendPrecursorsForProcess( | 230 void AttachmentBrokerPrivilegedMac::SendPrecursorsForProcess( |
226 base::ProcessId pid) { | 231 base::ProcessId pid, |
| 232 bool store_on_failure) { |
227 base::AutoLock l(precursors_lock_); | 233 base::AutoLock l(precursors_lock_); |
228 auto it = precursors_.find(pid); | 234 auto it = precursors_.find(pid); |
229 if (it == precursors_.end()) | 235 if (it == precursors_.end()) |
230 return; | 236 return; |
231 | 237 |
232 // Whether this process is the destination process. | 238 // Whether this process is the destination process. |
233 bool to_self = pid == base::GetCurrentProcId(); | 239 bool to_self = pid == base::GetCurrentProcId(); |
234 | 240 |
235 if (!to_self) { | 241 if (!to_self) { |
236 base::AutoLock auto_lock(*get_lock()); | 242 base::AutoLock auto_lock(*get_lock()); |
237 AttachmentBrokerPrivileged::EndpointRunnerPair pair = | 243 AttachmentBrokerPrivileged::EndpointRunnerPair pair = |
238 GetSenderWithProcessId(pid); | 244 GetSenderWithProcessId(pid); |
239 if (!pair.first) { | 245 if (!pair.first) { |
240 // If there is no sender, then the destination process is no longer | 246 if (store_on_failure) { |
241 // running, or never existed to begin with. | 247 // Try again later. |
242 LogError(DESTINATION_NOT_FOUND); | 248 LogError(DELAYED); |
243 delete it->second; | 249 } else { |
244 precursors_.erase(it); | 250 // If there is no sender, then permanently fail. |
| 251 LogError(DESTINATION_NOT_FOUND); |
| 252 delete it->second; |
| 253 precursors_.erase(it); |
| 254 } |
245 return; | 255 return; |
246 } | 256 } |
247 } | 257 } |
248 | 258 |
249 mach_port_t task_port = port_provider_->TaskForPid(pid); | 259 mach_port_t task_port = port_provider_->TaskForPid(pid); |
250 | 260 |
251 // It's possible that the destination process has not yet provided the | 261 // It's possible that the destination process has not yet provided the |
252 // privileged process with its task port. | 262 // privileged process with its task port. |
253 if (!to_self && task_port == MACH_PORT_NULL) | 263 if (!to_self && task_port == MACH_PORT_NULL) |
254 return; | 264 return; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 base::AutoLock l(precursors_lock_); | 321 base::AutoLock l(precursors_lock_); |
312 auto it = precursors_.find(pid); | 322 auto it = precursors_.find(pid); |
313 if (it == precursors_.end()) | 323 if (it == precursors_.end()) |
314 precursors_[pid] = new ScopedVector<AttachmentPrecursor>; | 324 precursors_[pid] = new ScopedVector<AttachmentPrecursor>; |
315 | 325 |
316 precursors_[pid]->push_back(new AttachmentPrecursor( | 326 precursors_[pid]->push_back(new AttachmentPrecursor( |
317 pid, base::mac::ScopedMachSendRight(port.release()), id)); | 327 pid, base::mac::ScopedMachSendRight(port.release()), id)); |
318 } | 328 } |
319 | 329 |
320 void AttachmentBrokerPrivilegedMac::ProcessExtractorsForProcess( | 330 void AttachmentBrokerPrivilegedMac::ProcessExtractorsForProcess( |
321 base::ProcessId pid) { | 331 base::ProcessId pid, |
| 332 bool store_on_failure) { |
322 base::AutoLock l(extractors_lock_); | 333 base::AutoLock l(extractors_lock_); |
323 auto it = extractors_.find(pid); | 334 auto it = extractors_.find(pid); |
324 if (it == extractors_.end()) | 335 if (it == extractors_.end()) |
325 return; | 336 return; |
326 | 337 |
327 { | 338 { |
328 base::AutoLock auto_lock(*get_lock()); | 339 base::AutoLock auto_lock(*get_lock()); |
329 AttachmentBrokerPrivileged::EndpointRunnerPair pair = | 340 AttachmentBrokerPrivileged::EndpointRunnerPair pair = |
330 GetSenderWithProcessId(pid); | 341 GetSenderWithProcessId(pid); |
331 if (!pair.first) { | 342 if (!pair.first) { |
332 // If there is no sender, then the source process is no longer running. | 343 if (store_on_failure) { |
333 LogError(ERROR_SOURCE_NOT_FOUND); | 344 // If there is no sender, then the communication channel with the source |
334 delete it->second; | 345 // process has not yet been established. Try again later. |
335 extractors_.erase(it); | 346 LogError(DELAYED); |
| 347 } else { |
| 348 // There is no sender. Permanently fail. |
| 349 LogError(ERROR_SOURCE_NOT_FOUND); |
| 350 delete it->second; |
| 351 extractors_.erase(it); |
| 352 } |
336 return; | 353 return; |
337 } | 354 } |
338 } | 355 } |
339 | 356 |
340 mach_port_t task_port = port_provider_->TaskForPid(pid); | 357 mach_port_t task_port = port_provider_->TaskForPid(pid); |
341 | 358 |
342 // It's possible that the source process has not yet provided the privileged | 359 // It's possible that the source process has not yet provided the privileged |
343 // process with its task port. | 360 // process with its task port. |
344 if (task_port == MACH_PORT_NULL) | 361 if (task_port == MACH_PORT_NULL) |
345 return; | 362 return; |
(...skipping 10 matching lines...) Expand all Loading... |
356 | 373 |
357 void AttachmentBrokerPrivilegedMac::ProcessExtractor( | 374 void AttachmentBrokerPrivilegedMac::ProcessExtractor( |
358 AttachmentExtractor* extractor, | 375 AttachmentExtractor* extractor, |
359 mach_port_t task_port) { | 376 mach_port_t task_port) { |
360 DCHECK(task_port); | 377 DCHECK(task_port); |
361 base::mac::ScopedMachSendRight send_right = | 378 base::mac::ScopedMachSendRight send_right = |
362 ExtractNamedRight(task_port, extractor->port()); | 379 ExtractNamedRight(task_port, extractor->port()); |
363 AddPrecursor(extractor->dest_pid(), | 380 AddPrecursor(extractor->dest_pid(), |
364 base::mac::ScopedMachSendRight(send_right.release()), | 381 base::mac::ScopedMachSendRight(send_right.release()), |
365 extractor->id()); | 382 extractor->id()); |
366 SendPrecursorsForProcess(extractor->dest_pid()); | 383 SendPrecursorsForProcess(extractor->dest_pid(), true); |
367 } | 384 } |
368 | 385 |
369 void AttachmentBrokerPrivilegedMac::AddExtractor( | 386 void AttachmentBrokerPrivilegedMac::AddExtractor( |
370 base::ProcessId source_pid, | 387 base::ProcessId source_pid, |
371 base::ProcessId dest_pid, | 388 base::ProcessId dest_pid, |
372 mach_port_name_t port, | 389 mach_port_name_t port, |
373 const BrokerableAttachment::AttachmentId& id) { | 390 const BrokerableAttachment::AttachmentId& id) { |
374 base::AutoLock l(extractors_lock_); | 391 base::AutoLock l(extractors_lock_); |
375 DCHECK_NE(base::GetCurrentProcId(), source_pid); | 392 DCHECK_NE(base::GetCurrentProcId(), source_pid); |
376 | 393 |
377 auto it = extractors_.find(source_pid); | 394 auto it = extractors_.find(source_pid); |
378 if (it == extractors_.end()) | 395 if (it == extractors_.end()) |
379 extractors_[source_pid] = new ScopedVector<AttachmentExtractor>; | 396 extractors_[source_pid] = new ScopedVector<AttachmentExtractor>; |
380 | 397 |
381 extractors_[source_pid]->push_back( | 398 extractors_[source_pid]->push_back( |
382 new AttachmentExtractor(source_pid, dest_pid, port, id)); | 399 new AttachmentExtractor(source_pid, dest_pid, port, id)); |
383 } | 400 } |
384 | 401 |
385 } // namespace IPC | 402 } // namespace IPC |
OLD | NEW |