blob: 1dc475da37204b298226e7500c7f1b674a74a6e3 [file] [log] [blame]
[email protected]5c41e6e12012-03-17 02:20:461// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d27893f62010-07-03 05:47:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4734d0b2011-12-03 07:10:445#include "content/common/child_process_host_impl.h"
[email protected]d27893f62010-07-03 05:47:426
[email protected]4306c3792011-12-02 01:57:537#include <limits>
8
[email protected]3cb7cc9532014-01-08 22:55:519#include "base/atomic_sequence_num.h"
[email protected]d27893f62010-07-03 05:47:4210#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
ssid1050d802015-07-28 20:28:1412#include "base/hash.h"
[email protected]8c40f322011-08-24 03:33:3613#include "base/logging.h"
erikchena91d05132016-03-21 23:19:4014#include "base/message_loop/message_loop.h"
[email protected]835d7c82010-10-14 04:38:3815#include "base/metrics/histogram.h"
reveman22dd9292014-10-13 20:52:0516#include "base/numerics/safe_math.h"
[email protected]d27893f62010-07-03 05:47:4217#include "base/path_service.h"
[email protected]71ed8e022013-07-25 14:39:5718#include "base/process/process_metrics.h"
[email protected]4306c3792011-12-02 01:57:5319#include "base/rand_util.h"
[email protected]30fe1f92013-06-12 16:34:3420#include "base/strings/stringprintf.h"
erikchen5708aae2015-09-14 17:45:1221#include "base/synchronization/lock.h"
[email protected]a5f28b42011-01-17 10:30:1322#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
avia9aa7a82015-12-25 03:06:3123#include "build/build_config.h"
[email protected]ff47b2962011-03-07 23:51:4924#include "content/common/child_process_messages.h"
[email protected]4cb43102011-12-02 20:24:4925#include "content/public/common/child_process_host_delegate.h"
[email protected]5d921d4c2011-10-21 22:26:1426#include "content/public/common/content_paths.h"
[email protected]c08950d22011-10-13 22:20:2927#include "content/public/common/content_switches.h"
penghuang346a46f92016-03-31 21:37:5228#include "gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h"
erikchen87397e02015-10-10 01:10:2429#include "ipc/attachment_broker.h"
erikchen9a199772015-11-03 19:47:2830#include "ipc/attachment_broker_privileged.h"
[email protected]5c41e6e12012-03-17 02:20:4631#include "ipc/ipc_channel.h"
amistryd4aa70d2016-06-23 07:52:3732#include "ipc/ipc_channel_mojo.h"
[email protected]a83d42292010-08-17 22:51:1033#include "ipc/ipc_logging.h"
[email protected]74122042014-04-25 00:07:3034#include "ipc/message_filter.h"
amistryab52b0c2016-06-07 04:22:5735#include "mojo/edk/embedder/embedder.h"
[email protected]d27893f62010-07-03 05:47:4236
37#if defined(OS_LINUX)
38#include "base/linux_util.h"
[email protected]e35c9a82011-12-01 18:48:4139#elif defined(OS_WIN)
40#include "content/common/font_cache_dispatcher_win.h"
[email protected]d27893f62010-07-03 05:47:4241#endif // OS_LINUX
42
[email protected]8c40f322011-08-24 03:33:3643namespace {
44
[email protected]3cb7cc9532014-01-08 22:55:5145// Global atomic to generate child process unique IDs.
46base::StaticAtomicSequenceNumber g_unique_id;
[email protected]8c40f322011-08-24 03:33:3647
48} // namespace
[email protected]8c40f322011-08-24 03:33:3649
[email protected]4734d0b2011-12-03 07:10:4450namespace content {
[email protected]d27893f62010-07-03 05:47:4251
[email protected]3cb7cc9532014-01-08 22:55:5152int ChildProcessHost::kInvalidUniqueID = -1;
[email protected]d7c7c98a2012-07-12 21:27:4453
avia9aa7a82015-12-25 03:06:3154uint64_t ChildProcessHost::kBrowserTracingProcessId =
55 std::numeric_limits<uint64_t>::max();
ssid1050d802015-07-28 20:28:1456
[email protected]4734d0b2011-12-03 07:10:4457// static
58ChildProcessHost* ChildProcessHost::Create(ChildProcessHostDelegate* delegate) {
59 return new ChildProcessHostImpl(delegate);
[email protected]d27893f62010-07-03 05:47:4260}
61
62// static
[email protected]a7329162013-02-07 19:21:4863base::FilePath ChildProcessHost::GetChildPath(int flags) {
64 base::FilePath child_path;
[email protected]d27893f62010-07-03 05:47:4265
[email protected]479278702014-08-11 20:32:0966 child_path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
[email protected]d27893f62010-07-03 05:47:4267 switches::kBrowserSubprocessPath);
[email protected]d27893f62010-07-03 05:47:4268
[email protected]d27893f62010-07-03 05:47:4269#if defined(OS_LINUX)
70 // Use /proc/self/exe rather than our known binary path so updates
71 // can't swap out the binary from underneath us.
[email protected]a5f28b42011-01-17 10:30:1372 // When running under Valgrind, forking /proc/self/exe ends up forking the
73 // Valgrind executable, which then crashes. However, it's almost safe to
74 // assume that the updates won't happen while testing with Valgrind tools.
[email protected]bfd47482011-08-24 13:57:2675 if (child_path.empty() && flags & CHILD_ALLOW_SELF && !RunningOnValgrind())
[email protected]a7329162013-02-07 19:21:4876 child_path = base::FilePath(base::kProcSelfExe);
[email protected]d27893f62010-07-03 05:47:4277#endif
78
79 // On most platforms, the child executable is the same as the current
80 // executable.
[email protected]bfd47482011-08-24 13:57:2681 if (child_path.empty())
[email protected]dcc72db2013-01-02 00:44:1882 PathService::Get(CHILD_PROCESS_EXE, &child_path);
[email protected]d27893f62010-07-03 05:47:4283 return child_path;
84}
85
[email protected]4734d0b2011-12-03 07:10:4486ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
87 : delegate_(delegate),
[email protected]4734d0b2011-12-03 07:10:4488 opening_channel_(false) {
89#if defined(OS_WIN)
90 AddFilter(new FontCacheDispatcher());
91#endif
erikchen9a199772015-11-03 19:47:2892
93#if USE_ATTACHMENT_BROKER
jame1f453c2016-03-21 15:51:3494#if defined(OS_MACOSX)
erikchen9a199772015-11-03 19:47:2895 // On Mac, the privileged AttachmentBroker needs a reference to the Mach port
96 // Provider, which is only available in the chrome/ module. The attachment
97 // broker must already be created.
98 DCHECK(IPC::AttachmentBroker::GetGlobal());
99#else
100 // Construct the privileged attachment broker early in the life cycle of a
101 // child process.
102 IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
jame1f453c2016-03-21 15:51:34103#endif // defined(OS_MACOSX)
erikchen9a199772015-11-03 19:47:28104#endif // USE_ATTACHMENT_BROKER
[email protected]4734d0b2011-12-03 07:10:44105}
106
107ChildProcessHostImpl::~ChildProcessHostImpl() {
chrishae9950382015-12-07 20:51:56108 // If a channel was never created than it wasn't registered and the filters
109 // weren't notified. For the sake of symmetry don't call the matching teardown
110 // functions. This is analogous to how RenderProcessHostImpl handles things.
111 if (!channel_)
112 return;
113
erikchen1bfccba2015-07-31 01:09:27114#if USE_ATTACHMENT_BROKER
erikchend8a3d9022015-10-22 20:02:02115 IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
116 channel_.get());
erikchen1bfccba2015-07-31 01:09:27117#endif
[email protected]4734d0b2011-12-03 07:10:44118 for (size_t i = 0; i < filters_.size(); ++i) {
119 filters_[i]->OnChannelClosing();
120 filters_[i]->OnFilterRemoved();
121 }
[email protected]4734d0b2011-12-03 07:10:44122}
123
[email protected]74122042014-04-25 00:07:30124void ChildProcessHostImpl::AddFilter(IPC::MessageFilter* filter) {
[email protected]4734d0b2011-12-03 07:10:44125 filters_.push_back(filter);
126
[email protected]59383c782013-04-17 16:43:27127 if (channel_)
[email protected]4734d0b2011-12-03 07:10:44128 filter->OnFilterAdded(channel_.get());
129}
130
131void ChildProcessHostImpl::ForceShutdown() {
[email protected]bdae9812011-10-15 00:33:03132 Send(new ChildProcessMsg_Shutdown());
133}
[email protected]91443fc2010-07-14 05:08:46134
amistryab52b0c2016-06-07 04:22:57135std::string ChildProcessHostImpl::CreateChannelMojo(
136 const std::string& child_token) {
137 DCHECK(channel_id_.empty());
138 channel_id_ = mojo::edk::GenerateRandomToken();
139 mojo::ScopedMessagePipeHandle host_handle =
140 mojo::edk::CreateParentMessagePipe(channel_id_, child_token);
141 channel_ = IPC::ChannelMojo::Create(std::move(host_handle),
142 IPC::Channel::MODE_SERVER, this);
143 if (!channel_ || !InitChannel())
144 return std::string();
145
146 return channel_id_;
147}
148
[email protected]4734d0b2011-12-03 07:10:44149std::string ChildProcessHostImpl::CreateChannel() {
amistryab52b0c2016-06-07 04:22:57150 DCHECK(channel_id_.empty());
[email protected]5c41e6e12012-03-17 02:20:46151 channel_id_ = IPC::Channel::GenerateVerifiedChannelID(std::string());
erikchen5708aae2015-09-14 17:45:12152 channel_ = IPC::Channel::CreateServer(channel_id_, this);
amistryab52b0c2016-06-07 04:22:57153 if (!channel_ || !InitChannel())
154 return std::string();
155
156 return channel_id_;
157}
158
159bool ChildProcessHostImpl::InitChannel() {
erikchen1bfccba2015-07-31 01:09:27160#if USE_ATTACHMENT_BROKER
erikchend8a3d9022015-10-22 20:02:02161 IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
erikchena91d05132016-03-21 23:19:40162 channel_.get(), base::MessageLoopForIO::current()->task_runner());
erikchen1bfccba2015-07-31 01:09:27163#endif
erikchen90971902016-04-25 23:45:31164 if (!channel_->Connect()) {
165#if USE_ATTACHMENT_BROKER
166 IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
167 channel_.get());
168#endif
amistryab52b0c2016-06-07 04:22:57169 return false;
erikchen90971902016-04-25 23:45:31170 }
[email protected]d27893f62010-07-03 05:47:42171
[email protected]8e2b6472010-12-15 22:19:48172 for (size_t i = 0; i < filters_.size(); ++i)
173 filters_[i]->OnFilterAdded(channel_.get());
174
[email protected]91443fc2010-07-14 05:08:46175 // Make sure these messages get sent first.
176#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]8e8bb6d2010-12-13 08:18:55177 bool enabled = IPC::Logging::GetInstance()->Enabled();
[email protected]ff47b2962011-03-07 23:51:49178 Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled));
[email protected]91443fc2010-07-14 05:08:46179#endif
180
[email protected]d27893f62010-07-03 05:47:42181 opening_channel_ = true;
182
amistryab52b0c2016-06-07 04:22:57183 return true;
[email protected]d27893f62010-07-03 05:47:42184}
185
[email protected]4734d0b2011-12-03 07:10:44186bool ChildProcessHostImpl::IsChannelOpening() {
187 return opening_channel_;
188}
189
190#if defined(OS_POSIX)
morritaa409ccc2014-10-20 23:53:25191base::ScopedFD ChildProcessHostImpl::TakeClientFileDescriptor() {
[email protected]4734d0b2011-12-03 07:10:44192 return channel_->TakeClientFileDescriptor();
193}
194#endif
195
196bool ChildProcessHostImpl::Send(IPC::Message* message) {
[email protected]59383c782013-04-17 16:43:27197 if (!channel_) {
[email protected]8e2b6472010-12-15 22:19:48198 delete message;
[email protected]d27893f62010-07-03 05:47:42199 return false;
200 }
[email protected]8e2b6472010-12-15 22:19:48201 return channel_->Send(message);
[email protected]d27893f62010-07-03 05:47:42202}
203
[email protected]4734d0b2011-12-03 07:10:44204void ChildProcessHostImpl::AllocateSharedMemory(
[email protected]3f892832013-01-11 03:23:59205 size_t buffer_size, base::ProcessHandle child_process_handle,
[email protected]bdae9812011-10-15 00:33:03206 base::SharedMemoryHandle* shared_memory_handle) {
207 base::SharedMemory shared_buf;
[email protected]e607e2c12013-09-13 09:46:58208 if (!shared_buf.CreateAnonymous(buffer_size)) {
[email protected]bdae9812011-10-15 00:33:03209 *shared_memory_handle = base::SharedMemory::NULLHandle();
[email protected]e607e2c12013-09-13 09:46:58210 NOTREACHED() << "Cannot create shared memory buffer";
[email protected]bdae9812011-10-15 00:33:03211 return;
212 }
213 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle);
214}
215
[email protected]4734d0b2011-12-03 07:10:44216int ChildProcessHostImpl::GenerateChildProcessUniqueId() {
[email protected]4306c3792011-12-02 01:57:53217 // This function must be threadsafe.
[email protected]d7c7c98a2012-07-12 21:27:44218 //
[email protected]3cb7cc9532014-01-08 22:55:51219 // Historically, this function returned ids started with 1, so in several
220 // places in the code a value of 0 (rather than kInvalidUniqueID) was used as
221 // an invalid value. So we retain those semantics.
222 int id = g_unique_id.GetNext() + 1;
[email protected]d7c7c98a2012-07-12 21:27:44223
[email protected]3cb7cc9532014-01-08 22:55:51224 CHECK_NE(0, id);
225 CHECK_NE(kInvalidUniqueID, id);
[email protected]d7c7c98a2012-07-12 21:27:44226
227 return id;
[email protected]4306c3792011-12-02 01:57:53228}
229
avia9aa7a82015-12-25 03:06:31230uint64_t ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
ssid1050d802015-07-28 20:28:14231 int child_process_id) {
232 // In single process mode, all the children are hosted in the same process,
233 // therefore the generated memory dump guids should not be conditioned by the
234 // child process id. The clients need not be aware of SPM and the conversion
235 // takes care of the SPM special case while translating child process ids to
236 // tracing process ids.
237 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
238 switches::kSingleProcess))
239 return ChildProcessHost::kBrowserTracingProcessId;
240
241 // The hash value is incremented so that the tracing id is never equal to
242 // MemoryDumpManager::kInvalidTracingProcessId.
avia9aa7a82015-12-25 03:06:31243 return static_cast<uint64_t>(
ssid1050d802015-07-28 20:28:14244 base::Hash(reinterpret_cast<const char*>(&child_process_id),
245 sizeof(child_process_id))) +
246 1;
247}
248
[email protected]4734d0b2011-12-03 07:10:44249bool ChildProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
[email protected]d27893f62010-07-03 05:47:42250#ifdef IPC_MESSAGE_LOG_ENABLED
[email protected]8e8bb6d2010-12-13 08:18:55251 IPC::Logging* logger = IPC::Logging::GetInstance();
[email protected]d27893f62010-07-03 05:47:42252 if (msg.type() == IPC_LOGGING_ID) {
253 logger->OnReceivedLoggingMessage(msg);
[email protected]a95986a82010-12-24 06:19:28254 return true;
[email protected]d27893f62010-07-03 05:47:42255 }
256
257 if (logger->Enabled())
258 logger->OnPreDispatchMessage(msg);
259#endif
260
[email protected]8e2b6472010-12-15 22:19:48261 bool handled = false;
[email protected]4cb43102011-12-02 20:24:49262 for (size_t i = 0; i < filters_.size(); ++i) {
263 if (filters_[i]->OnMessageReceived(msg)) {
[email protected]8e2b6472010-12-15 22:19:48264 handled = true;
265 break;
[email protected]d27893f62010-07-03 05:47:42266 }
267 }
268
[email protected]bdae9812011-10-15 00:33:03269 if (!handled) {
[email protected]e5257432010-12-21 01:18:37270 handled = true;
[email protected]4734d0b2011-12-03 07:10:44271 IPC_BEGIN_MESSAGE_MAP(ChildProcessHostImpl, msg)
[email protected]bdae9812011-10-15 00:33:03272 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
273 OnShutdownRequest)
avief875b522015-09-11 20:58:51274 // NB: The SyncAllocateSharedMemory, SyncAllocateGpuMemoryBuffer, and
275 // DeletedGpuMemoryBuffer IPCs are handled here for non-renderer child
276 // processes. For renderer processes, they are handled in
277 // RenderMessageFilter.
[email protected]bdae9812011-10-15 00:33:03278 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
279 OnAllocateSharedMemory)
jam813663162015-03-26 16:46:29280 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
281 OnAllocateGpuMemoryBuffer)
reveman22dd9292014-10-13 20:52:05282 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedGpuMemoryBuffer,
283 OnDeletedGpuMemoryBuffer)
[email protected]bdae9812011-10-15 00:33:03284 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]4cb43102011-12-02 20:24:49285 IPC_END_MESSAGE_MAP()
[email protected]e5257432010-12-21 01:18:37286
[email protected]bdae9812011-10-15 00:33:03287 if (!handled)
[email protected]4cb43102011-12-02 20:24:49288 handled = delegate_->OnMessageReceived(msg);
[email protected]bdae9812011-10-15 00:33:03289 }
[email protected]8e2b6472010-12-15 22:19:48290
[email protected]d27893f62010-07-03 05:47:42291#ifdef IPC_MESSAGE_LOG_ENABLED
292 if (logger->Enabled())
[email protected]4cb43102011-12-02 20:24:49293 logger->OnPostDispatchMessage(msg, channel_id_);
[email protected]d27893f62010-07-03 05:47:42294#endif
[email protected]a95986a82010-12-24 06:19:28295 return handled;
[email protected]d27893f62010-07-03 05:47:42296}
297
avia9aa7a82015-12-25 03:06:31298void ChildProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
rvargas5779b382014-11-18 20:44:11299 if (!peer_process_.IsValid()) {
rvargas1c376a82015-03-16 23:03:52300 peer_process_ = base::Process::OpenWithExtraPrivileges(peer_pid);
rvargas747ff242015-01-17 02:46:47301 if (!peer_process_.IsValid())
302 peer_process_ = delegate_->GetProcess().Duplicate();
rvargas5779b382014-11-18 20:44:11303 DCHECK(peer_process_.IsValid());
[email protected]bdae9812011-10-15 00:33:03304 }
[email protected]4cb43102011-12-02 20:24:49305 opening_channel_ = false;
306 delegate_->OnChannelConnected(peer_pid);
307 for (size_t i = 0; i < filters_.size(); ++i)
308 filters_[i]->OnChannelConnected(peer_pid);
[email protected]d27893f62010-07-03 05:47:42309}
310
[email protected]4734d0b2011-12-03 07:10:44311void ChildProcessHostImpl::OnChannelError() {
[email protected]4cb43102011-12-02 20:24:49312 opening_channel_ = false;
313 delegate_->OnChannelError();
[email protected]d27893f62010-07-03 05:47:42314
[email protected]4cb43102011-12-02 20:24:49315 for (size_t i = 0; i < filters_.size(); ++i)
316 filters_[i]->OnChannelError();
[email protected]8e2b6472010-12-15 22:19:48317
[email protected]d27893f62010-07-03 05:47:42318 // This will delete host_, which will also destroy this!
[email protected]4cb43102011-12-02 20:24:49319 delegate_->OnChildDisconnected();
[email protected]d27893f62010-07-03 05:47:42320}
321
[email protected]ef2f6ba2014-05-15 23:06:07322void ChildProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) {
323 delegate_->OnBadMessageReceived(message);
324}
325
[email protected]4734d0b2011-12-03 07:10:44326void ChildProcessHostImpl::OnAllocateSharedMemory(
avia9aa7a82015-12-25 03:06:31327 uint32_t buffer_size,
[email protected]bdae9812011-10-15 00:33:03328 base::SharedMemoryHandle* handle) {
rvargas5779b382014-11-18 20:44:11329 AllocateSharedMemory(buffer_size, peer_process_.Handle(), handle);
[email protected]bdae9812011-10-15 00:33:03330}
331
[email protected]4734d0b2011-12-03 07:10:44332void ChildProcessHostImpl::OnShutdownRequest() {
[email protected]4cb43102011-12-02 20:24:49333 if (delegate_->CanShutdown())
334 Send(new ChildProcessMsg_Shutdown());
[email protected]d27893f62010-07-03 05:47:42335}
[email protected]4734d0b2011-12-03 07:10:44336
[email protected]bc10f462013-10-22 23:13:09337void ChildProcessHostImpl::OnAllocateGpuMemoryBuffer(
ericrkc9984ebe2015-08-17 14:22:37338 gfx::GpuMemoryBufferId id,
avia9aa7a82015-12-25 03:06:31339 uint32_t width,
340 uint32_t height,
spangfcf5fab42015-08-04 19:25:35341 gfx::BufferFormat format,
342 gfx::BufferUsage usage,
jam813663162015-03-26 16:46:29343 gfx::GpuMemoryBufferHandle* handle) {
reveman22dd9292014-10-13 20:52:05344 // TODO(reveman): Add support for other types of GpuMemoryBuffers.
revemanbc2de2b2014-11-17 03:21:32345
346 // AllocateForChildProcess() will check if |width| and |height| are valid
347 // and handle failure in a controlled way when not. We just need to make
reveman485728ba2015-10-23 18:43:22348 // sure |usage| is supported here.
penghuang346a46f92016-03-31 21:37:52349 if (gpu::GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage)) {
350 *handle = gpu::GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
ericrkc9984ebe2015-08-17 14:22:37351 id, gfx::Size(width, height), format, peer_process_.Handle());
reveman22dd9292014-10-13 20:52:05352 }
reveman22dd9292014-10-13 20:52:05353}
354
355void ChildProcessHostImpl::OnDeletedGpuMemoryBuffer(
reveman510a6e02014-11-05 00:59:18356 gfx::GpuMemoryBufferId id,
dyenac45ecf2015-11-06 17:40:56357 const gpu::SyncToken& sync_token) {
reveman22dd9292014-10-13 20:52:05358 // Note: Nothing to do here as ownership of shared memory backed
359 // GpuMemoryBuffers is passed with IPC.
360}
361
[email protected]4734d0b2011-12-03 07:10:44362} // namespace content