| 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 |