Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: content/browser/child_process_launcher.cc

Issue 98603007: Launches a privileged utility process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolves review feedback. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/child_process_launcher.h" 5 #include "content/browser/child_process_launcher.h"
6 6
7 #include <utility> // For std::pair. 7 #include <utility> // For std::pair.
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()-> 64 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()->
65 HasSwitch(switches::kChildCleanExit); 65 HasSwitch(switches::kChildCleanExit);
66 #else 66 #else
67 terminate_child_on_shutdown_ = true; 67 terminate_child_on_shutdown_ = true;
68 #endif 68 #endif
69 } 69 }
70 70
71 void Launch( 71 void Launch(
72 #if defined(OS_WIN) 72 #if defined(OS_WIN)
73 SandboxedProcessLauncherDelegate* delegate, 73 SandboxedProcessLauncherDelegate* delegate,
74 bool launch_elevated,
74 #elif defined(OS_ANDROID) 75 #elif defined(OS_ANDROID)
75 int ipcfd, 76 int ipcfd,
76 #elif defined(OS_POSIX) 77 #elif defined(OS_POSIX)
77 bool use_zygote, 78 bool use_zygote,
78 const base::EnvironmentMap& environ, 79 const base::EnvironmentMap& environ,
79 int ipcfd, 80 int ipcfd,
80 #endif 81 #endif
81 CommandLine* cmd_line, 82 CommandLine* cmd_line,
82 int child_process_id, 83 int child_process_id,
83 Client* client) { 84 Client* client) {
84 client_ = client; 85 client_ = client;
85 86
86 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); 87 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));
87 88
88 #if defined(OS_ANDROID) 89 #if defined(OS_ANDROID)
89 // We need to close the client end of the IPC channel to reliably detect 90 // We need to close the client end of the IPC channel to reliably detect
90 // child termination. We will close this fd after we create the child 91 // child termination. We will close this fd after we create the child
91 // process which is asynchronous on Android. 92 // process which is asynchronous on Android.
92 ipcfd_ = ipcfd; 93 ipcfd_ = ipcfd;
93 #endif 94 #endif
94 BrowserThread::PostTask( 95 BrowserThread::PostTask(
95 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 96 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
96 base::Bind( 97 base::Bind(
97 &Context::LaunchInternal, 98 &Context::LaunchInternal,
98 make_scoped_refptr(this), 99 make_scoped_refptr(this),
99 client_thread_id_, 100 client_thread_id_,
100 child_process_id, 101 child_process_id,
101 #if defined(OS_WIN) 102 #if defined(OS_WIN)
102 delegate, 103 delegate,
104 launch_elevated,
103 #elif defined(OS_ANDROID) 105 #elif defined(OS_ANDROID)
104 ipcfd, 106 ipcfd,
105 #elif defined(OS_POSIX) 107 #elif defined(OS_POSIX)
106 use_zygote, 108 use_zygote,
107 environ, 109 environ,
108 ipcfd, 110 ipcfd,
109 #endif 111 #endif
110 cmd_line)); 112 cmd_line));
111 } 113 }
112 114
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 178 }
177 } 179 }
178 180
179 static void LaunchInternal( 181 static void LaunchInternal(
180 // |this_object| is NOT thread safe. Only use it to post a task back. 182 // |this_object| is NOT thread safe. Only use it to post a task back.
181 scoped_refptr<Context> this_object, 183 scoped_refptr<Context> this_object,
182 BrowserThread::ID client_thread_id, 184 BrowserThread::ID client_thread_id,
183 int child_process_id, 185 int child_process_id,
184 #if defined(OS_WIN) 186 #if defined(OS_WIN)
185 SandboxedProcessLauncherDelegate* delegate, 187 SandboxedProcessLauncherDelegate* delegate,
188 bool launch_elevated,
186 #elif defined(OS_ANDROID) 189 #elif defined(OS_ANDROID)
187 int ipcfd, 190 int ipcfd,
188 #elif defined(OS_POSIX) 191 #elif defined(OS_POSIX)
189 bool use_zygote, 192 bool use_zygote,
190 const base::EnvironmentMap& env, 193 const base::EnvironmentMap& env,
191 int ipcfd, 194 int ipcfd,
192 #endif 195 #endif
193 CommandLine* cmd_line) { 196 CommandLine* cmd_line) {
194 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); 197 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line);
195 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 198 base::TimeTicks begin_launch_time = base::TimeTicks::Now();
196 199
197 #if defined(OS_WIN) 200 #if defined(OS_WIN)
198 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); 201 base::ProcessHandle handle = base::kNullProcessHandle;
199 base::ProcessHandle handle = StartSandboxedProcess(delegate, cmd_line); 202 if (launch_elevated) {
203 base::LaunchOptions options;
204 options.start_hidden = true;
205 base::LaunchElevatedProcess(*cmd_line, options, &handle);
206 } else {
207 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
208 handle = StartSandboxedProcess(delegate, cmd_line);
209 }
200 #elif defined(OS_ANDROID) 210 #elif defined(OS_ANDROID)
201 // Android WebView runs in single process, ensure that we never get here 211 // Android WebView runs in single process, ensure that we never get here
202 // when running in single process mode. 212 // when running in single process mode.
203 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); 213 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess));
204 214
205 std::string process_type = 215 std::string process_type =
206 cmd_line->GetSwitchValueASCII(switches::kProcessType); 216 cmd_line->GetSwitchValueASCII(switches::kProcessType);
207 std::vector<FileDescriptorInfo> files_to_register; 217 std::vector<FileDescriptorInfo> files_to_register;
208 files_to_register.push_back( 218 files_to_register.push_back(
209 FileDescriptorInfo(kPrimaryIPCChannel, 219 FileDescriptorInfo(kPrimaryIPCChannel,
210 base::FileDescriptor(ipcfd, false))); 220 base::FileDescriptor(ipcfd, false)));
211 221
212 GetContentClient()->browser()-> 222 GetContentClient()->browser()->
213 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, 223 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id,
214 &files_to_register); 224 &files_to_register);
215 225
216 StartChildProcess(cmd_line->argv(), files_to_register, 226 StartChildProcess(cmd_line->argv(), files_to_register,
217 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, 227 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted,
218 this_object, client_thread_id, begin_launch_time)); 228 this_object, client_thread_id, begin_launch_time));
219 229
220 #elif defined(OS_POSIX) 230 #elif defined(OS_POSIX)
221 base::ProcessHandle handle = base::kNullProcessHandle; 231 base::ProcessHandle handle = base::kNullProcessHandle;
222 // We need to close the client end of the IPC channel to reliably detect 232 // We need to close the client end of the IPC channel to reliably detect
223 // child termination. 233 // child termination.
224 file_util::ScopedFD ipcfd_closer(&ipcfd); 234 file_util::ScopedFD ipcfd_closer(&ipcfd);
225 235
226 std::string process_type = 236 std::string process_type =
227 cmd_line->GetSwitchValueASCII(switches::kProcessType); 237 cmd_line->GetSwitchValueASCII(switches::kProcessType);
228 std::vector<FileDescriptorInfo> files_to_register; 238 std::vector<FileDescriptorInfo> files_to_register;
229 files_to_register.push_back( 239 files_to_register.push_back(
230 FileDescriptorInfo(kPrimaryIPCChannel, 240 FileDescriptorInfo(kPrimaryIPCChannel,
231 base::FileDescriptor(ipcfd, false))); 241 base::FileDescriptor(ipcfd, false)));
232 242
233 #if !defined(OS_MACOSX) 243 #if !defined(OS_MACOSX)
234 GetContentClient()->browser()-> 244 GetContentClient()->browser()->
235 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, 245 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id,
236 &files_to_register); 246 &files_to_register);
237 if (use_zygote) { 247 if (use_zygote) {
238 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), 248 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(),
239 files_to_register, 249 files_to_register,
240 process_type); 250 process_type);
241 } else 251 } else
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 #endif 333 #endif
324 starting_ = false; 334 starting_ = false;
325 process_.set_handle(handle); 335 process_.set_handle(handle);
326 if (!handle) 336 if (!handle)
327 LOG(ERROR) << "Failed to launch child process"; 337 LOG(ERROR) << "Failed to launch child process";
328 338
329 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 339 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
330 zygote_ = zygote; 340 zygote_ = zygote;
331 #endif 341 #endif
332 if (client_) { 342 if (client_) {
333 client_->OnProcessLaunched(); 343 if (handle) {
344 client_->OnProcessLaunched();
345 } else {
346 client_->OnProcessLaunchFailed();
347 }
334 } else { 348 } else {
335 Terminate(); 349 Terminate();
336 } 350 }
337 } 351 }
338 352
339 void Terminate() { 353 void Terminate() {
340 if (!process_.handle()) 354 if (!process_.handle())
341 return; 355 return;
342 356
343 if (!terminate_child_on_shutdown_) 357 if (!terminate_child_on_shutdown_)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 int ipcfd_; 420 int ipcfd_;
407 #elif defined(OS_POSIX) && !defined(OS_MACOSX) 421 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
408 bool zygote_; 422 bool zygote_;
409 #endif 423 #endif
410 }; 424 };
411 425
412 426
413 ChildProcessLauncher::ChildProcessLauncher( 427 ChildProcessLauncher::ChildProcessLauncher(
414 #if defined(OS_WIN) 428 #if defined(OS_WIN)
415 SandboxedProcessLauncherDelegate* delegate, 429 SandboxedProcessLauncherDelegate* delegate,
430 bool launch_elevated,
416 #elif defined(OS_POSIX) 431 #elif defined(OS_POSIX)
417 bool use_zygote, 432 bool use_zygote,
418 const base::EnvironmentMap& environ, 433 const base::EnvironmentMap& environ,
419 int ipcfd, 434 int ipcfd,
420 #endif 435 #endif
421 CommandLine* cmd_line, 436 CommandLine* cmd_line,
422 int child_process_id, 437 int child_process_id,
423 Client* client) { 438 Client* client) {
424 context_ = new Context(); 439 context_ = new Context();
425 context_->Launch( 440 context_->Launch(
426 #if defined(OS_WIN) 441 #if defined(OS_WIN)
427 delegate, 442 delegate,
443 launch_elevated,
428 #elif defined(OS_ANDROID) 444 #elif defined(OS_ANDROID)
429 ipcfd, 445 ipcfd,
430 #elif defined(OS_POSIX) 446 #elif defined(OS_POSIX)
431 use_zygote, 447 use_zygote,
432 environ, 448 environ,
433 ipcfd, 449 ipcfd,
434 #endif 450 #endif
435 cmd_line, 451 cmd_line,
436 child_process_id, 452 child_process_id,
437 client); 453 client);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 GetHandle(), background)); 515 GetHandle(), background));
500 } 516 }
501 517
502 void ChildProcessLauncher::SetTerminateChildOnShutdown( 518 void ChildProcessLauncher::SetTerminateChildOnShutdown(
503 bool terminate_on_shutdown) { 519 bool terminate_on_shutdown) {
504 if (context_.get()) 520 if (context_.get())
505 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); 521 context_->set_terminate_child_on_shutdown(terminate_on_shutdown);
506 } 522 }
507 523
508 } // namespace content 524 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698