OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/nacl_host/nacl_process_host.h" | 7 #include "chrome/browser/nacl_host/nacl_process_host.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 22 matching lines...) Expand all Loading... |
33 #endif | 33 #endif |
34 | 34 |
35 using content::BrowserThread; | 35 using content::BrowserThread; |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 #if !defined(DISABLE_NACL) | 39 #if !defined(DISABLE_NACL) |
40 void SetCloseOnExec(nacl::Handle fd) { | 40 void SetCloseOnExec(nacl::Handle fd) { |
41 #if defined(OS_POSIX) | 41 #if defined(OS_POSIX) |
42 int flags = fcntl(fd, F_GETFD); | 42 int flags = fcntl(fd, F_GETFD); |
43 CHECK(flags != -1); | 43 CHECK_NE(flags, -1); |
44 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 44 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
45 CHECK(rc == 0); | 45 CHECK_EQ(rc, 0); |
46 #endif | 46 #endif |
47 } | 47 } |
48 #endif | 48 #endif |
49 | 49 |
| 50 // Represents shared state for all NaClProcessHost objects in the browser. |
| 51 // Currently this just handles holding onto the file descriptor for the IRT. |
| 52 class 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 |
50 } // namespace | 96 } // namespace |
51 | 97 |
52 struct NaClProcessHost::NaClInternal { | 98 struct NaClProcessHost::NaClInternal { |
53 std::vector<nacl::Handle> sockets_for_renderer; | 99 std::vector<nacl::Handle> sockets_for_renderer; |
54 std::vector<nacl::Handle> sockets_for_sel_ldr; | 100 std::vector<nacl::Handle> sockets_for_sel_ldr; |
55 }; | 101 }; |
56 | 102 |
| 103 static 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 |
57 NaClProcessHost::NaClProcessHost(const std::wstring& url) | 112 NaClProcessHost::NaClProcessHost(const std::wstring& url) |
58 : BrowserChildProcessHost(NACL_LOADER_PROCESS), | 113 : BrowserChildProcessHost(NACL_LOADER_PROCESS), |
59 reply_msg_(NULL), | 114 reply_msg_(NULL), |
60 internal_(new NaClInternal()), | 115 internal_(new NaClInternal()), |
61 running_on_wow64_(false), | |
62 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 116 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
63 set_name(WideToUTF16Hack(url)); | 117 set_name(WideToUTF16Hack(url)); |
64 #if defined(OS_WIN) | |
65 running_on_wow64_ = (base::win::OSInfo::GetInstance()->wow64_status() == | |
66 base::win::OSInfo::WOW64_ENABLED); | |
67 #endif | |
68 } | 118 } |
69 | 119 |
70 NaClProcessHost::~NaClProcessHost() { | 120 NaClProcessHost::~NaClProcessHost() { |
71 // nacl::Close() is not available at link time if DISABLE_NACL is | 121 // nacl::Close() is not available at link time if DISABLE_NACL is |
72 // defined, but we still compile a bunch of other code from this | 122 // defined, but we still compile a bunch of other code from this |
73 // file anyway. TODO(mseaborn): Make this less messy. | 123 // file anyway. TODO(mseaborn): Make this less messy. |
74 #ifndef DISABLE_NACL | 124 #ifndef DISABLE_NACL |
75 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 125 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
76 if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) { | 126 if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) { |
77 LOG(ERROR) << "nacl::Close() failed"; | 127 LOG(ERROR) << "nacl::Close() failed"; |
78 } | 128 } |
79 } | 129 } |
80 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 130 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
81 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) { | 131 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) { |
82 LOG(ERROR) << "nacl::Close() failed"; | 132 LOG(ERROR) << "nacl::Close() failed"; |
83 } | 133 } |
84 } | 134 } |
85 #endif | 135 #endif |
86 | 136 |
87 if (reply_msg_) { | 137 if (reply_msg_) { |
88 // The process failed to launch for some reason. | 138 // The process failed to launch for some reason. |
89 // Don't keep the renderer hanging. | 139 // Don't keep the renderer hanging. |
90 reply_msg_->set_reply_error(); | 140 reply_msg_->set_reply_error(); |
91 chrome_render_message_filter_->Send(reply_msg_); | 141 chrome_render_message_filter_->Send(reply_msg_); |
92 } | 142 } |
93 } | 143 } |
94 | 144 |
| 145 // Attempt to ensure the IRT will be available when we need it, but don't wait. |
| 146 bool 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. |
| 157 bool 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 |
| 165 void 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 |
95 bool NaClProcessHost::Launch( | 173 bool NaClProcessHost::Launch( |
96 ChromeRenderMessageFilter* chrome_render_message_filter, | 174 ChromeRenderMessageFilter* chrome_render_message_filter, |
97 int socket_count, | 175 int socket_count, |
98 IPC::Message* reply_msg) { | 176 IPC::Message* reply_msg) { |
99 #ifdef DISABLE_NACL | 177 #ifdef DISABLE_NACL |
100 NOTIMPLEMENTED() << "Native Client disabled at build time"; | 178 NOTIMPLEMENTED() << "Native Client disabled at build time"; |
101 return false; | 179 return false; |
102 #else | 180 #else |
103 // Place an arbitrary limit on the number of sockets to limit | 181 // Place an arbitrary limit on the number of sockets to limit |
104 // exposure in case the renderer is compromised. We can increase | 182 // exposure in case the renderer is compromised. We can increase |
105 // this if necessary. | 183 // this if necessary. |
106 if (socket_count > 8) { | 184 if (socket_count > 8) { |
107 return false; | 185 return false; |
108 } | 186 } |
109 | 187 |
| 188 // 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 |
110 // Rather than creating a socket pair in the renderer, and passing | 195 // Rather than creating a socket pair in the renderer, and passing |
111 // one side through the browser to sel_ldr, socket pairs are created | 196 // one side through the browser to sel_ldr, socket pairs are created |
112 // in the browser and then passed to the renderer and sel_ldr. | 197 // in the browser and then passed to the renderer and sel_ldr. |
113 // | 198 // |
114 // This is mainly for the benefit of Windows, where sockets cannot | 199 // This is mainly for the benefit of Windows, where sockets cannot |
115 // be passed in messages, but are copied via DuplicateHandle(). | 200 // be passed in messages, but are copied via DuplicateHandle(). |
116 // This means the sandboxed renderer cannot send handles to the | 201 // This means the sandboxed renderer cannot send handles to the |
117 // browser process. | 202 // browser process. |
118 | 203 |
119 for (int i = 0; i < socket_count; i++) { | 204 for (int i = 0; i < socket_count; i++) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 switches::kNaClLoaderProcess); | 260 switches::kNaClLoaderProcess); |
176 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); | 261 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); |
177 if (logging::DialogsAreSuppressed()) | 262 if (logging::DialogsAreSuppressed()) |
178 cmd_line->AppendSwitch(switches::kNoErrorDialogs); | 263 cmd_line->AppendSwitch(switches::kNoErrorDialogs); |
179 | 264 |
180 if (!nacl_loader_prefix.empty()) | 265 if (!nacl_loader_prefix.empty()) |
181 cmd_line->PrependWrapper(nacl_loader_prefix); | 266 cmd_line->PrependWrapper(nacl_loader_prefix); |
182 | 267 |
183 // On Windows we might need to start the broker process to launch a new loader | 268 // On Windows we might need to start the broker process to launch a new loader |
184 #if defined(OS_WIN) | 269 #if defined(OS_WIN) |
185 if (running_on_wow64_) { | 270 if (RunningOnWOW64()) { |
186 return NaClBrokerService::GetInstance()->LaunchLoader( | 271 return NaClBrokerService::GetInstance()->LaunchLoader( |
187 this, ASCIIToWide(channel_id())); | 272 this, ASCIIToWide(channel_id())); |
188 } else { | 273 } else { |
189 BrowserChildProcessHost::Launch(FilePath(), cmd_line); | 274 BrowserChildProcessHost::Launch(FilePath(), cmd_line); |
190 } | 275 } |
191 #elif defined(OS_POSIX) | 276 #elif defined(OS_POSIX) |
192 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote | 277 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote |
193 base::environment_vector(), | 278 base::environment_vector(), |
194 cmd_line); | 279 cmd_line); |
195 #endif | 280 #endif |
196 | 281 |
197 return true; | 282 return true; |
198 } | 283 } |
199 | 284 |
200 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 285 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
201 set_handle(handle); | 286 set_handle(handle); |
202 OnProcessLaunched(); | 287 OnProcessLaunched(); |
203 } | 288 } |
204 | 289 |
205 base::TerminationStatus NaClProcessHost::GetChildTerminationStatus( | 290 base::TerminationStatus NaClProcessHost::GetChildTerminationStatus( |
206 int* exit_code) { | 291 int* exit_code) { |
207 if (running_on_wow64_) | 292 if (RunningOnWOW64()) |
208 return base::GetTerminationStatus(handle(), exit_code); | 293 return base::GetTerminationStatus(handle(), exit_code); |
209 return BrowserChildProcessHost::GetChildTerminationStatus(exit_code); | 294 return BrowserChildProcessHost::GetChildTerminationStatus(exit_code); |
210 } | 295 } |
211 | 296 |
212 void NaClProcessHost::OnChildDied() { | 297 void NaClProcessHost::OnChildDied() { |
213 int exit_code; | 298 int exit_code; |
214 GetChildTerminationStatus(&exit_code); | 299 GetChildTerminationStatus(&exit_code); |
215 std::string message = | 300 std::string message = |
216 base::StringPrintf("NaCl process exited with status %i (0x%x)", | 301 base::StringPrintf("NaCl process exited with status %i (0x%x)", |
217 exit_code, exit_code); | 302 exit_code, exit_code); |
218 if (exit_code == 0) { | 303 if (exit_code == 0) { |
219 LOG(INFO) << message; | 304 LOG(INFO) << message; |
220 } else { | 305 } else { |
221 LOG(ERROR) << message; | 306 LOG(ERROR) << message; |
222 } | 307 } |
223 | 308 |
224 #if defined(OS_WIN) | 309 #if defined(OS_WIN) |
225 NaClBrokerService::GetInstance()->OnLoaderDied(); | 310 NaClBrokerService::GetInstance()->OnLoaderDied(); |
226 #endif | 311 #endif |
227 BrowserChildProcessHost::OnChildDied(); | 312 BrowserChildProcessHost::OnChildDied(); |
228 } | 313 } |
229 | 314 |
230 FilePath::StringType NaClProcessHost::GetIrtLibraryFilename() { | 315 // This only ever runs on the BrowserThread::FILE thread. |
231 bool on_x86_64 = running_on_wow64_; | 316 // If multiple tasks are posted, the later ones are no-ops. |
232 #if defined(__x86_64__) | 317 void NaClBrowser::OpenIrtLibraryFile() { |
233 on_x86_64 = true; | 318 if (irt_platform_file_ != base::kInvalidPlatformFileValue) |
234 #endif | 319 // We've already run. |
235 if (on_x86_64) { | 320 return; |
236 return FILE_PATH_LITERAL("nacl_irt_x86_64.nexe"); | |
237 } else { | |
238 return FILE_PATH_LITERAL("nacl_irt_x86_32.nexe"); | |
239 } | |
240 } | |
241 | 321 |
242 void NaClProcessHost::OnProcessLaunched() { | 322 FilePath irt_filepath; |
243 // TODO(mseaborn): Opening the IRT file every time a NaCl process is | 323 |
244 // launched probably does not work with auto-update on Linux. We | |
245 // might need to open the file on startup. If so, we would need to | |
246 // ensure that NaCl's ELF loader does not use lseek() on the shared | |
247 // IRT file descriptor, otherwise there would be a race condition. | |
248 FilePath irt_path; | |
249 // Allow the IRT library to be overridden via an environment | 324 // Allow the IRT library to be overridden via an environment |
250 // variable. This allows the NaCl/Chromium integration bot to | 325 // variable. This allows the NaCl/Chromium integration bot to |
251 // specify a newly-built IRT rather than using a prebuilt one | 326 // specify a newly-built IRT rather than using a prebuilt one |
252 // downloaded via Chromium's DEPS file. We use the same environment | 327 // downloaded via Chromium's DEPS file. We use the same environment |
253 // variable that the standalone NaCl PPAPI plugin accepts. | 328 // variable that the standalone NaCl PPAPI plugin accepts. |
254 const char* irt_path_var = getenv("NACL_IRT_LIBRARY"); | 329 const char* irt_path_var = getenv("NACL_IRT_LIBRARY"); |
255 if (irt_path_var != NULL) { | 330 if (irt_path_var != NULL) { |
256 FilePath::StringType string(irt_path_var, | 331 FilePath::StringType path_string( |
257 irt_path_var + strlen(irt_path_var)); | 332 irt_path_var, const_cast<const char*>(strchr(irt_path_var, '\0'))); |
258 irt_path = FilePath(string); | 333 irt_filepath = FilePath(path_string); |
259 } else { | 334 } else { |
260 FilePath plugin_dir; | 335 FilePath plugin_dir; |
261 if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) { | 336 if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) { |
262 LOG(ERROR) << "Failed to locate the plugins directory"; | 337 LOG(ERROR) << "Failed to locate the plugins directory"; |
263 delete this; | |
264 return; | 338 return; |
265 } | 339 } |
266 irt_path = plugin_dir.Append(GetIrtLibraryFilename()); | 340 |
| 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); |
267 } | 353 } |
268 | 354 |
269 if (!base::FileUtilProxy::CreateOrOpen( | 355 base::PlatformFileError error_code; |
270 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), | 356 irt_platform_file_ = base::CreatePlatformFile(irt_filepath, |
271 irt_path, | 357 base::PLATFORM_FILE_OPEN | |
272 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, | 358 base::PLATFORM_FILE_READ, |
273 base::Bind(&NaClProcessHost::OpenIrtFileDone, | 359 NULL, |
274 weak_factory_.GetWeakPtr()))) { | 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 |
| 368 void 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. |
| 382 void 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"; |
275 delete this; | 389 delete this; |
276 } | 390 } |
277 } | 391 } |
278 | 392 |
279 void NaClProcessHost::OpenIrtFileDone(base::PlatformFileError error_code, | 393 static bool SendHandleToSelLdr( |
280 base::PassPlatformFile file, | 394 base::ProcessHandle processh, |
281 bool created) { | 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 |
| 423 void NaClProcessHost::SendStart(base::PlatformFile irt_file) { |
| 424 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
| 425 |
282 std::vector<nacl::FileDescriptor> handles_for_renderer; | 426 std::vector<nacl::FileDescriptor> handles_for_renderer; |
283 base::ProcessHandle nacl_process_handle; | 427 base::ProcessHandle nacl_process_handle; |
284 bool have_irt_file = false; | |
285 if (base::PLATFORM_FILE_OK == error_code) { | |
286 internal_->sockets_for_sel_ldr.push_back(file.ReleaseValue()); | |
287 have_irt_file = true; | |
288 } else { | |
289 LOG(ERROR) << "Failed to open the NaCl IRT library file"; | |
290 } | |
291 | 428 |
292 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 429 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
293 #if defined(OS_WIN) | 430 #if defined(OS_WIN) |
294 // Copy the handle into the renderer process. | 431 // Copy the handle into the renderer process. |
295 HANDLE handle_in_renderer; | 432 HANDLE handle_in_renderer; |
296 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 433 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
297 reinterpret_cast<HANDLE>( | 434 reinterpret_cast<HANDLE>( |
298 internal_->sockets_for_renderer[i]), | 435 internal_->sockets_for_renderer[i]), |
299 chrome_render_message_filter_->peer_handle(), | 436 chrome_render_message_filter_->peer_handle(), |
300 &handle_in_renderer, | 437 &handle_in_renderer, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 477 |
341 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | 478 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
342 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); | 479 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); |
343 chrome_render_message_filter_->Send(reply_msg_); | 480 chrome_render_message_filter_->Send(reply_msg_); |
344 chrome_render_message_filter_ = NULL; | 481 chrome_render_message_filter_ = NULL; |
345 reply_msg_ = NULL; | 482 reply_msg_ = NULL; |
346 internal_->sockets_for_renderer.clear(); | 483 internal_->sockets_for_renderer.clear(); |
347 | 484 |
348 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; | 485 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; |
349 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 486 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
350 #if defined(OS_WIN) | 487 if (!SendHandleToSelLdr(handle(), |
351 HANDLE channel; | 488 internal_->sockets_for_sel_ldr[i], true, |
352 if (!DuplicateHandle(GetCurrentProcess(), | 489 &handles_for_sel_ldr)) { |
353 reinterpret_cast<HANDLE>( | |
354 internal_->sockets_for_sel_ldr[i]), | |
355 handle(), | |
356 &channel, | |
357 0, // Unused given DUPLICATE_SAME_ACCESS. | |
358 FALSE, | |
359 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | |
360 LOG(ERROR) << "DuplicateHandle() failed"; | |
361 delete this; | 490 delete this; |
362 return; | 491 return; |
363 } | 492 } |
364 handles_for_sel_ldr.push_back( | 493 } |
365 reinterpret_cast<nacl::FileDescriptor>(channel)); | 494 |
366 #else | 495 // Send over the IRT file handle. We don't close our own copy! |
367 nacl::FileDescriptor channel; | 496 if (!SendHandleToSelLdr(handle(), irt_file, false, &handles_for_sel_ldr)) { |
368 channel.fd = internal_->sockets_for_sel_ldr[i]; | 497 delete this; |
369 channel.auto_close = true; | 498 return; |
370 handles_for_sel_ldr.push_back(channel); | |
371 #endif | |
372 } | 499 } |
373 | 500 |
374 #if defined(OS_MACOSX) | 501 #if defined(OS_MACOSX) |
375 // For dynamic loading support, NaCl requires a file descriptor that | 502 // For dynamic loading support, NaCl requires a file descriptor that |
376 // was created in /tmp, since those created with shm_open() are not | 503 // was created in /tmp, since those created with shm_open() are not |
377 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 504 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
378 // round trip out of the sandbox, we create an FD here. | 505 // round trip out of the sandbox, we create an FD here. |
379 base::SharedMemory memory_buffer; | 506 base::SharedMemory memory_buffer; |
380 if (!memory_buffer.CreateAnonymous(/* size= */ 1)) { | 507 if (!memory_buffer.CreateAnonymous(/* size= */ 1)) { |
381 LOG(ERROR) << "Failed to allocate memory buffer"; | 508 LOG(ERROR) << "Failed to allocate memory buffer"; |
382 delete this; | 509 delete this; |
383 return; | 510 return; |
384 } | 511 } |
385 nacl::FileDescriptor memory_fd; | 512 nacl::FileDescriptor memory_fd; |
386 memory_fd.fd = dup(memory_buffer.handle().fd); | 513 memory_fd.fd = dup(memory_buffer.handle().fd); |
387 if (memory_fd.fd < 0) { | 514 if (memory_fd.fd < 0) { |
388 LOG(ERROR) << "Failed to dup() a file descriptor"; | 515 LOG(ERROR) << "Failed to dup() a file descriptor"; |
389 delete this; | 516 delete this; |
390 return; | 517 return; |
391 } | 518 } |
392 memory_fd.auto_close = true; | 519 memory_fd.auto_close = true; |
393 handles_for_sel_ldr.push_back(memory_fd); | 520 handles_for_sel_ldr.push_back(memory_fd); |
394 #endif | 521 #endif |
395 | 522 |
396 Send(new NaClProcessMsg_Start(handles_for_sel_ldr, have_irt_file)); | 523 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); |
397 internal_->sockets_for_sel_ldr.clear(); | 524 internal_->sockets_for_sel_ldr.clear(); |
398 } | 525 } |
399 | 526 |
400 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 527 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
401 NOTREACHED() << "Invalid message with type = " << msg.type(); | 528 NOTREACHED() << "Invalid message with type = " << msg.type(); |
402 return false; | 529 return false; |
403 } | 530 } |
404 | 531 |
405 bool NaClProcessHost::CanShutdown() { | 532 bool NaClProcessHost::CanShutdown() { |
406 return true; | 533 return true; |
407 } | 534 } |
OLD | NEW |