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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 9748012: Fix memory leak when errors happens in NaClProcessHost::Launch. Allow Launch to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
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 "chrome/browser/nacl_host/nacl_process_host.h" 5 #include "chrome/browser/nacl_host/nacl_process_host.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 }; 228 };
229 229
230 #if defined(OS_WIN) 230 #if defined(OS_WIN)
231 static bool RunningOnWOW64() { 231 static bool RunningOnWOW64() {
232 return (base::win::OSInfo::GetInstance()->wow64_status() == 232 return (base::win::OSInfo::GetInstance()->wow64_status() ==
233 base::win::OSInfo::WOW64_ENABLED); 233 base::win::OSInfo::WOW64_ENABLED);
234 } 234 }
235 #endif 235 #endif
236 236
237 NaClProcessHost::NaClProcessHost(const std::wstring& url) 237 NaClProcessHost::NaClProcessHost(const std::wstring& url)
238 : reply_msg_(NULL), 238 :
239 #if defined(OS_WIN)
240 process_launched_by_broker_(false),
241 #endif
242 reply_msg_(NULL),
239 internal_(new NaClInternal()), 243 internal_(new NaClInternal()),
240 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 244 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
241 enable_exception_handling_(false) { 245 enable_exception_handling_(false) {
242 process_.reset(content::BrowserChildProcessHost::Create( 246 process_.reset(content::BrowserChildProcessHost::Create(
243 content::PROCESS_TYPE_NACL_LOADER, this)); 247 content::PROCESS_TYPE_NACL_LOADER, this));
244 process_->SetName(WideToUTF16Hack(url)); 248 process_->SetName(WideToUTF16Hack(url));
245 249
246 // We allow untrusted hardware exception handling to be enabled via 250 // We allow untrusted hardware exception handling to be enabled via
247 // an env var for consistency with the standalone build of NaCl. 251 // an env var for consistency with the standalone build of NaCl.
248 if (CommandLine::ForCurrentProcess()->HasSwitch( 252 if (CommandLine::ForCurrentProcess()->HasSwitch(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 284 }
281 } 285 }
282 286
283 if (reply_msg_) { 287 if (reply_msg_) {
284 // The process failed to launch for some reason. 288 // The process failed to launch for some reason.
285 // Don't keep the renderer hanging. 289 // Don't keep the renderer hanging.
286 reply_msg_->set_reply_error(); 290 reply_msg_->set_reply_error();
287 chrome_render_message_filter_->Send(reply_msg_); 291 chrome_render_message_filter_->Send(reply_msg_);
288 } 292 }
289 #if defined(OS_WIN) 293 #if defined(OS_WIN)
290 if (RunningOnWOW64()) { 294 if (process_launched_by_broker_) {
291 // If the nacl-gdb switch is not empty, the NaCl loader has been launched 295 NaClBrokerService::GetInstance()->OnLoaderDied();
292 // without the broker and so we shouldn't inform the broker about
293 // the loader termination.
294 if (CommandLine::ForCurrentProcess()->GetSwitchValuePath(
295 switches::kNaClGdb).empty()) {
296 NaClBrokerService::GetInstance()->OnLoaderDied();
297 }
298 } 296 }
299 if (debug_context_ != NULL) { 297 if (debug_context_ != NULL) {
300 debug_context_->SetChildProcessHost(NULL); 298 debug_context_->SetChildProcessHost(NULL);
301 } 299 }
302 #endif 300 #endif
303 } 301 }
304 302
305 // Attempt to ensure the IRT will be available when we need it, but don't wait. 303 // Attempt to ensure the IRT will be available when we need it, but don't wait.
306 bool NaClBrowser::EnsureIrtAvailable() { 304 bool NaClBrowser::EnsureIrtAvailable() {
307 if (IrtAvailable()) 305 if (IrtAvailable())
(...skipping 15 matching lines...) Expand all
323 // This is called at browser startup. 321 // This is called at browser startup.
324 // static 322 // static
325 void NaClProcessHost::EarlyStartup() { 323 void NaClProcessHost::EarlyStartup() {
326 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 324 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
327 // Open the IRT file early to make sure that it isn't replaced out from 325 // Open the IRT file early to make sure that it isn't replaced out from
328 // under us by autoupdate. 326 // under us by autoupdate.
329 NaClBrowser::GetInstance()->EnsureIrtAvailable(); 327 NaClBrowser::GetInstance()->EnsureIrtAvailable();
330 #endif 328 #endif
331 } 329 }
332 330
333 bool NaClProcessHost::Launch( 331 void NaClProcessHost::Launch(
334 ChromeRenderMessageFilter* chrome_render_message_filter, 332 ChromeRenderMessageFilter* chrome_render_message_filter,
335 int socket_count, 333 int socket_count,
336 IPC::Message* reply_msg) { 334 IPC::Message* reply_msg) {
335 chrome_render_message_filter_ = chrome_render_message_filter;
336 reply_msg_ = reply_msg;
337
337 // Place an arbitrary limit on the number of sockets to limit 338 // Place an arbitrary limit on the number of sockets to limit
338 // exposure in case the renderer is compromised. We can increase 339 // exposure in case the renderer is compromised. We can increase
339 // this if necessary. 340 // this if necessary.
340 if (socket_count > 8) { 341 if (socket_count > 8) {
341 return false; 342 delete this;
343 return;
342 } 344 }
343 345
344 // Start getting the IRT open asynchronously while we launch the NaCl process. 346 // Start getting the IRT open asynchronously while we launch the NaCl process.
345 // We'll make sure this actually finished in OnProcessLaunched, below. 347 // We'll make sure this actually finished in OnProcessLaunched, below.
346 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) { 348 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) {
347 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed"; 349 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
348 return false; 350 delete this;
351 return;
349 } 352 }
350 353
351 // Rather than creating a socket pair in the renderer, and passing 354 // Rather than creating a socket pair in the renderer, and passing
352 // one side through the browser to sel_ldr, socket pairs are created 355 // one side through the browser to sel_ldr, socket pairs are created
353 // in the browser and then passed to the renderer and sel_ldr. 356 // in the browser and then passed to the renderer and sel_ldr.
354 // 357 //
355 // This is mainly for the benefit of Windows, where sockets cannot 358 // This is mainly for the benefit of Windows, where sockets cannot
356 // be passed in messages, but are copied via DuplicateHandle(). 359 // be passed in messages, but are copied via DuplicateHandle().
357 // This means the sandboxed renderer cannot send handles to the 360 // This means the sandboxed renderer cannot send handles to the
358 // browser process. 361 // browser process.
359 362
360 for (int i = 0; i < socket_count; i++) { 363 for (int i = 0; i < socket_count; i++) {
361 nacl::Handle pair[2]; 364 nacl::Handle pair[2];
362 // Create a connected socket 365 // Create a connected socket
363 if (nacl::SocketPair(pair) == -1) 366 if (nacl::SocketPair(pair) == -1) {
364 return false; 367 delete this;
368 return;
369 }
365 internal_->sockets_for_renderer.push_back(pair[0]); 370 internal_->sockets_for_renderer.push_back(pair[0]);
366 internal_->sockets_for_sel_ldr.push_back(pair[1]); 371 internal_->sockets_for_sel_ldr.push_back(pair[1]);
367 SetCloseOnExec(pair[0]); 372 SetCloseOnExec(pair[0]);
368 SetCloseOnExec(pair[1]); 373 SetCloseOnExec(pair[1]);
369 } 374 }
370 375
371 // Launch the process 376 // Launch the process
372 if (!LaunchSelLdr()) { 377 if (!LaunchSelLdr()) {
373 return false; 378 delete this;
374 } 379 }
375
376 chrome_render_message_filter_ = chrome_render_message_filter;
377
378 // On success, we take responsibility for sending the reply.
379 reply_msg_ = reply_msg;
380 return true;
381 } 380 }
382 381
383 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb( 382 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb(
384 const FilePath& nacl_gdb, CommandLine* line) { 383 const FilePath& nacl_gdb, CommandLine* line) {
385 CommandLine* cmd_line = new CommandLine(nacl_gdb); 384 CommandLine* cmd_line = new CommandLine(nacl_gdb);
386 // We can't use PrependWrapper because our parameters contain spaces. 385 // We can't use PrependWrapper because our parameters contain spaces.
387 cmd_line->AppendArg("--eval-command"); 386 cmd_line->AppendArg("--eval-command");
388 const FilePath::StringType& irt_path = 387 const FilePath::StringType& irt_path =
389 NaClBrowser::GetInstance()->GetIrtFilePath().value(); 388 NaClBrowser::GetInstance()->GetIrtFilePath().value();
390 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path); 389 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 #elif defined(OS_POSIX) 477 #elif defined(OS_POSIX)
479 process_->Launch(nacl_loader_prefix.empty(), // use_zygote 478 process_->Launch(nacl_loader_prefix.empty(), // use_zygote
480 base::EnvironmentVector(), 479 base::EnvironmentVector(),
481 cmd_line.release()); 480 cmd_line.release());
482 #endif 481 #endif
483 482
484 return true; 483 return true;
485 } 484 }
486 485
487 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { 486 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
487 #if defined(OS_WIN)
488 process_launched_by_broker_ = true;
489 #endif
488 process_->SetHandle(handle); 490 process_->SetHandle(handle);
489 OnProcessLaunched(); 491 OnProcessLaunched();
490 } 492 }
491 493
492 void NaClProcessHost::OnProcessCrashed(int exit_code) { 494 void NaClProcessHost::OnProcessCrashed(int exit_code) {
493 std::string message = base::StringPrintf( 495 std::string message = base::StringPrintf(
494 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); 496 "NaCl process exited with status %i (0x%x)", exit_code, exit_code);
495 LOG(ERROR) << message; 497 LOG(ERROR) << message;
496 } 498 }
497 499
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 process_->Send(start_message); 810 process_->Send(start_message);
809 #endif 811 #endif
810 812
811 internal_->sockets_for_sel_ldr.clear(); 813 internal_->sockets_for_sel_ldr.clear();
812 } 814 }
813 815
814 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 816 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
815 NOTREACHED() << "Invalid message with type = " << msg.type(); 817 NOTREACHED() << "Invalid message with type = " << msg.type();
816 return false; 818 return false;
817 } 819 }
OLDNEW
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/browser/renderer_host/chrome_render_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698