| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 21 #include "ipc/ipc_listener.h" | 21 #include "ipc/ipc_listener.h" |
| 22 #include "ipc/ipc_logging.h" | 22 #include "ipc/ipc_logging.h" |
| 23 #include "ipc/ipc_message_attachment_set.h" | 23 #include "ipc/ipc_message_attachment_set.h" |
| 24 #include "ipc/ipc_message_macros.h" | 24 #include "ipc/ipc_message_macros.h" |
| 25 #include "ipc/mojo/ipc_mojo_bootstrap.h" | 25 #include "ipc/mojo/ipc_mojo_bootstrap.h" |
| 26 #include "ipc/mojo/ipc_mojo_handle_attachment.h" | 26 #include "ipc/mojo/ipc_mojo_handle_attachment.h" |
| 27 #include "mojo/edk/embedder/embedder.h" | |
| 28 #include "mojo/public/cpp/bindings/binding.h" | 27 #include "mojo/public/cpp/bindings/binding.h" |
| 28 #include "mojo/public/cpp/system/platform_handle.h" |
| 29 | 29 |
| 30 #if defined(OS_POSIX) | 30 #if defined(OS_POSIX) |
| 31 #include "ipc/ipc_platform_file_attachment_posix.h" | 31 #include "ipc/ipc_platform_file_attachment_posix.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 #if defined(OS_MACOSX) | 34 #if defined(OS_MACOSX) |
| 35 #include "ipc/mach_port_attachment_mac.h" | 35 #include "ipc/mach_port_attachment_mac.h" |
| 36 #endif | 36 #endif |
| 37 | 37 |
| 38 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 63 | 63 |
| 64 mojom::SerializedHandlePtr CreateSerializedHandle( | 64 mojom::SerializedHandlePtr CreateSerializedHandle( |
| 65 mojo::ScopedHandle handle, | 65 mojo::ScopedHandle handle, |
| 66 mojom::SerializedHandle::Type type) { | 66 mojom::SerializedHandle::Type type) { |
| 67 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New(); | 67 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New(); |
| 68 serialized_handle->the_handle = std::move(handle); | 68 serialized_handle->the_handle = std::move(handle); |
| 69 serialized_handle->type = type; | 69 serialized_handle->type = type; |
| 70 return serialized_handle; | 70 return serialized_handle; |
| 71 } | 71 } |
| 72 | 72 |
| 73 MojoResult WrapPlatformHandle(mojo::edk::ScopedPlatformHandle handle, | 73 MojoResult WrapPlatformHandle(base::PlatformFile handle, |
| 74 mojom::SerializedHandle::Type type, | 74 mojom::SerializedHandle::Type type, |
| 75 mojom::SerializedHandlePtr* serialized) { | 75 mojom::SerializedHandlePtr* serialized) { |
| 76 mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformFile(handle); |
| 77 if (!wrapped_handle.is_valid()) |
| 78 return MOJO_RESULT_UNKNOWN; |
| 79 |
| 80 *serialized = CreateSerializedHandle(std::move(wrapped_handle), type); |
| 81 return MOJO_RESULT_OK; |
| 82 } |
| 83 |
| 84 #if defined(OS_MACOSX) |
| 85 |
| 86 MojoResult WrapMachPort(mach_port_t mach_port, |
| 87 mojom::SerializedHandlePtr* serialized) { |
| 88 MojoPlatformHandle platform_handle = { |
| 89 sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT, |
| 90 static_cast<uint64_t>(mach_port) |
| 91 }; |
| 92 |
| 76 MojoHandle wrapped_handle; | 93 MojoHandle wrapped_handle; |
| 77 MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper( | 94 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle); |
| 78 std::move(handle), &wrapped_handle); | 95 if (result != MOJO_RESULT_OK) |
| 79 if (wrap_result != MOJO_RESULT_OK) | 96 return result; |
| 80 return wrap_result; | |
| 81 | 97 |
| 82 *serialized = CreateSerializedHandle( | 98 *serialized = CreateSerializedHandle( |
| 83 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)), type); | 99 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)), |
| 100 mojom::SerializedHandle::Type::MACH_PORT); |
| 84 return MOJO_RESULT_OK; | 101 return MOJO_RESULT_OK; |
| 85 } | 102 } |
| 86 | 103 |
| 104 #endif |
| 105 |
| 87 #if defined(OS_POSIX) | 106 #if defined(OS_POSIX) |
| 88 | 107 |
| 89 base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { | 108 base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { |
| 90 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile()) | 109 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile()) |
| 91 : base::ScopedFD(dup(attachment->file())); | 110 : base::ScopedFD(dup(attachment->file())); |
| 92 } | 111 } |
| 93 | 112 |
| 94 #endif | 113 #endif |
| 95 | 114 |
| 96 MojoResult WrapAttachmentImpl(MessageAttachment* attachment, | 115 MojoResult WrapAttachmentImpl(MessageAttachment* attachment, |
| 97 mojom::SerializedHandlePtr* serialized) { | 116 mojom::SerializedHandlePtr* serialized) { |
| 98 if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) { | 117 if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) { |
| 99 *serialized = CreateSerializedHandle( | 118 *serialized = CreateSerializedHandle( |
| 100 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(), | 119 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(), |
| 101 mojom::SerializedHandle::Type::MOJO_HANDLE); | 120 mojom::SerializedHandle::Type::MOJO_HANDLE); |
| 102 return MOJO_RESULT_OK; | 121 return MOJO_RESULT_OK; |
| 103 } | 122 } |
| 104 #if defined(OS_POSIX) | 123 #if defined(OS_POSIX) |
| 105 if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) { | 124 if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) { |
| 106 // We dup() the handles in IPC::Message to transmit. | 125 // We dup() the handles in IPC::Message to transmit. |
| 107 // IPC::MessageAttachmentSet has intricate lifecycle semantics | 126 // IPC::MessageAttachmentSet has intricate lifecycle semantics |
| 108 // of FDs, so just to dup()-and-own them is the safest option. | 127 // of FDs, so just to dup()-and-own them is the safest option. |
| 109 base::ScopedFD file = TakeOrDupFile( | 128 base::ScopedFD file = TakeOrDupFile( |
| 110 static_cast<IPC::internal::PlatformFileAttachment*>(attachment)); | 129 static_cast<IPC::internal::PlatformFileAttachment*>(attachment)); |
| 111 if (!file.is_valid()) { | 130 if (!file.is_valid()) { |
| 112 DPLOG(WARNING) << "Failed to dup FD to transmit."; | 131 DPLOG(WARNING) << "Failed to dup FD to transmit."; |
| 113 return MOJO_RESULT_UNKNOWN; | 132 return MOJO_RESULT_UNKNOWN; |
| 114 } | 133 } |
| 115 | 134 |
| 116 return WrapPlatformHandle(mojo::edk::ScopedPlatformHandle( | 135 return WrapPlatformHandle(file.release(), |
| 117 mojo::edk::PlatformHandle(file.release())), | |
| 118 mojom::SerializedHandle::Type::PLATFORM_FILE, | 136 mojom::SerializedHandle::Type::PLATFORM_FILE, |
| 119 serialized); | 137 serialized); |
| 120 } | 138 } |
| 121 #endif | 139 #endif |
| 122 #if defined(OS_MACOSX) | 140 #if defined(OS_MACOSX) |
| 123 DCHECK_EQ(attachment->GetType(), | 141 DCHECK_EQ(attachment->GetType(), |
| 124 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); | 142 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); |
| 125 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), | 143 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), |
| 126 BrokerableAttachment::MACH_PORT); | 144 BrokerableAttachment::MACH_PORT); |
| 127 internal::MachPortAttachmentMac& mach_port_attachment = | 145 internal::MachPortAttachmentMac& mach_port_attachment = |
| 128 static_cast<internal::MachPortAttachmentMac&>(*attachment); | 146 static_cast<internal::MachPortAttachmentMac&>(*attachment); |
| 129 MojoResult result = WrapPlatformHandle( | 147 MojoResult result = WrapMachPort(mach_port_attachment.get_mach_port(), |
| 130 mojo::edk::ScopedPlatformHandle( | 148 serialized); |
| 131 mojo::edk::PlatformHandle(mach_port_attachment.get_mach_port())), | |
| 132 mojom::SerializedHandle::Type::MACH_PORT, serialized); | |
| 133 mach_port_attachment.reset_mach_port_ownership(); | 149 mach_port_attachment.reset_mach_port_ownership(); |
| 134 return result; | 150 return result; |
| 135 #elif defined(OS_WIN) | 151 #elif defined(OS_WIN) |
| 136 DCHECK_EQ(attachment->GetType(), | 152 DCHECK_EQ(attachment->GetType(), |
| 137 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); | 153 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); |
| 138 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), | 154 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), |
| 139 BrokerableAttachment::WIN_HANDLE); | 155 BrokerableAttachment::WIN_HANDLE); |
| 140 internal::HandleAttachmentWin& handle_attachment = | 156 internal::HandleAttachmentWin& handle_attachment = |
| 141 static_cast<internal::HandleAttachmentWin&>(*attachment); | 157 static_cast<internal::HandleAttachmentWin&>(*attachment); |
| 142 MojoResult result = WrapPlatformHandle( | 158 MojoResult result = WrapPlatformHandle( |
| 143 mojo::edk::ScopedPlatformHandle( | 159 handle_attachment.get_handle(), |
| 144 mojo::edk::PlatformHandle(handle_attachment.get_handle())), | |
| 145 mojom::SerializedHandle::Type::WIN_HANDLE, serialized); | 160 mojom::SerializedHandle::Type::WIN_HANDLE, serialized); |
| 146 handle_attachment.reset_handle_ownership(); | 161 handle_attachment.reset_handle_ownership(); |
| 147 return result; | 162 return result; |
| 148 #else | 163 #else |
| 149 NOTREACHED(); | 164 NOTREACHED(); |
| 150 return MOJO_RESULT_UNKNOWN; | 165 return MOJO_RESULT_UNKNOWN; |
| 151 #endif // defined(OS_MACOSX) | 166 #endif // defined(OS_MACOSX) |
| 152 } | 167 } |
| 153 | 168 |
| 154 MojoResult WrapAttachment(MessageAttachment* attachment, | 169 MojoResult WrapAttachment(MessageAttachment* attachment, |
| 155 mojo::Array<mojom::SerializedHandlePtr>* handles) { | 170 mojo::Array<mojom::SerializedHandlePtr>* handles) { |
| 156 mojom::SerializedHandlePtr serialized_handle; | 171 mojom::SerializedHandlePtr serialized_handle; |
| 157 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle); | 172 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle); |
| 158 if (wrap_result != MOJO_RESULT_OK) { | 173 if (wrap_result != MOJO_RESULT_OK) { |
| 159 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result; | 174 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result; |
| 160 return wrap_result; | 175 return wrap_result; |
| 161 } | 176 } |
| 162 handles->push_back(std::move(serialized_handle)); | 177 handles->push_back(std::move(serialized_handle)); |
| 163 return MOJO_RESULT_OK; | 178 return MOJO_RESULT_OK; |
| 164 } | 179 } |
| 165 | 180 |
| 166 MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle, | 181 MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle, |
| 167 scoped_refptr<MessageAttachment>* attachment) { | 182 scoped_refptr<MessageAttachment>* attachment) { |
| 168 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) { | 183 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) { |
| 169 *attachment = | 184 *attachment = |
| 170 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle)); | 185 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle)); |
| 171 return MOJO_RESULT_OK; | 186 return MOJO_RESULT_OK; |
| 172 } | 187 } |
| 173 mojo::edk::ScopedPlatformHandle platform_handle; | 188 MojoPlatformHandle platform_handle = { sizeof(MojoPlatformHandle), 0, 0 }; |
| 174 MojoResult unwrap_result = mojo::edk::PassWrappedPlatformHandle( | 189 MojoResult unwrap_result = MojoUnwrapPlatformHandle( |
| 175 handle->the_handle.release().value(), &platform_handle); | 190 handle->the_handle.release().value(), &platform_handle); |
| 176 if (unwrap_result != MOJO_RESULT_OK) | 191 if (unwrap_result != MOJO_RESULT_OK) |
| 177 return unwrap_result; | 192 return unwrap_result; |
| 178 #if defined(OS_POSIX) | 193 #if defined(OS_POSIX) |
| 179 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE && | 194 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE) { |
| 180 platform_handle.get().type == mojo::edk::PlatformHandle::Type::POSIX) { | 195 base::PlatformFile file = base::kInvalidPlatformFile; |
| 181 *attachment = new internal::PlatformFileAttachment( | 196 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR) |
| 182 platform_handle.release().handle); | 197 file = static_cast<base::PlatformFile>(platform_handle.value); |
| 198 *attachment = new internal::PlatformFileAttachment(file); |
| 183 return MOJO_RESULT_OK; | 199 return MOJO_RESULT_OK; |
| 184 } | 200 } |
| 185 #endif // defined(OS_POSIX) | 201 #endif // defined(OS_POSIX) |
| 186 #if defined(OS_MACOSX) | 202 #if defined(OS_MACOSX) |
| 187 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT && | 203 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT) { |
| 188 platform_handle.get().type == mojo::edk::PlatformHandle::Type::MACH) { | 204 mach_port_t mach_port = MACH_PORT_NULL; |
| 205 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT) |
| 206 mach_port = static_cast<mach_port_t>(platform_handle.value); |
| 189 *attachment = new internal::MachPortAttachmentMac( | 207 *attachment = new internal::MachPortAttachmentMac( |
| 190 platform_handle.release().port, | 208 mach_port, internal::MachPortAttachmentMac::FROM_WIRE); |
| 191 internal::MachPortAttachmentMac::FROM_WIRE); | |
| 192 return MOJO_RESULT_OK; | 209 return MOJO_RESULT_OK; |
| 193 } | 210 } |
| 194 #endif // defined(OS_MACOSX) | 211 #endif // defined(OS_MACOSX) |
| 195 #if defined(OS_WIN) | 212 #if defined(OS_WIN) |
| 196 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) { | 213 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) { |
| 214 base::PlatformFile handle = base::kInvalidPlatformFile; |
| 215 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE) |
| 216 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value); |
| 197 *attachment = new internal::HandleAttachmentWin( | 217 *attachment = new internal::HandleAttachmentWin( |
| 198 platform_handle.release().handle, | 218 handle, internal::HandleAttachmentWin::FROM_WIRE); |
| 199 internal::HandleAttachmentWin::FROM_WIRE); | |
| 200 return MOJO_RESULT_OK; | 219 return MOJO_RESULT_OK; |
| 201 } | 220 } |
| 202 #endif // defined(OS_WIN) | 221 #endif // defined(OS_WIN) |
| 203 NOTREACHED(); | 222 NOTREACHED(); |
| 204 return MOJO_RESULT_UNKNOWN; | 223 return MOJO_RESULT_UNKNOWN; |
| 205 } | 224 } |
| 206 | 225 |
| 207 } // namespace | 226 } // namespace |
| 208 | 227 |
| 209 //------------------------------------------------------------------------------ | 228 //------------------------------------------------------------------------------ |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 DCHECK(ok); | 463 DCHECK(ok); |
| 445 if (!ok) { | 464 if (!ok) { |
| 446 LOG(ERROR) << "Failed to add new Mojo handle."; | 465 LOG(ERROR) << "Failed to add new Mojo handle."; |
| 447 return MOJO_RESULT_UNKNOWN; | 466 return MOJO_RESULT_UNKNOWN; |
| 448 } | 467 } |
| 449 } | 468 } |
| 450 return MOJO_RESULT_OK; | 469 return MOJO_RESULT_OK; |
| 451 } | 470 } |
| 452 | 471 |
| 453 } // namespace IPC | 472 } // namespace IPC |
| OLD | NEW |