[email protected] | a3b85d85 | 2012-01-27 02:04:48 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 5 | #include "content/browser/utility_process_host_impl.h" |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 6 | |
danakj | e3de838f | 2015-12-03 01:49:40 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
jdduke | b7ce1e3 | 2015-03-18 00:14:17 | [diff] [blame] | 9 | #include "base/base_switches.h" |
[email protected] | 037edb5 | 2011-11-15 21:14:06 | [diff] [blame] | 10 | #include "base/bind.h" |
| 11 | #include "base/bind_helpers.h" |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 12 | #include "base/command_line.h" |
rickyz | 5010931 | 2015-11-11 00:37:08 | [diff] [blame] | 13 | #include "base/files/file_path.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 14 | #include "base/lazy_instance.h" |
avi | b734894 | 2015-12-25 20:57:10 | [diff] [blame] | 15 | #include "base/macros.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 16 | #include "base/message_loop/message_loop.h" |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 17 | #include "base/process/process_handle.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 18 | #include "base/run_loop.h" |
[email protected] | fb44196 | 2013-05-08 05:35:24 | [diff] [blame] | 19 | #include "base/sequenced_task_runner.h" |
[email protected] | 74ebfb1 | 2013-06-07 20:48:00 | [diff] [blame] | 20 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 21 | #include "base/synchronization/lock.h" |
| 22 | #include "base/synchronization/waitable_event.h" |
avi | b734894 | 2015-12-25 20:57:10 | [diff] [blame] | 23 | #include "build/build_config.h" |
[email protected] | 4c01d499 | 2012-01-23 23:33:01 | [diff] [blame] | 24 | #include "content/browser/browser_child_process_host_impl.h" |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 25 | #include "content/browser/mojo/mojo_application_host.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 26 | #include "content/browser/renderer_host/render_process_host_impl.h" |
[email protected] | 4734d0b | 2011-12-03 07:10:44 | [diff] [blame] | 27 | #include "content/common/child_process_host_impl.h" |
morrita | c6238ab | 2015-03-18 01:48:29 | [diff] [blame] | 28 | #include "content/common/in_process_child_thread_params.h" |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 29 | #include "content/common/utility_messages.h" |
[email protected] | b7b6387 | 2013-01-03 02:41:19 | [diff] [blame] | 30 | #include "content/public/browser/browser_thread.h" |
[email protected] | 87f3c08 | 2011-10-19 18:07:44 | [diff] [blame] | 31 | #include "content/public/browser/content_browser_client.h" |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 32 | #include "content/public/browser/utility_process_host_client.h" |
[email protected] | c08950d2 | 2011-10-13 22:20:29 | [diff] [blame] | 33 | #include "content/public/common/content_switches.h" |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 34 | #include "content/public/common/process_type.h" |
wfh | 182da09c | 2015-06-24 19:23:03 | [diff] [blame] | 35 | #include "content/public/common/sandbox_type.h" |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 36 | #include "content/public/common/sandboxed_process_launcher_delegate.h" |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 37 | #include "ipc/ipc_switches.h" |
| 38 | #include "ui/base/ui_base_switches.h" |
| 39 | |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 40 | #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 41 | #include "content/public/browser/zygote_handle_linux.h" |
| 42 | #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 43 | |
rickyz | 5010931 | 2015-11-11 00:37:08 | [diff] [blame] | 44 | #if defined(OS_WIN) |
| 45 | #include "sandbox/win/src/sandbox_policy.h" |
| 46 | #include "sandbox/win/src/sandbox_types.h" |
| 47 | #endif |
| 48 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 49 | namespace content { |
| 50 | |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 51 | #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 52 | namespace { |
| 53 | ZygoteHandle g_utility_zygote; |
| 54 | } // namespace |
| 55 | #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 56 | |
[email protected] | 34f4868 | 2013-03-20 00:30:18 | [diff] [blame] | 57 | // NOTE: changes to this class need to be reviewed by the security team. |
| 58 | class UtilitySandboxedProcessLauncherDelegate |
| 59 | : public SandboxedProcessLauncherDelegate { |
| 60 | public: |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 61 | UtilitySandboxedProcessLauncherDelegate(const base::FilePath& exposed_dir, |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 62 | bool launch_elevated, |
| 63 | bool no_sandbox, |
amistry | 5f70aa5e | 2015-02-25 00:46:40 | [diff] [blame] | 64 | const base::EnvironmentMap& env, |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 65 | ChildProcessHost* host) |
| 66 | : exposed_dir_(exposed_dir), |
| 67 | #if defined(OS_WIN) |
| 68 | launch_elevated_(launch_elevated) |
| 69 | #elif defined(OS_POSIX) |
| 70 | env_(env), |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 71 | #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 72 | no_sandbox_(no_sandbox), |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 73 | #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 74 | ipc_fd_(host->TakeClientFileDescriptor()) |
| 75 | #endif // OS_WIN |
| 76 | {} |
| 77 | |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 78 | ~UtilitySandboxedProcessLauncherDelegate() override {} |
[email protected] | 34f4868 | 2013-03-20 00:30:18 | [diff] [blame] | 79 | |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 80 | #if defined(OS_WIN) |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 81 | bool ShouldLaunchElevated() override { return launch_elevated_; } |
rickyz | 5010931 | 2015-11-11 00:37:08 | [diff] [blame] | 82 | |
| 83 | bool PreSpawnTarget(sandbox::TargetPolicy* policy) override { |
| 84 | if (exposed_dir_.empty()) |
| 85 | return true; |
| 86 | |
| 87 | sandbox::ResultCode result; |
| 88 | result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, |
| 89 | sandbox::TargetPolicy::FILES_ALLOW_ANY, |
| 90 | exposed_dir_.value().c_str()); |
| 91 | if (result != sandbox::SBOX_ALL_OK) |
| 92 | return false; |
| 93 | |
| 94 | base::FilePath exposed_files = exposed_dir_.AppendASCII("*"); |
| 95 | result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, |
| 96 | sandbox::TargetPolicy::FILES_ALLOW_ANY, |
| 97 | exposed_files.value().c_str()); |
| 98 | return result == sandbox::SBOX_ALL_OK; |
[email protected] | 34f4868 | 2013-03-20 00:30:18 | [diff] [blame] | 99 | } |
rickyz | 5010931 | 2015-11-11 00:37:08 | [diff] [blame] | 100 | |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 101 | #elif defined(OS_POSIX) |
[email protected] | 34f4868 | 2013-03-20 00:30:18 | [diff] [blame] | 102 | |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 103 | #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 104 | ZygoteHandle* GetZygote() override { |
| 105 | if (no_sandbox_ || !exposed_dir_.empty()) |
| 106 | return nullptr; |
kerrnel | 94807ee | 2016-02-01 18:57:28 | [diff] [blame] | 107 | return GetGenericZygote(); |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 108 | } |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 109 | #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 110 | base::EnvironmentMap GetEnvironment() override { return env_; } |
danakj | e3de838f | 2015-12-03 01:49:40 | [diff] [blame] | 111 | base::ScopedFD TakeIpcFd() override { return std::move(ipc_fd_); } |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 112 | #endif // OS_WIN |
| 113 | |
wfh | 182da09c | 2015-06-24 19:23:03 | [diff] [blame] | 114 | SandboxType GetSandboxType() override { |
| 115 | return SANDBOX_TYPE_UTILITY; |
| 116 | } |
| 117 | |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 118 | private: |
amistry | 5f70aa5e | 2015-02-25 00:46:40 | [diff] [blame] | 119 | base::FilePath exposed_dir_; |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 120 | |
| 121 | #if defined(OS_WIN) |
| 122 | bool launch_elevated_; |
| 123 | #elif defined(OS_POSIX) |
| 124 | base::EnvironmentMap env_; |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 125 | #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 126 | bool no_sandbox_; |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 127 | #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) |
morrita | a409ccc | 2014-10-20 23:53:25 | [diff] [blame] | 128 | base::ScopedFD ipc_fd_; |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 129 | #endif // OS_WIN |
[email protected] | 34f4868 | 2013-03-20 00:30:18 | [diff] [blame] | 130 | }; |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 131 | |
[email protected] | d7a2d89 | 2013-08-16 07:45:36 | [diff] [blame] | 132 | UtilityMainThreadFactoryFunction g_utility_main_thread_factory = NULL; |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 133 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 134 | UtilityProcessHost* UtilityProcessHost::Create( |
dcheng | d3c6060 | 2014-09-03 17:14:37 | [diff] [blame] | 135 | const scoped_refptr<UtilityProcessHostClient>& client, |
| 136 | const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) { |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 137 | return new UtilityProcessHostImpl(client, client_task_runner); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 138 | } |
| 139 | |
[email protected] | 683f427 | 2014-04-17 20:42:18 | [diff] [blame] | 140 | void UtilityProcessHostImpl::RegisterUtilityMainThreadFactory( |
[email protected] | d7a2d89 | 2013-08-16 07:45:36 | [diff] [blame] | 141 | UtilityMainThreadFactoryFunction create) { |
| 142 | g_utility_main_thread_factory = create; |
| 143 | } |
| 144 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 145 | UtilityProcessHostImpl::UtilityProcessHostImpl( |
dcheng | d3c6060 | 2014-09-03 17:14:37 | [diff] [blame] | 146 | const scoped_refptr<UtilityProcessHostClient>& client, |
| 147 | const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 148 | : client_(client), |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 149 | client_task_runner_(client_task_runner), |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 150 | is_batch_mode_(false), |
[email protected] | 4912595 | 2011-09-27 18:05:15 | [diff] [blame] | 151 | no_sandbox_(false), |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 152 | run_elevated_(false), |
[email protected] | 4912595 | 2011-09-27 18:05:15 | [diff] [blame] | 153 | #if defined(OS_LINUX) |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 154 | child_flags_(ChildProcessHost::CHILD_ALLOW_SELF), |
[email protected] | 4912595 | 2011-09-27 18:05:15 | [diff] [blame] | 155 | #else |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 156 | child_flags_(ChildProcessHost::CHILD_NORMAL), |
[email protected] | 4912595 | 2011-09-27 18:05:15 | [diff] [blame] | 157 | #endif |
amistry | cd95c25 | 2015-03-20 02:07:04 | [diff] [blame] | 158 | started_(false), |
asargent | f766aa7 | 2015-08-24 18:05:49 | [diff] [blame] | 159 | name_(base::ASCIIToUTF16("utility process")), |
| 160 | weak_ptr_factory_(this) { |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 161 | } |
| 162 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 163 | UtilityProcessHostImpl::~UtilityProcessHostImpl() { |
mostynb | 042582e | 2015-03-16 22:13:40 | [diff] [blame] | 164 | DCHECK_CURRENTLY_ON(BrowserThread::IO); |
[email protected] | 809d34b | 2013-07-20 11:51:53 | [diff] [blame] | 165 | if (is_batch_mode_) |
| 166 | EndBatchMode(); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 167 | } |
| 168 | |
asargent | f766aa7 | 2015-08-24 18:05:49 | [diff] [blame] | 169 | base::WeakPtr<UtilityProcessHost> UtilityProcessHostImpl::AsWeakPtr() { |
| 170 | return weak_ptr_factory_.GetWeakPtr(); |
| 171 | } |
| 172 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 173 | bool UtilityProcessHostImpl::Send(IPC::Message* message) { |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 174 | if (!StartProcess()) |
| 175 | return false; |
| 176 | |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 177 | return process_->Send(message); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 178 | } |
| 179 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 180 | bool UtilityProcessHostImpl::StartBatchMode() { |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 181 | CHECK(!is_batch_mode_); |
| 182 | is_batch_mode_ = StartProcess(); |
| 183 | Send(new UtilityMsg_BatchMode_Started()); |
| 184 | return is_batch_mode_; |
| 185 | } |
| 186 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 187 | void UtilityProcessHostImpl::EndBatchMode() { |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 188 | CHECK(is_batch_mode_); |
| 189 | is_batch_mode_ = false; |
| 190 | Send(new UtilityMsg_BatchMode_Finished()); |
| 191 | } |
| 192 | |
[email protected] | 2dec8ec | 2013-02-07 19:20:34 | [diff] [blame] | 193 | void UtilityProcessHostImpl::SetExposedDir(const base::FilePath& dir) { |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 194 | exposed_dir_ = dir; |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 195 | } |
| 196 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 197 | void UtilityProcessHostImpl::DisableSandbox() { |
| 198 | no_sandbox_ = true; |
| 199 | } |
| 200 | |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 201 | #if defined(OS_WIN) |
| 202 | void UtilityProcessHostImpl::ElevatePrivileges() { |
| 203 | no_sandbox_ = true; |
| 204 | run_elevated_ = true; |
| 205 | } |
| 206 | #endif |
| 207 | |
[email protected] | dc1571a15 | 2012-12-19 02:23:38 | [diff] [blame] | 208 | const ChildProcessData& UtilityProcessHostImpl::GetData() { |
| 209 | return process_->GetData(); |
| 210 | } |
| 211 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 212 | #if defined(OS_POSIX) |
| 213 | |
[email protected] | b345c48 | 2013-08-30 18:00:39 | [diff] [blame] | 214 | void UtilityProcessHostImpl::SetEnv(const base::EnvironmentMap& env) { |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 215 | env_ = env; |
| 216 | } |
| 217 | |
| 218 | #endif // OS_POSIX |
| 219 | |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 220 | bool UtilityProcessHostImpl::StartMojoMode() { |
| 221 | CHECK(!mojo_application_host_); |
| 222 | mojo_application_host_.reset(new MojoApplicationHost); |
| 223 | |
| 224 | bool mojo_result = mojo_application_host_->Init(); |
| 225 | if (!mojo_result) |
| 226 | return false; |
| 227 | |
| 228 | return StartProcess(); |
| 229 | } |
| 230 | |
| 231 | ServiceRegistry* UtilityProcessHostImpl::GetServiceRegistry() { |
amistry | faa231a4 | 2015-05-20 01:49:12 | [diff] [blame] | 232 | if (mojo_application_host_) |
| 233 | return mojo_application_host_->service_registry(); |
| 234 | return nullptr; |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 235 | } |
| 236 | |
thestig | 1a255e5 | 2015-04-01 17:53:39 | [diff] [blame] | 237 | void UtilityProcessHostImpl::SetName(const base::string16& name) { |
amistry | cd95c25 | 2015-03-20 02:07:04 | [diff] [blame] | 238 | name_ = name; |
| 239 | } |
| 240 | |
kerrnel | afd49a83b | 2016-01-22 21:16:15 | [diff] [blame] | 241 | #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 242 | // static |
| 243 | void UtilityProcessHostImpl::EarlyZygoteLaunch() { |
| 244 | DCHECK(!g_utility_zygote); |
| 245 | g_utility_zygote = CreateZygote(); |
| 246 | } |
| 247 | #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
| 248 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 249 | bool UtilityProcessHostImpl::StartProcess() { |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 250 | if (started_) |
| 251 | return true; |
| 252 | started_ = true; |
| 253 | |
| 254 | if (is_batch_mode_) |
| 255 | return true; |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 256 | |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 257 | // Name must be set or metrics_service will crash in any test which |
| 258 | // launches a UtilityProcessHost. |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 259 | process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_UTILITY, this)); |
thestig | 1a255e5 | 2015-04-01 17:53:39 | [diff] [blame] | 260 | process_->SetName(name_); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 261 | |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 262 | std::string channel_id = process_->GetHost()->CreateChannel(); |
[email protected] | 4734d0b | 2011-12-03 07:10:44 | [diff] [blame] | 263 | if (channel_id.empty()) |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 264 | return false; |
| 265 | |
[email protected] | 5281947 | 2013-11-24 22:49:55 | [diff] [blame] | 266 | if (RenderProcessHost::run_renderer_in_process()) { |
| 267 | DCHECK(g_utility_main_thread_factory); |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 268 | // See comment in RenderProcessHostImpl::Init() for the background on why we |
| 269 | // support single process mode this way. |
morrita | c6238ab | 2015-03-18 01:48:29 | [diff] [blame] | 270 | in_process_thread_.reset( |
| 271 | g_utility_main_thread_factory(InProcessChildThreadParams( |
| 272 | channel_id, BrowserThread::UnsafeGetMessageLoopForThread( |
| 273 | BrowserThread::IO)->task_runner()))); |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 274 | in_process_thread_->Start(); |
rockot | eb6ee29 | 2015-05-18 20:29:38 | [diff] [blame] | 275 | OnProcessLaunched(); |
[email protected] | d7a2d89 | 2013-08-16 07:45:36 | [diff] [blame] | 276 | } else { |
[email protected] | 47927870 | 2014-08-11 20:32:09 | [diff] [blame] | 277 | const base::CommandLine& browser_command_line = |
| 278 | *base::CommandLine::ForCurrentProcess(); |
[email protected] | 74a890c | 2012-09-13 21:42:40 | [diff] [blame] | 279 | |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 280 | bool has_cmd_prefix = browser_command_line.HasSwitch( |
| 281 | switches::kUtilityCmdPrefix); |
[email protected] | 74a890c | 2012-09-13 21:42:40 | [diff] [blame] | 282 | |
twellington | a7bf963 | 2015-11-09 18:18:17 | [diff] [blame] | 283 | #if defined(OS_ANDROID) |
| 284 | // readlink("/prof/self/exe") sometimes fails on Android at startup. |
| 285 | // As a workaround skip calling it here, since the executable name is |
| 286 | // not needed on Android anyway. See crbug.com/500854. |
| 287 | base::CommandLine* cmd_line = |
| 288 | new base::CommandLine(base::CommandLine::NO_PROGRAM); |
| 289 | #else |
| 290 | int child_flags = child_flags_; |
[email protected] | 74a890c | 2012-09-13 21:42:40 | [diff] [blame] | 291 | |
twellington | a7bf963 | 2015-11-09 18:18:17 | [diff] [blame] | 292 | // When running under gdb, forking /proc/self/exe ends up forking the gdb |
| 293 | // executable instead of Chromium. It is almost safe to assume that no |
| 294 | // updates will happen while a developer is running with |
| 295 | // |switches::kUtilityCmdPrefix|. See ChildProcessHost::GetChildPath() for |
| 296 | // a similar case with Valgrind. |
| 297 | if (has_cmd_prefix) |
| 298 | child_flags = ChildProcessHost::CHILD_NORMAL; |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 299 | |
twellington | a7bf963 | 2015-11-09 18:18:17 | [diff] [blame] | 300 | base::FilePath exe_path = ChildProcessHost::GetChildPath(child_flags); |
| 301 | if (exe_path.empty()) { |
| 302 | NOTREACHED() << "Unable to get utility process binary name."; |
| 303 | return false; |
| 304 | } |
| 305 | |
| 306 | base::CommandLine* cmd_line = new base::CommandLine(exe_path); |
| 307 | #endif |
| 308 | |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 309 | cmd_line->AppendSwitchASCII(switches::kProcessType, |
| 310 | switches::kUtilityProcess); |
| 311 | cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
| 312 | std::string locale = GetContentClient()->browser()->GetApplicationLocale(); |
| 313 | cmd_line->AppendSwitchASCII(switches::kLang, locale); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 314 | |
fdoray | 343068c4 | 2016-02-03 15:45:58 | [diff] [blame] | 315 | #if defined(OS_WIN) |
| 316 | if (GetContentClient()->browser()->ShouldUseWindowsPrefetchArgument()) |
| 317 | cmd_line->AppendArg(switches::kPrefetchArgumentOther); |
| 318 | #endif // defined(OS_WIN) |
| 319 | |
jdduke | b7ce1e3 | 2015-03-18 00:14:17 | [diff] [blame] | 320 | if (no_sandbox_) |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 321 | cmd_line->AppendSwitch(switches::kNoSandbox); |
jdduke | b7ce1e3 | 2015-03-18 00:14:17 | [diff] [blame] | 322 | |
| 323 | // Browser command-line switches to propagate to the utility process. |
| 324 | static const char* const kSwitchNames[] = { |
| 325 | switches::kDebugPluginLoading, |
| 326 | switches::kNoSandbox, |
| 327 | switches::kProfilerTiming, |
[email protected] | 172ca98 | 2012-10-03 19:55:07 | [diff] [blame] | 328 | #if defined(OS_MACOSX) |
jdduke | b7ce1e3 | 2015-03-18 00:14:17 | [diff] [blame] | 329 | switches::kEnableSandboxLogging, |
[email protected] | 172ca98 | 2012-10-03 19:55:07 | [diff] [blame] | 330 | #endif |
jdduke | b7ce1e3 | 2015-03-18 00:14:17 | [diff] [blame] | 331 | }; |
| 332 | cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, |
| 333 | arraysize(kSwitchNames)); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 334 | |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 335 | if (has_cmd_prefix) { |
[email protected] | dc120e7 | 2013-11-05 04:36:51 | [diff] [blame] | 336 | // Launch the utility child process with some prefix |
[email protected] | 215d49e | 2013-09-20 07:40:15 | [diff] [blame] | 337 | // (usually "xterm -e gdb --args"). |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 338 | cmd_line->PrependWrapper(browser_command_line.GetSwitchValueNative( |
| 339 | switches::kUtilityCmdPrefix)); |
| 340 | } |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 341 | |
[email protected] | dc120e7 | 2013-11-05 04:36:51 | [diff] [blame] | 342 | if (!exposed_dir_.empty()) { |
| 343 | cmd_line->AppendSwitchPath(switches::kUtilityProcessAllowedDir, |
| 344 | exposed_dir_); |
| 345 | } |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 346 | |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 347 | #if defined(OS_WIN) |
| 348 | // Let the utility process know if it is intended to be elevated. |
| 349 | if (run_elevated_) |
| 350 | cmd_line->AppendSwitch(switches::kUtilityProcessRunningElevated); |
| 351 | #endif |
| 352 | |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 353 | process_->Launch( |
[email protected] | 121e6138 | 2014-03-13 11:35:15 | [diff] [blame] | 354 | new UtilitySandboxedProcessLauncherDelegate(exposed_dir_, |
| 355 | run_elevated_, |
| 356 | no_sandbox_, env_, |
| 357 | process_->GetHost()), |
sievers | 954e37a | 2015-03-28 01:50:24 | [diff] [blame] | 358 | cmd_line, |
| 359 | true); |
[email protected] | 6d057a0c | 2013-07-09 21:12:07 | [diff] [blame] | 360 | } |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 361 | |
| 362 | return true; |
| 363 | } |
| 364 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 365 | bool UtilityProcessHostImpl::OnMessageReceived(const IPC::Message& message) { |
dcheng | 54c3719d | 2014-08-26 21:52:56 | [diff] [blame] | 366 | if (!client_.get()) |
[email protected] | b62c08c | 2014-08-21 17:48:50 | [diff] [blame] | 367 | return true; |
| 368 | |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 369 | client_task_runner_->PostTask( |
| 370 | FROM_HERE, |
[email protected] | b62c08c | 2014-08-21 17:48:50 | [diff] [blame] | 371 | base::Bind( |
| 372 | base::IgnoreResult(&UtilityProcessHostClient::OnMessageReceived), |
| 373 | client_.get(), |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 374 | message)); |
[email protected] | b62c08c | 2014-08-21 17:48:50 | [diff] [blame] | 375 | |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 376 | return true; |
| 377 | } |
| 378 | |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 379 | void UtilityProcessHostImpl::OnProcessLaunchFailed() { |
dcheng | 54c3719d | 2014-08-26 21:52:56 | [diff] [blame] | 380 | if (!client_.get()) |
[email protected] | b62c08c | 2014-08-21 17:48:50 | [diff] [blame] | 381 | return; |
| 382 | |
[email protected] | fa01e47 | 2014-02-11 14:45:35 | [diff] [blame] | 383 | client_task_runner_->PostTask( |
| 384 | FROM_HERE, |
| 385 | base::Bind(&UtilityProcessHostClient::OnProcessLaunchFailed, |
| 386 | client_.get())); |
| 387 | } |
| 388 | |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 389 | void UtilityProcessHostImpl::OnProcessCrashed(int exit_code) { |
dcheng | 54c3719d | 2014-08-26 21:52:56 | [diff] [blame] | 390 | if (!client_.get()) |
[email protected] | b62c08c | 2014-08-21 17:48:50 | [diff] [blame] | 391 | return; |
| 392 | |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 393 | client_task_runner_->PostTask( |
| 394 | FROM_HERE, |
[email protected] | c4f883a | 2012-02-03 17:02:07 | [diff] [blame] | 395 | base::Bind(&UtilityProcessHostClient::OnProcessCrashed, client_.get(), |
| 396 | exit_code)); |
[email protected] | 373c106 | 2011-06-09 21:11:51 | [diff] [blame] | 397 | } |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 398 | |
amistry | 467cdc7 | 2015-03-13 01:58:47 | [diff] [blame] | 399 | void UtilityProcessHostImpl::OnProcessLaunched() { |
| 400 | if (mojo_application_host_) { |
| 401 | base::ProcessHandle handle; |
| 402 | if (RenderProcessHost::run_renderer_in_process()) |
| 403 | handle = base::GetCurrentProcessHandle(); |
| 404 | else |
| 405 | handle = process_->GetData().handle; |
| 406 | |
| 407 | mojo_application_host_->Activate(this, handle); |
| 408 | } |
| 409 | } |
| 410 | |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 411 | } // namespace content |