blob: a119ec37bf24276cf5497883d5f1c251526a9c25 [file] [log] [blame]
[email protected]1e67c2b2011-03-04 01:17:371// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]d032f492009-09-29 00:33:462// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "build/build_config.h"
6
[email protected]e15a4fa2010-02-11 23:09:297#include "chrome/browser/nacl_host/nacl_process_host.h"
[email protected]d032f492009-09-29 00:33:468
9#if defined(OS_POSIX)
10#include <fcntl.h>
11#endif
12
[email protected]30c1eea2011-10-17 18:40:3013#include "base/bind.h"
[email protected]103607e2010-02-01 18:57:0914#include "base/command_line.h"
[email protected]338466a82011-05-03 04:27:4315#include "base/path_service.h"
[email protected]a0a69bf2011-09-23 21:40:2816#include "base/stringprintf.h"
[email protected]be1ce6a72010-08-03 14:35:2217#include "base/utf_string_conversions.h"
[email protected]1e67c2b2011-03-04 01:17:3718#include "base/win/windows_version.h"
[email protected]338466a82011-05-03 04:27:4319#include "chrome/common/chrome_paths.h"
[email protected]d032f492009-09-29 00:33:4620#include "chrome/common/chrome_switches.h"
21#include "chrome/common/logging_chrome.h"
[email protected]103607e2010-02-01 18:57:0922#include "chrome/common/nacl_cmd_line.h"
[email protected]d032f492009-09-29 00:33:4623#include "chrome/common/nacl_messages.h"
[email protected]fb1277e82009-11-21 20:32:3024#include "chrome/common/render_messages.h"
[email protected]92d56412011-03-24 20:53:5225#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]d032f492009-09-29 00:33:4626#include "ipc/ipc_switches.h"
[email protected]1d8a3d1f2011-02-19 07:11:5227#include "native_client/src/shared/imc/nacl_imc.h"
[email protected]d032f492009-09-29 00:33:4628
[email protected]d032f492009-09-29 00:33:4629#if defined(OS_POSIX)
30#include "ipc/ipc_channel_posix.h"
[email protected]4bdde602010-06-16 03:17:3531#elif defined(OS_WIN)
32#include "chrome/browser/nacl_host/nacl_broker_service_win.h"
[email protected]d032f492009-09-29 00:33:4633#endif
34
[email protected]631bb742011-11-02 11:29:3935using content::BrowserThread;
36
[email protected]c47ec402010-07-29 10:20:4937namespace {
38
[email protected]ba077002010-09-27 15:22:3039#if !defined(DISABLE_NACL)
[email protected]c47ec402010-07-29 10:20:4940void SetCloseOnExec(nacl::Handle fd) {
41#if defined(OS_POSIX)
42 int flags = fcntl(fd, F_GETFD);
[email protected]773ebb92011-11-15 19:06:5243 CHECK_NE(flags, -1);
[email protected]c47ec402010-07-29 10:20:4944 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
[email protected]773ebb92011-11-15 19:06:5245 CHECK_EQ(rc, 0);
[email protected]c47ec402010-07-29 10:20:4946#endif
47}
[email protected]ba077002010-09-27 15:22:3048#endif
[email protected]c47ec402010-07-29 10:20:4949
[email protected]773ebb92011-11-15 19:06:5250// Represents shared state for all NaClProcessHost objects in the browser.
51// Currently this just handles holding onto the file descriptor for the IRT.
52class NaClBrowser {
53 public:
54 static NaClBrowser* GetInstance() {
55 return Singleton<NaClBrowser>::get();
56 }
57
58 bool IrtAvailable() const {
59 return irt_platform_file_ != base::kInvalidPlatformFileValue;
60 }
61
62 base::PlatformFile IrtFile() const {
63 CHECK_NE(irt_platform_file_, base::kInvalidPlatformFileValue);
64 return irt_platform_file_;
65 }
66
67 // Asynchronously attempt to get the IRT open.
68 bool EnsureIrtAvailable();
69
70 // Make sure the IRT gets opened and follow up with the reply when it's ready.
71 bool MakeIrtAvailable(const base::Closure& reply);
72
73 private:
74 base::PlatformFile irt_platform_file_;
75
76 friend struct DefaultSingletonTraits<NaClBrowser>;
77
78 NaClBrowser()
79 : irt_platform_file_(base::kInvalidPlatformFileValue)
80 {}
81
82 ~NaClBrowser() {
83 if (irt_platform_file_ != base::kInvalidPlatformFileValue)
84 base::ClosePlatformFile(irt_platform_file_);
85 }
86
87 void OpenIrtLibraryFile();
88
89 static void DoOpenIrtLibraryFile() {
90 GetInstance()->OpenIrtLibraryFile();
91 }
92
93 DISALLOW_COPY_AND_ASSIGN(NaClBrowser);
94};
95
[email protected]c47ec402010-07-29 10:20:4996} // namespace
97
[email protected]1d8a3d1f2011-02-19 07:11:5298struct NaClProcessHost::NaClInternal {
99 std::vector<nacl::Handle> sockets_for_renderer;
100 std::vector<nacl::Handle> sockets_for_sel_ldr;
101};
102
[email protected]773ebb92011-11-15 19:06:52103static bool RunningOnWOW64() {
104#if defined(OS_WIN)
105 return (base::win::OSInfo::GetInstance()->wow64_status() ==
106 base::win::OSInfo::WOW64_ENABLED);
107#else
108 return false;
109#endif
110}
111
[email protected]1dbaaa702011-04-06 17:43:42112NaClProcessHost::NaClProcessHost(const std::wstring& url)
[email protected]5afcf6882011-04-08 20:11:15113 : BrowserChildProcessHost(NACL_LOADER_PROCESS),
[email protected]fb1277e82009-11-21 20:32:30114 reply_msg_(NULL),
[email protected]1d8a3d1f2011-02-19 07:11:52115 internal_(new NaClInternal()),
[email protected]30c1eea2011-10-17 18:40:30116 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
[email protected]68b9e72b2011-08-05 23:08:22117 set_name(WideToUTF16Hack(url));
[email protected]d032f492009-09-29 00:33:46118}
119
[email protected]fb1277e82009-11-21 20:32:30120NaClProcessHost::~NaClProcessHost() {
[email protected]990b29e2010-07-29 12:53:47121 // nacl::Close() is not available at link time if DISABLE_NACL is
122 // defined, but we still compile a bunch of other code from this
123 // file anyway. TODO(mseaborn): Make this less messy.
124#ifndef DISABLE_NACL
[email protected]1d8a3d1f2011-02-19 07:11:52125 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
[email protected]909c2402011-05-09 11:39:04126 if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) {
127 LOG(ERROR) << "nacl::Close() failed";
128 }
[email protected]c47ec402010-07-29 10:20:49129 }
[email protected]1d8a3d1f2011-02-19 07:11:52130 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
[email protected]909c2402011-05-09 11:39:04131 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) {
132 LOG(ERROR) << "nacl::Close() failed";
133 }
[email protected]c47ec402010-07-29 10:20:49134 }
[email protected]990b29e2010-07-29 12:53:47135#endif
[email protected]c47ec402010-07-29 10:20:49136
[email protected]909c2402011-05-09 11:39:04137 if (reply_msg_) {
138 // The process failed to launch for some reason.
139 // Don't keep the renderer hanging.
140 reply_msg_->set_reply_error();
141 chrome_render_message_filter_->Send(reply_msg_);
142 }
[email protected]fb1277e82009-11-21 20:32:30143}
144
[email protected]773ebb92011-11-15 19:06:52145// Attempt to ensure the IRT will be available when we need it, but don't wait.
146bool NaClBrowser::EnsureIrtAvailable() {
147 if (IrtAvailable())
148 return true;
149
150 return BrowserThread::PostTask(
151 BrowserThread::FILE, FROM_HERE,
152 base::Bind(&NaClBrowser::DoOpenIrtLibraryFile));
153}
154
155// We really need the IRT to be available now, so make sure that it is.
156// When it's ready, we'll run the reply closure.
157bool NaClBrowser::MakeIrtAvailable(const base::Closure& reply) {
158 return BrowserThread::PostTaskAndReply(
159 BrowserThread::FILE, FROM_HERE,
160 base::Bind(&NaClBrowser::DoOpenIrtLibraryFile), reply);
161}
162
163// This is called at browser startup.
164// static
165void NaClProcessHost::EarlyStartup() {
166#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
167 // Open the IRT file early to make sure that it isn't replaced out from
168 // under us by autoupdate.
169 NaClBrowser::GetInstance()->EnsureIrtAvailable();
170#endif
171}
172
[email protected]92d56412011-03-24 20:53:52173bool NaClProcessHost::Launch(
174 ChromeRenderMessageFilter* chrome_render_message_filter,
175 int socket_count,
176 IPC::Message* reply_msg) {
[email protected]d8c7cbcc2009-10-02 19:00:31177#ifdef DISABLE_NACL
178 NOTIMPLEMENTED() << "Native Client disabled at build time";
179 return false;
180#else
[email protected]c47ec402010-07-29 10:20:49181 // Place an arbitrary limit on the number of sockets to limit
182 // exposure in case the renderer is compromised. We can increase
183 // this if necessary.
184 if (socket_count > 8) {
[email protected]d032f492009-09-29 00:33:46185 return false;
[email protected]c47ec402010-07-29 10:20:49186 }
187
[email protected]773ebb92011-11-15 19:06:52188 // Start getting the IRT open asynchronously while we launch the NaCl process.
189 // We'll make sure this actually finished in OnProcessLaunched, below.
190 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) {
191 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
192 return false;
193 }
194
[email protected]c47ec402010-07-29 10:20:49195 // Rather than creating a socket pair in the renderer, and passing
196 // one side through the browser to sel_ldr, socket pairs are created
197 // in the browser and then passed to the renderer and sel_ldr.
198 //
199 // This is mainly for the benefit of Windows, where sockets cannot
200 // be passed in messages, but are copied via DuplicateHandle().
201 // This means the sandboxed renderer cannot send handles to the
202 // browser process.
203
204 for (int i = 0; i < socket_count; i++) {
205 nacl::Handle pair[2];
206 // Create a connected socket
207 if (nacl::SocketPair(pair) == -1)
208 return false;
[email protected]1d8a3d1f2011-02-19 07:11:52209 internal_->sockets_for_renderer.push_back(pair[0]);
210 internal_->sockets_for_sel_ldr.push_back(pair[1]);
[email protected]c47ec402010-07-29 10:20:49211 SetCloseOnExec(pair[0]);
212 SetCloseOnExec(pair[1]);
213 }
[email protected]d032f492009-09-29 00:33:46214
215 // Launch the process
[email protected]fb1277e82009-11-21 20:32:30216 if (!LaunchSelLdr()) {
[email protected]d032f492009-09-29 00:33:46217 return false;
218 }
[email protected]92d56412011-03-24 20:53:52219 chrome_render_message_filter_ = chrome_render_message_filter;
[email protected]fb1277e82009-11-21 20:32:30220 reply_msg_ = reply_msg;
[email protected]f08e47d2009-10-15 21:46:15221
[email protected]d032f492009-09-29 00:33:46222 return true;
[email protected]d8c7cbcc2009-10-02 19:00:31223#endif // DISABLE_NACL
[email protected]d032f492009-09-29 00:33:46224}
225
[email protected]fb1277e82009-11-21 20:32:30226bool NaClProcessHost::LaunchSelLdr() {
[email protected]d032f492009-09-29 00:33:46227 if (!CreateChannel())
228 return false;
229
[email protected]e3fc75a2011-05-05 08:20:42230 CommandLine::StringType nacl_loader_prefix;
231#if defined(OS_POSIX)
232 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative(
233 switches::kNaClLoaderCmdPrefix);
234#endif // defined(OS_POSIX)
235
[email protected]d032f492009-09-29 00:33:46236 // Build command line for nacl.
[email protected]8c40f322011-08-24 03:33:36237
238#if defined(OS_MACOSX)
239 // The Native Client process needs to be able to allocate a 1GB contiguous
240 // region to use as the client environment's virtual address space. ASLR
241 // (PIE) interferes with this by making it possible that no gap large enough
242 // to accomodate this request will exist in the child process' address
243 // space. Disable PIE for NaCl processes. See http://crbug.com/90221 and
244 // http://code.google.com/p/nativeclient/issues/detail?id=2043.
245 int flags = CHILD_NO_PIE;
246#elif defined(OS_LINUX)
247 int flags = nacl_loader_prefix.empty() ? CHILD_ALLOW_SELF : CHILD_NORMAL;
248#else
249 int flags = CHILD_NORMAL;
250#endif
251
252 FilePath exe_path = GetChildPath(flags);
[email protected]fb1277e82009-11-21 20:32:30253 if (exe_path.empty())
[email protected]d032f492009-09-29 00:33:46254 return false;
255
[email protected]fb1277e82009-11-21 20:32:30256 CommandLine* cmd_line = new CommandLine(exe_path);
[email protected]103607e2010-02-01 18:57:09257 nacl::CopyNaClCommandLineArguments(cmd_line);
[email protected]599e6642010-01-27 18:52:13258
[email protected]05076ba22010-07-30 05:59:57259 cmd_line->AppendSwitchASCII(switches::kProcessType,
260 switches::kNaClLoaderProcess);
[email protected]05076ba22010-07-30 05:59:57261 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
[email protected]93156cec2011-09-12 21:14:44262 if (logging::DialogsAreSuppressed())
263 cmd_line->AppendSwitch(switches::kNoErrorDialogs);
[email protected]d032f492009-09-29 00:33:46264
[email protected]e3fc75a2011-05-05 08:20:42265 if (!nacl_loader_prefix.empty())
266 cmd_line->PrependWrapper(nacl_loader_prefix);
267
[email protected]103607e2010-02-01 18:57:09268 // On Windows we might need to start the broker process to launch a new loader
[email protected]d032f492009-09-29 00:33:46269#if defined(OS_WIN)
[email protected]773ebb92011-11-15 19:06:52270 if (RunningOnWOW64()) {
[email protected]1dbaaa702011-04-06 17:43:42271 return NaClBrokerService::GetInstance()->LaunchLoader(
272 this, ASCIIToWide(channel_id()));
[email protected]4bdde602010-06-16 03:17:35273 } else {
[email protected]d27893f62010-07-03 05:47:42274 BrowserChildProcessHost::Launch(FilePath(), cmd_line);
[email protected]4bdde602010-06-16 03:17:35275 }
[email protected]103607e2010-02-01 18:57:09276#elif defined(OS_POSIX)
[email protected]e3fc75a2011-05-05 08:20:42277 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote
[email protected]d27893f62010-07-03 05:47:42278 base::environment_vector(),
279 cmd_line);
[email protected]103607e2010-02-01 18:57:09280#endif
[email protected]d032f492009-09-29 00:33:46281
[email protected]fb1277e82009-11-21 20:32:30282 return true;
[email protected]d032f492009-09-29 00:33:46283}
284
[email protected]103607e2010-02-01 18:57:09285void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
286 set_handle(handle);
287 OnProcessLaunched();
288}
289
[email protected]443b80e2010-12-14 00:42:23290base::TerminationStatus NaClProcessHost::GetChildTerminationStatus(
291 int* exit_code) {
[email protected]773ebb92011-11-15 19:06:52292 if (RunningOnWOW64())
[email protected]443b80e2010-12-14 00:42:23293 return base::GetTerminationStatus(handle(), exit_code);
294 return BrowserChildProcessHost::GetChildTerminationStatus(exit_code);
[email protected]103607e2010-02-01 18:57:09295}
296
[email protected]16e70ae2010-03-08 21:41:28297void NaClProcessHost::OnChildDied() {
[email protected]a0a69bf2011-09-23 21:40:28298 int exit_code;
299 GetChildTerminationStatus(&exit_code);
300 std::string message =
301 base::StringPrintf("NaCl process exited with status %i (0x%x)",
302 exit_code, exit_code);
303 if (exit_code == 0) {
304 LOG(INFO) << message;
305 } else {
306 LOG(ERROR) << message;
307 }
308
[email protected]16e70ae2010-03-08 21:41:28309#if defined(OS_WIN)
310 NaClBrokerService::GetInstance()->OnLoaderDied();
311#endif
[email protected]d27893f62010-07-03 05:47:42312 BrowserChildProcessHost::OnChildDied();
[email protected]16e70ae2010-03-08 21:41:28313}
314
[email protected]773ebb92011-11-15 19:06:52315// This only ever runs on the BrowserThread::FILE thread.
316// If multiple tasks are posted, the later ones are no-ops.
317void NaClBrowser::OpenIrtLibraryFile() {
318 if (irt_platform_file_ != base::kInvalidPlatformFileValue)
319 // We've already run.
320 return;
[email protected]338466a82011-05-03 04:27:43321
[email protected]773ebb92011-11-15 19:06:52322 FilePath irt_filepath;
323
[email protected]88e15832011-07-19 01:18:24324 // Allow the IRT library to be overridden via an environment
325 // variable. This allows the NaCl/Chromium integration bot to
326 // specify a newly-built IRT rather than using a prebuilt one
327 // downloaded via Chromium's DEPS file. We use the same environment
328 // variable that the standalone NaCl PPAPI plugin accepts.
329 const char* irt_path_var = getenv("NACL_IRT_LIBRARY");
330 if (irt_path_var != NULL) {
[email protected]773ebb92011-11-15 19:06:52331 FilePath::StringType path_string(
332 irt_path_var, const_cast<const char*>(strchr(irt_path_var, '\0')));
333 irt_filepath = FilePath(path_string);
[email protected]88e15832011-07-19 01:18:24334 } else {
335 FilePath plugin_dir;
336 if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) {
337 LOG(ERROR) << "Failed to locate the plugins directory";
[email protected]88e15832011-07-19 01:18:24338 return;
339 }
[email protected]773ebb92011-11-15 19:06:52340
341 bool on_x86_64 = RunningOnWOW64();
342#if defined(__x86_64__)
343 on_x86_64 = true;
344#endif
345 FilePath::StringType irt_name;
346 if (on_x86_64) {
347 irt_name = FILE_PATH_LITERAL("nacl_irt_x86_64.nexe");
348 } else {
349 irt_name = FILE_PATH_LITERAL("nacl_irt_x86_32.nexe");
350 }
351
352 irt_filepath = plugin_dir.Append(irt_name);
[email protected]338466a82011-05-03 04:27:43353 }
[email protected]88e15832011-07-19 01:18:24354
[email protected]773ebb92011-11-15 19:06:52355 base::PlatformFileError error_code;
356 irt_platform_file_ = base::CreatePlatformFile(irt_filepath,
357 base::PLATFORM_FILE_OPEN |
358 base::PLATFORM_FILE_READ,
359 NULL,
360 &error_code);
361 if (error_code != base::PLATFORM_FILE_OK) {
362 LOG(ERROR) << "Failed to open NaCl IRT file \""
363 << irt_filepath.LossyDisplayName()
364 << "\": " << error_code;
365 }
366}
367
368void NaClProcessHost::OnProcessLaunched() {
369 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
370
371 if (nacl_browser->IrtAvailable()) {
372 // The IRT is already open. Away we go.
373 SendStart(nacl_browser->IrtFile());
374 } else {
375 // We're waiting for the IRT to be open.
376 nacl_browser->MakeIrtAvailable(base::Bind(&NaClProcessHost::IrtReady,
377 weak_factory_.GetWeakPtr()));
378 }
379}
380
381// The asynchronous attempt to get the IRT file open has completed.
382void NaClProcessHost::IrtReady() {
383 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
384
385 if (nacl_browser->IrtAvailable()) {
386 SendStart(nacl_browser->IrtFile());
387 } else {
388 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
[email protected]338466a82011-05-03 04:27:43389 delete this;
390 }
391}
392
[email protected]773ebb92011-11-15 19:06:52393static bool SendHandleToSelLdr(
394 base::ProcessHandle processh,
395 nacl::Handle sourceh, bool close_source,
396 std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) {
397#if defined(OS_WIN)
398 HANDLE channel;
399 int flags = DUPLICATE_SAME_ACCESS;
400 if (close_source)
401 flags |= DUPLICATE_CLOSE_SOURCE;
402 if (!DuplicateHandle(GetCurrentProcess(),
403 reinterpret_cast<HANDLE>(sourceh),
404 processh,
405 &channel,
406 0, // Unused given DUPLICATE_SAME_ACCESS.
407 FALSE,
408 flags)) {
409 LOG(ERROR) << "DuplicateHandle() failed";
410 return false;
411 }
412 handles_for_sel_ldr->push_back(
413 reinterpret_cast<nacl::FileDescriptor>(channel));
414#else
415 nacl::FileDescriptor channel;
416 channel.fd = sourceh;
417 channel.auto_close = close_source;
418 handles_for_sel_ldr->push_back(channel);
419#endif
420 return true;
421}
422
423void NaClProcessHost::SendStart(base::PlatformFile irt_file) {
424 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
425
[email protected]c47ec402010-07-29 10:20:49426 std::vector<nacl::FileDescriptor> handles_for_renderer;
[email protected]fb1277e82009-11-21 20:32:30427 base::ProcessHandle nacl_process_handle;
[email protected]fb1277e82009-11-21 20:32:30428
[email protected]1d8a3d1f2011-02-19 07:11:52429 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
[email protected]c47ec402010-07-29 10:20:49430#if defined(OS_WIN)
431 // Copy the handle into the renderer process.
432 HANDLE handle_in_renderer;
[email protected]909c2402011-05-09 11:39:04433 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
434 reinterpret_cast<HANDLE>(
435 internal_->sockets_for_renderer[i]),
436 chrome_render_message_filter_->peer_handle(),
437 &handle_in_renderer,
438 0, // Unused given DUPLICATE_SAME_ACCESS.
439 FALSE,
440 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
441 LOG(ERROR) << "DuplicateHandle() failed";
442 delete this;
443 return;
444 }
[email protected]c47ec402010-07-29 10:20:49445 handles_for_renderer.push_back(
446 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
447#else
448 // No need to dup the imc_handle - we don't pass it anywhere else so
449 // it cannot be closed.
450 nacl::FileDescriptor imc_handle;
[email protected]1d8a3d1f2011-02-19 07:11:52451 imc_handle.fd = internal_->sockets_for_renderer[i];
[email protected]c47ec402010-07-29 10:20:49452 imc_handle.auto_close = true;
453 handles_for_renderer.push_back(imc_handle);
454#endif
455 }
456
457#if defined(OS_WIN)
458 // Copy the process handle into the renderer process.
[email protected]909c2402011-05-09 11:39:04459 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
460 handle(),
461 chrome_render_message_filter_->peer_handle(),
462 &nacl_process_handle,
463 PROCESS_DUP_HANDLE,
464 FALSE,
465 0)) {
466 LOG(ERROR) << "DuplicateHandle() failed";
467 delete this;
468 return;
469 }
[email protected]fb1277e82009-11-21 20:32:30470#else
[email protected]fb1277e82009-11-21 20:32:30471 // We use pid as process handle on Posix
472 nacl_process_handle = handle();
[email protected]fb1277e82009-11-21 20:32:30473#endif
474
475 // Get the pid of the NaCl process
476 base::ProcessId nacl_process_id = base::GetProcId(handle());
477
[email protected]2ccf45c2011-08-19 23:35:50478 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
[email protected]c47ec402010-07-29 10:20:49479 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id);
[email protected]92d56412011-03-24 20:53:52480 chrome_render_message_filter_->Send(reply_msg_);
481 chrome_render_message_filter_ = NULL;
[email protected]fb1277e82009-11-21 20:32:30482 reply_msg_ = NULL;
[email protected]1d8a3d1f2011-02-19 07:11:52483 internal_->sockets_for_renderer.clear();
[email protected]fb1277e82009-11-21 20:32:30484
[email protected]c47ec402010-07-29 10:20:49485 std::vector<nacl::FileDescriptor> handles_for_sel_ldr;
[email protected]1d8a3d1f2011-02-19 07:11:52486 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
[email protected]773ebb92011-11-15 19:06:52487 if (!SendHandleToSelLdr(handle(),
488 internal_->sockets_for_sel_ldr[i], true,
489 &handles_for_sel_ldr)) {
[email protected]909c2402011-05-09 11:39:04490 delete this;
[email protected]c47ec402010-07-29 10:20:49491 return;
492 }
[email protected]773ebb92011-11-15 19:06:52493 }
494
495 // Send over the IRT file handle. We don't close our own copy!
496 if (!SendHandleToSelLdr(handle(), irt_file, false, &handles_for_sel_ldr)) {
497 delete this;
498 return;
[email protected]c47ec402010-07-29 10:20:49499 }
500
[email protected]c783bc52011-11-16 21:58:37501#if defined(OS_POSIX)
502 // For dynamic loading support, NaCl requires a file descriptor on an
503 // anonymous file that can have PROT_EXEC applied to its mappings.
[email protected]cbbe7842011-11-17 22:01:25504 // Rather than requiring an extra IPC round trip out of the sandbox,
505 // we create an FD here.
506 base::SharedMemory memory_buffer;
507 if (!memory_buffer.CreateAnonymous(/* size= */ 1)) {
[email protected]2c68bf032010-11-11 23:16:30508 LOG(ERROR) << "Failed to allocate memory buffer";
[email protected]909c2402011-05-09 11:39:04509 delete this;
[email protected]2c68bf032010-11-11 23:16:30510 return;
511 }
[email protected]cbbe7842011-11-17 22:01:25512 nacl::FileDescriptor memory_fd;
513 memory_fd.fd = dup(memory_buffer.handle().fd);
514 if (memory_fd.fd < 0) {
515 LOG(ERROR) << "Failed to dup() a file descriptor";
516 delete this;
517 return;
518 }
519 memory_fd.auto_close = true;
[email protected]2c68bf032010-11-11 23:16:30520 handles_for_sel_ldr.push_back(memory_fd);
521#endif
522
[email protected]773ebb92011-11-15 19:06:52523 Send(new NaClProcessMsg_Start(handles_for_sel_ldr));
[email protected]1d8a3d1f2011-02-19 07:11:52524 internal_->sockets_for_sel_ldr.clear();
[email protected]d032f492009-09-29 00:33:46525}
526
[email protected]a95986a82010-12-24 06:19:28527bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
[email protected]d032f492009-09-29 00:33:46528 NOTREACHED() << "Invalid message with type = " << msg.type();
[email protected]a95986a82010-12-24 06:19:28529 return false;
[email protected]d032f492009-09-29 00:33:46530}
531
[email protected]e4be2dd2010-12-14 00:44:39532bool NaClProcessHost::CanShutdown() {
533 return true;
534}