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

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

Issue 1532423003: Have each SandboxedProcessLauncherDelegate maintain a zygote. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fetch sandbox status Created 4 years, 12 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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> 7 #include <utility>
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 21 matching lines...) Expand all
32 #include "content/browser/browser_io_surface_manager_mac.h" 32 #include "content/browser/browser_io_surface_manager_mac.h"
33 #include "content/browser/mach_broker_mac.h" 33 #include "content/browser/mach_broker_mac.h"
34 #include "sandbox/mac/bootstrap_sandbox.h" 34 #include "sandbox/mac/bootstrap_sandbox.h"
35 #include "sandbox/mac/pre_exec_delegate.h" 35 #include "sandbox/mac/pre_exec_delegate.h"
36 #elif defined(OS_ANDROID) 36 #elif defined(OS_ANDROID)
37 #include "base/android/jni_android.h" 37 #include "base/android/jni_android.h"
38 #include "content/browser/android/child_process_launcher_android.h" 38 #include "content/browser/android/child_process_launcher_android.h"
39 #elif defined(OS_POSIX) 39 #elif defined(OS_POSIX)
40 #include "base/memory/singleton.h" 40 #include "base/memory/singleton.h"
41 #include "content/browser/renderer_host/render_sandbox_host_linux.h" 41 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
42 #include "content/browser/zygote_host/zygote_communication_linux.h"
42 #include "content/browser/zygote_host/zygote_host_impl_linux.h" 43 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
43 #include "content/common/child_process_sandbox_support_impl_linux.h" 44 #include "content/common/child_process_sandbox_support_impl_linux.h"
44 #endif 45 #endif
45 46
46 #if defined(OS_POSIX) 47 #if defined(OS_POSIX)
47 #include "base/posix/global_descriptors.h" 48 #include "base/posix/global_descriptors.h"
48 #include "content/browser/file_descriptor_info_impl.h" 49 #include "content/browser/file_descriptor_info_impl.h"
49 #include "gin/v8_initializer.h" 50 #include "gin/v8_initializer.h"
50 #endif 51 #endif
51 52
52 namespace content { 53 namespace content {
53 54
54 namespace { 55 namespace {
55 56
56 typedef base::Callback<void(bool, 57 typedef base::Callback<void(ZygoteHandle,
57 #if defined(OS_ANDROID) 58 #if defined(OS_ANDROID)
58 base::ScopedFD, 59 base::ScopedFD,
59 #endif 60 #endif
60 base::Process)> NotifyCallback; 61 base::Process)> NotifyCallback;
61 62
62 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { 63 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
63 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 64 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
64 // Log the launch time, separating out the first one (which will likely be 65 // Log the launch time, separating out the first one (which will likely be
65 // slower due to the rest of the browser initializing at the same time). 66 // slower due to the rest of the browser initializing at the same time).
66 static bool done_first_launch = false; 67 static bool done_first_launch = false;
(...skipping 13 matching lines...) Expand all
80 const base::TimeTicks begin_launch_time, 81 const base::TimeTicks begin_launch_time,
81 base::ScopedFD ipcfd, 82 base::ScopedFD ipcfd,
82 base::ProcessHandle handle) { 83 base::ProcessHandle handle) {
83 // This can be called on the launcher thread or UI thread. 84 // This can be called on the launcher thread or UI thread.
84 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; 85 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time;
85 BrowserThread::PostTask( 86 BrowserThread::PostTask(
86 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 87 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
87 base::Bind(&RecordHistogramsOnLauncherThread, launch_time)); 88 base::Bind(&RecordHistogramsOnLauncherThread, launch_time));
88 89
89 base::Closure callback_on_client_thread( 90 base::Closure callback_on_client_thread(
90 base::Bind(callback, false, base::Passed(&ipcfd), 91 base::Bind(callback, ZygoteHandle(), base::Passed(&ipcfd),
91 base::Passed(base::Process(handle)))); 92 base::Passed(base::Process(handle))));
92 if (BrowserThread::CurrentlyOn(client_thread_id)) { 93 if (BrowserThread::CurrentlyOn(client_thread_id)) {
93 callback_on_client_thread.Run(); 94 callback_on_client_thread.Run();
94 } else { 95 } else {
95 BrowserThread::PostTask( 96 BrowserThread::PostTask(
96 client_thread_id, FROM_HERE, callback_on_client_thread); 97 client_thread_id, FROM_HERE, callback_on_client_thread);
97 } 98 }
98 } 99 }
99 #endif 100 #endif
100 101
101 void LaunchOnLauncherThread(const NotifyCallback& callback, 102 void LaunchOnLauncherThread(const NotifyCallback& callback,
102 BrowserThread::ID client_thread_id, 103 BrowserThread::ID client_thread_id,
103 int child_process_id, 104 int child_process_id,
104 SandboxedProcessLauncherDelegate* delegate, 105 SandboxedProcessLauncherDelegate* delegate,
105 #if defined(OS_ANDROID) 106 #if defined(OS_ANDROID)
106 base::ScopedFD ipcfd, 107 base::ScopedFD ipcfd,
107 #endif 108 #endif
108 base::CommandLine* cmd_line) { 109 base::CommandLine* cmd_line) {
109 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 110 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
110 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); 111 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
112 #if !defined(OS_ANDROID)
113 ZygoteHandle zygote;
114 #endif
111 #if defined(OS_WIN) 115 #if defined(OS_WIN)
112 bool use_zygote = false;
113 bool launch_elevated = delegate->ShouldLaunchElevated(); 116 bool launch_elevated = delegate->ShouldLaunchElevated();
114 #elif defined(OS_MACOSX) 117 #elif defined(OS_MACOSX)
115 bool use_zygote = false;
116 base::EnvironmentMap env = delegate->GetEnvironment(); 118 base::EnvironmentMap env = delegate->GetEnvironment();
117 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 119 base::ScopedFD ipcfd = delegate->TakeIpcFd();
118 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 120 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
119 bool use_zygote = delegate->ShouldUseZygote();
120 base::EnvironmentMap env = delegate->GetEnvironment(); 121 base::EnvironmentMap env = delegate->GetEnvironment();
121 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 122 base::ScopedFD ipcfd = delegate->TakeIpcFd();
122 #endif 123 #endif
123 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); 124 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line);
124 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 125 base::TimeTicks begin_launch_time = base::TimeTicks::Now();
125 126
126 base::Process process; 127 base::Process process;
127 #if defined(OS_WIN) 128 #if defined(OS_WIN)
128 if (launch_elevated) { 129 if (launch_elevated) {
129 base::LaunchOptions options; 130 base::LaunchOptions options;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 StartChildProcess( 193 StartChildProcess(
193 cmd_line->argv(), child_process_id, std::move(files_to_register), regions, 194 cmd_line->argv(), child_process_id, std::move(files_to_register), regions,
194 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id, 195 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
195 begin_launch_time, base::Passed(&ipcfd))); 196 begin_launch_time, base::Passed(&ipcfd)));
196 197
197 #elif defined(OS_POSIX) 198 #elif defined(OS_POSIX)
198 // We need to close the client end of the IPC channel to reliably detect 199 // We need to close the client end of the IPC channel to reliably detect
199 // child termination. 200 // child termination.
200 201
201 #if !defined(OS_MACOSX) 202 #if !defined(OS_MACOSX)
202 if (use_zygote) { 203 zygote = nullptr;
mdempsky 2015/12/22 21:21:33 Hm, so if you use using ZygoteHandle = std::n
Greg K 2016/01/05 21:42:13 Done.
203 base::ProcessHandle handle = ZygoteHostImpl::GetInstance()->ForkRequest( 204 ZygoteHandle* zygote_handle = delegate->GetZygote();
205 if (zygote_handle) {
206 if (*zygote_handle == nullptr) {
mdempsky 2015/12/22 21:21:33 I'd suggest adding a comment that mentions we're r
Greg K 2016/01/05 21:42:13 Done.
207 *zygote_handle = new ZygoteCommunication();
208 (*zygote_handle)->Init();
209 }
210 zygote = *zygote_handle;
211 base::ProcessHandle handle = zygote->ForkRequest(
204 cmd_line->argv(), std::move(files_to_register), process_type); 212 cmd_line->argv(), std::move(files_to_register), process_type);
205 process = base::Process(handle); 213 process = base::Process(handle);
206 } else 214 } else
207 // Fall through to the normal posix case below when we're not zygoting. 215 // Fall through to the normal posix case below when we're not zygoting.
208 #endif // !defined(OS_MACOSX) 216 #endif // !defined(OS_MACOSX)
209 { 217 {
210 // Convert FD mapping to FileHandleMappingVector 218 // Convert FD mapping to FileHandleMappingVector
211 base::FileHandleMappingVector fds_to_map = 219 base::FileHandleMappingVector fds_to_map =
212 files_to_register->GetMappingWithIDAdjustment( 220 files_to_register->GetMappingWithIDAdjustment(
213 base::GlobalDescriptors::kBaseDescriptor); 221 base::GlobalDescriptors::kBaseDescriptor);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 broker->GetLock().Release(); 283 broker->GetLock().Release();
276 #endif // defined(OS_MACOSX) 284 #endif // defined(OS_MACOSX)
277 } 285 }
278 #endif // else defined(OS_POSIX) 286 #endif // else defined(OS_POSIX)
279 #if !defined(OS_ANDROID) 287 #if !defined(OS_ANDROID)
280 if (process.IsValid()) { 288 if (process.IsValid()) {
281 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() - 289 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() -
282 begin_launch_time); 290 begin_launch_time);
283 } 291 }
284 BrowserThread::PostTask(client_thread_id, FROM_HERE, 292 BrowserThread::PostTask(client_thread_id, FROM_HERE,
285 base::Bind(callback, 293 base::Bind(callback, zygote, base::Passed(&process)));
286 use_zygote,
287 base::Passed(&process)));
288 #endif // !defined(OS_ANDROID) 294 #endif // !defined(OS_ANDROID)
289 } 295 }
290 296
291 void TerminateOnLauncherThread(bool zygote, base::Process process) { 297 void TerminateOnLauncherThread(ZygoteHandle zygote, base::Process process) {
292 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 298 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
293 #if defined(OS_ANDROID) 299 #if defined(OS_ANDROID)
294 VLOG(1) << "ChromeProcess: Stopping process with handle " 300 VLOG(1) << "ChromeProcess: Stopping process with handle "
295 << process.Handle(); 301 << process.Handle();
296 StopChildProcess(process.Handle()); 302 StopChildProcess(process.Handle());
297 #else 303 #else
298 // Client has gone away, so just kill the process. Using exit code 0 304 // Client has gone away, so just kill the process. Using exit code 0
299 // means that UMA won't treat this as a crash. 305 // means that UMA won't treat this as a crash.
300 process.Terminate(RESULT_CODE_NORMAL_EXIT, false); 306 process.Terminate(RESULT_CODE_NORMAL_EXIT, false);
301 // On POSIX, we must additionally reap the child. 307 // On POSIX, we must additionally reap the child.
302 #if defined(OS_POSIX) 308 #if defined(OS_POSIX)
303 #if !defined(OS_MACOSX) 309 #if !defined(OS_MACOSX)
304 if (zygote) { 310 if (zygote) {
305 // If the renderer was created via a zygote, we have to proxy the reaping 311 // If the renderer was created via a zygote, we have to proxy the reaping
306 // through the zygote process. 312 // through the zygote process.
307 ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(process.Handle()); 313 zygote->EnsureProcessTerminated(process.Handle());
308 } else 314 } else
309 #endif // !OS_MACOSX 315 #endif // !OS_MACOSX
310 base::EnsureProcessTerminated(std::move(process)); 316 base::EnsureProcessTerminated(std::move(process));
311 #endif // OS_POSIX 317 #endif // OS_POSIX
312 #endif // defined(OS_ANDROID) 318 #endif // defined(OS_ANDROID)
313 } 319 }
314 320
315 void SetProcessBackgroundedOnLauncherThread(base::Process process, 321 void SetProcessBackgroundedOnLauncherThread(base::Process process,
316 bool background) { 322 bool background) {
317 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 323 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
318 if (process.CanBackgroundProcesses()) { 324 if (process.CanBackgroundProcesses()) {
319 process.SetProcessBackgrounded(background); 325 process.SetProcessBackgrounded(background);
320 } 326 }
321 #if defined(OS_ANDROID) 327 #if defined(OS_ANDROID)
322 SetChildProcessInForeground(process.Handle(), !background); 328 SetChildProcessInForeground(process.Handle(), !background);
323 #endif 329 #endif
324 } 330 }
325 331
326 } // namespace 332 } // namespace
327 333
328 ChildProcessLauncher::ChildProcessLauncher( 334 ChildProcessLauncher::ChildProcessLauncher(
329 SandboxedProcessLauncherDelegate* delegate, 335 SandboxedProcessLauncherDelegate* delegate,
330 base::CommandLine* cmd_line, 336 base::CommandLine* cmd_line,
331 int child_process_id, 337 int child_process_id,
332 Client* client, 338 Client* client,
333 bool terminate_on_shutdown) 339 bool terminate_on_shutdown)
334 : client_(client), 340 : client_(client),
335 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION), 341 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION),
336 exit_code_(RESULT_CODE_NORMAL_EXIT), 342 exit_code_(RESULT_CODE_NORMAL_EXIT),
337 zygote_(false), 343 zygote_(),
mdempsky 2015/12/22 21:21:33 (And explicitly initialize to nullptr here if you
Greg K 2016/01/05 21:42:13 Done.
338 starting_(true), 344 starting_(true),
339 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ 345 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
340 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ 346 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
341 defined(UNDEFINED_SANITIZER) 347 defined(UNDEFINED_SANITIZER)
342 terminate_child_on_shutdown_(false), 348 terminate_child_on_shutdown_(false),
343 #else 349 #else
344 terminate_child_on_shutdown_(terminate_on_shutdown), 350 terminate_child_on_shutdown_(terminate_on_shutdown),
345 #endif 351 #endif
346 weak_factory_(this) { 352 weak_factory_(this) {
347 DCHECK(CalledOnValidThread()); 353 DCHECK(CalledOnValidThread());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 #if defined(OS_ANDROID) 403 #if defined(OS_ANDROID)
398 base::Passed(&ipcfd), 404 base::Passed(&ipcfd),
399 #endif 405 #endif
400 cmd_line)); 406 cmd_line));
401 } 407 }
402 408
403 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { 409 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
404 DCHECK(CalledOnValidThread()); 410 DCHECK(CalledOnValidThread());
405 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 411 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
406 if (zygote_) { 412 if (zygote_) {
407 termination_status_ = ZygoteHostImpl::GetInstance()-> 413 termination_status_ = zygote_->GetTerminationStatus(
408 GetTerminationStatus(process_.Handle(), known_dead, &exit_code_); 414 process_.Handle(), known_dead, &exit_code_);
409 } else if (known_dead) { 415 } else if (known_dead) {
410 termination_status_ = 416 termination_status_ =
411 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_); 417 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
412 } else { 418 } else {
413 #elif defined(OS_MACOSX) 419 #elif defined(OS_MACOSX)
414 if (known_dead) { 420 if (known_dead) {
415 termination_status_ = 421 termination_status_ =
416 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_); 422 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
417 } else { 423 } else {
418 #elif defined(OS_ANDROID) 424 #elif defined(OS_ANDROID)
(...skipping 12 matching lines...) Expand all
431 DCHECK(CalledOnValidThread()); 437 DCHECK(CalledOnValidThread());
432 base::Process to_pass = process_.Duplicate(); 438 base::Process to_pass = process_.Duplicate();
433 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 439 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
434 base::Bind(&SetProcessBackgroundedOnLauncherThread, 440 base::Bind(&SetProcessBackgroundedOnLauncherThread,
435 base::Passed(&to_pass), background)); 441 base::Passed(&to_pass), background));
436 } 442 }
437 443
438 void ChildProcessLauncher::DidLaunch( 444 void ChildProcessLauncher::DidLaunch(
439 base::WeakPtr<ChildProcessLauncher> instance, 445 base::WeakPtr<ChildProcessLauncher> instance,
440 bool terminate_on_shutdown, 446 bool terminate_on_shutdown,
441 bool zygote, 447 ZygoteHandle zygote,
442 #if defined(OS_ANDROID) 448 #if defined(OS_ANDROID)
443 base::ScopedFD ipcfd, 449 base::ScopedFD ipcfd,
444 #endif 450 #endif
445 base::Process process) { 451 base::Process process) {
446 if (!process.IsValid()) 452 if (!process.IsValid())
447 LOG(ERROR) << "Failed to launch child process"; 453 LOG(ERROR) << "Failed to launch child process";
448 454
449 if (instance.get()) { 455 if (instance.get()) {
450 instance->Notify(zygote, 456 instance->Notify(zygote,
451 #if defined(OS_ANDROID) 457 #if defined(OS_ANDROID)
452 std::move(ipcfd), 458 std::move(ipcfd),
453 #endif 459 #endif
454 std::move(process)); 460 std::move(process));
455 } else { 461 } else {
456 if (process.IsValid() && terminate_on_shutdown) { 462 if (process.IsValid() && terminate_on_shutdown) {
457 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So 463 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So
458 // don't this on the UI/IO threads. 464 // don't this on the UI/IO threads.
459 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 465 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
460 base::Bind(&TerminateOnLauncherThread, zygote, 466 base::Bind(&TerminateOnLauncherThread, zygote,
461 base::Passed(&process))); 467 base::Passed(&process)));
462 } 468 }
463 } 469 }
464 } 470 }
465 471
466 void ChildProcessLauncher::Notify( 472 void ChildProcessLauncher::Notify(ZygoteHandle zygote,
467 bool zygote,
468 #if defined(OS_ANDROID) 473 #if defined(OS_ANDROID)
469 base::ScopedFD ipcfd, 474 base::ScopedFD ipcfd,
470 #endif 475 #endif
471 base::Process process) { 476 base::Process process) {
472 DCHECK(CalledOnValidThread()); 477 DCHECK(CalledOnValidThread());
473 starting_ = false; 478 starting_ = false;
474 process_ = std::move(process); 479 process_ = std::move(process);
475 480
476 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 481 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
477 zygote_ = zygote; 482 zygote_ = zygote;
478 #endif 483 #endif
479 if (process_.IsValid()) { 484 if (process_.IsValid()) {
480 client_->OnProcessLaunched(); 485 client_->OnProcessLaunched();
481 } else { 486 } else {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 } 529 }
525 530
526 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( 531 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
527 Client* client) { 532 Client* client) {
528 Client* ret = client_; 533 Client* ret = client_;
529 client_ = client; 534 client_ = client;
530 return ret; 535 return ret;
531 } 536 }
532 537
533 } // namespace content 538 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698