OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/nacl/loader/nacl_listener.h" | 5 #include "components/nacl/loader/nacl_listener.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 // Creates the PPAPI IPC channel between the NaCl IRT and the host | 137 // Creates the PPAPI IPC channel between the NaCl IRT and the host |
138 // (browser/renderer) process, and starts to listen it on the thread where | 138 // (browser/renderer) process, and starts to listen it on the thread where |
139 // the given message_loop_proxy runs. | 139 // the given message_loop_proxy runs. |
140 // Also, creates and sets the corresponding NaClDesc to the given nap with | 140 // Also, creates and sets the corresponding NaClDesc to the given nap with |
141 // the FD #. | 141 // the FD #. |
142 void SetUpIPCAdapter( | 142 void SetUpIPCAdapter( |
143 IPC::ChannelHandle* handle, | 143 IPC::ChannelHandle* handle, |
144 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 144 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
145 struct NaClApp* nap, | 145 struct NaClApp* nap, |
146 int nacl_fd, | 146 int nacl_fd, |
147 NaClIPCAdapter::ResolveFileTokenCallback resolve_file_token_cb) { | 147 NaClIPCAdapter::ResolveFileTokenCallback resolve_file_token_cb, |
148 NaClIPCAdapter::OpenResourceCallback open_resource_cb) { | |
148 scoped_refptr<NaClIPCAdapter> ipc_adapter( | 149 scoped_refptr<NaClIPCAdapter> ipc_adapter( |
149 new NaClIPCAdapter(*handle, | 150 new NaClIPCAdapter(*handle, |
150 message_loop_proxy.get(), | 151 message_loop_proxy.get(), |
151 resolve_file_token_cb)); | 152 resolve_file_token_cb, |
153 open_resource_cb)); | |
152 ipc_adapter->ConnectChannel(); | 154 ipc_adapter->ConnectChannel(); |
153 #if defined(OS_POSIX) | 155 #if defined(OS_POSIX) |
154 handle->socket = | 156 handle->socket = |
155 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor()); | 157 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor()); |
156 #endif | 158 #endif |
157 | 159 |
158 // Pass a NaClDesc to the untrusted side. This will hold a ref to the | 160 // Pass a NaClDesc to the untrusted side. This will hold a ref to the |
159 // NaClIPCAdapter. | 161 // NaClIPCAdapter. |
160 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); | 162 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); |
161 } | 163 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 | 272 |
271 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { | 273 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { |
272 bool handled = true; | 274 bool handled = true; |
273 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) | 275 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) |
274 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) | 276 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) |
275 IPC_MESSAGE_UNHANDLED(handled = false) | 277 IPC_MESSAGE_UNHANDLED(handled = false) |
276 IPC_END_MESSAGE_MAP() | 278 IPC_END_MESSAGE_MAP() |
277 return handled; | 279 return handled; |
278 } | 280 } |
279 | 281 |
282 bool NaClListener::OnOpenResource( | |
283 const IPC::Message& msg, | |
284 const std::string& key, | |
285 NaClIPCAdapter::OpenResourceReplyCallback cb) { | |
286 // This callback is executed only on |io_thread_| with NaClIPCAdapter's | |
287 // |lock_| not being held. | |
288 DCHECK(!cb.is_null()); | |
289 PrefetchedResourceFilesMap::iterator it = | |
290 prefetched_resource_files_.find(key); | |
291 | |
292 if (it != prefetched_resource_files_.end()) { | |
293 // Fast path for prefetched FDs. | |
294 IPC::PlatformFileForTransit file = it->second.first; | |
295 base::FilePath path = it->second.second; | |
296 prefetched_resource_files_.erase(it); | |
297 // A pre-opened resource descriptor is available. Run the reply callback | |
298 // and return true. | |
299 cb.Run(msg, file, path); | |
300 return true; | |
301 } | |
302 | |
303 // Return false to fall back to the slow path. Let the IPC adapter issue an | |
Mark Seaborn
2015/05/04 17:08:39
Nit: "the IPC adapter" -> "NaClIPCAdapter" to be m
Yusuke Sato
2015/05/05 18:27:16
Done.
| |
304 // IPC to the renderer. | |
305 return false; | |
306 } | |
307 | |
280 void NaClListener::OnStart(const nacl::NaClStartParams& params) { | 308 void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
281 #if defined(OS_LINUX) || defined(OS_MACOSX) | 309 #if defined(OS_LINUX) || defined(OS_MACOSX) |
282 int urandom_fd = dup(base::GetUrandomFD()); | 310 int urandom_fd = dup(base::GetUrandomFD()); |
283 if (urandom_fd < 0) { | 311 if (urandom_fd < 0) { |
284 LOG(ERROR) << "Failed to dup() the urandom FD"; | 312 LOG(ERROR) << "Failed to dup() the urandom FD"; |
285 return; | 313 return; |
286 } | 314 } |
287 NaClChromeMainSetUrandomFd(urandom_fd); | 315 NaClChromeMainSetUrandomFd(urandom_fd); |
288 #endif | 316 #endif |
289 struct NaClApp* nap = NULL; | 317 struct NaClApp* nap = NULL; |
290 NaClChromeMainInit(); | 318 NaClChromeMainInit(); |
291 | 319 |
292 crash_info_shmem_.reset(new base::SharedMemory(params.crash_info_shmem_handle, | 320 crash_info_shmem_.reset(new base::SharedMemory(params.crash_info_shmem_handle, |
293 false)); | 321 false)); |
294 CHECK(crash_info_shmem_->Map(nacl::kNaClCrashInfoShmemSize)); | 322 CHECK(crash_info_shmem_->Map(nacl::kNaClCrashInfoShmemSize)); |
295 NaClSetFatalErrorCallback(&FatalLogHandler); | 323 NaClSetFatalErrorCallback(&FatalLogHandler); |
296 | 324 |
297 nap = NaClAppCreate(); | 325 nap = NaClAppCreate(); |
298 if (nap == NULL) { | 326 if (nap == NULL) { |
299 LOG(ERROR) << "NaClAppCreate() failed"; | 327 LOG(ERROR) << "NaClAppCreate() failed"; |
300 return; | 328 return; |
301 } | 329 } |
302 | 330 |
303 IPC::ChannelHandle browser_handle; | 331 IPC::ChannelHandle browser_handle; |
304 IPC::ChannelHandle ppapi_renderer_handle; | 332 IPC::ChannelHandle ppapi_renderer_handle; |
305 IPC::ChannelHandle manifest_service_handle; | 333 IPC::ChannelHandle manifest_service_handle; |
306 | 334 |
335 for (size_t i = 0; i < params.prefetched_resource_files.size(); ++i) { | |
336 bool result = prefetched_resource_files_.insert(std::make_pair( | |
Mark Seaborn
2015/05/04 17:08:39
I think you'll need to rebase this use of std::pai
Yusuke Sato
2015/05/05 18:27:16
Done.
| |
337 params.prefetched_resource_files[i].file_key, | |
338 std::make_pair( | |
339 params.prefetched_resource_files[i].file, | |
340 params.prefetched_resource_files[i].file_path_metadata))).second; | |
341 if (!result) { | |
342 DLOG(ERROR) << "Duplicated open_resource key: " | |
Mark Seaborn
2015/05/04 17:08:39
How about just making this fatal? The renderer sh
Yusuke Sato
2015/05/05 18:27:16
Done.
| |
343 << params.prefetched_resource_files[i].file_key; | |
344 } | |
345 } | |
346 | |
307 if (params.enable_ipc_proxy) { | 347 if (params.enable_ipc_proxy) { |
308 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 348 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
309 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 349 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
310 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 350 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
311 | 351 |
312 // Create the PPAPI IPC channels between the NaCl IRT and the host | 352 // Create the PPAPI IPC channels between the NaCl IRT and the host |
313 // (browser/renderer) processes. The IRT uses these channels to | 353 // (browser/renderer) processes. The IRT uses these channels to |
314 // communicate with the host and to initialize the IPC dispatchers. | 354 // communicate with the host and to initialize the IPC dispatchers. |
315 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), | 355 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), |
316 nap, NACL_CHROME_DESC_BASE, | 356 nap, NACL_CHROME_DESC_BASE, |
317 NaClIPCAdapter::ResolveFileTokenCallback()); | 357 NaClIPCAdapter::ResolveFileTokenCallback(), |
358 NaClIPCAdapter::OpenResourceCallback()); | |
318 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), | 359 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), |
319 nap, NACL_CHROME_DESC_BASE + 1, | 360 nap, NACL_CHROME_DESC_BASE + 1, |
320 NaClIPCAdapter::ResolveFileTokenCallback()); | 361 NaClIPCAdapter::ResolveFileTokenCallback(), |
362 NaClIPCAdapter::OpenResourceCallback()); | |
321 SetUpIPCAdapter(&manifest_service_handle, | 363 SetUpIPCAdapter(&manifest_service_handle, |
322 io_thread_.message_loop_proxy(), | 364 io_thread_.message_loop_proxy(), |
323 nap, | 365 nap, |
324 NACL_CHROME_DESC_BASE + 2, | 366 NACL_CHROME_DESC_BASE + 2, |
325 base::Bind(&NaClListener::ResolveFileToken, | 367 base::Bind(&NaClListener::ResolveFileToken, |
368 base::Unretained(this)), | |
369 base::Bind(&NaClListener::OnOpenResource, | |
326 base::Unretained(this))); | 370 base::Unretained(this))); |
327 } | 371 } |
328 | 372 |
329 trusted_listener_ = new NaClTrustedListener( | 373 trusted_listener_ = new NaClTrustedListener( |
330 IPC::Channel::GenerateVerifiedChannelID("nacl"), | 374 IPC::Channel::GenerateVerifiedChannelID("nacl"), |
331 io_thread_.message_loop_proxy().get(), | 375 io_thread_.message_loop_proxy().get(), |
332 &shutdown_event_); | 376 &shutdown_event_); |
333 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( | 377 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( |
334 browser_handle, | 378 browser_handle, |
335 ppapi_renderer_handle, | 379 ppapi_renderer_handle, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 if (params.enable_mojo) { | 477 if (params.enable_mojo) { |
434 // InjectMojo adds a file descriptor to the process that allows Mojo calls | 478 // InjectMojo adds a file descriptor to the process that allows Mojo calls |
435 // to use an implementation defined outside the NaCl sandbox. See | 479 // to use an implementation defined outside the NaCl sandbox. See |
436 // //mojo/nacl for implementation details. | 480 // //mojo/nacl for implementation details. |
437 InjectMojo(nap); | 481 InjectMojo(nap); |
438 } else { | 482 } else { |
439 // When Mojo isn't enabled, we inject a file descriptor that intentionally | 483 // When Mojo isn't enabled, we inject a file descriptor that intentionally |
440 // fails on any imc_sendmsg() call to make debugging easier. | 484 // fails on any imc_sendmsg() call to make debugging easier. |
441 InjectDisabledMojo(nap); | 485 InjectDisabledMojo(nap); |
442 } | 486 } |
443 // TODO(yusukes): Support pre-opening resource files. | |
444 CHECK(params.prefetched_resource_files.empty()); | |
445 | 487 |
446 int exit_status; | 488 int exit_status; |
447 if (!NaClChromeMainStart(nap, args, &exit_status)) | 489 if (!NaClChromeMainStart(nap, args, &exit_status)) |
448 NaClExit(1); | 490 NaClExit(1); |
449 | 491 |
450 // Report the plugin's exit status if the application started successfully. | 492 // Report the plugin's exit status if the application started successfully. |
451 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); | 493 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
452 NaClExit(exit_status); | 494 NaClExit(exit_status); |
453 } | 495 } |
454 | 496 |
455 void NaClListener::ResolveFileToken( | 497 void NaClListener::ResolveFileToken( |
456 uint64_t token_lo, | 498 uint64_t token_lo, |
457 uint64_t token_hi, | 499 uint64_t token_hi, |
458 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { | 500 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
459 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { | 501 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { |
460 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); | 502 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
461 return; | 503 return; |
462 } | 504 } |
463 resolved_cb_ = cb; | 505 resolved_cb_ = cb; |
464 } | 506 } |
465 | 507 |
466 void NaClListener::OnFileTokenResolved( | 508 void NaClListener::OnFileTokenResolved( |
467 uint64_t token_lo, | 509 uint64_t token_lo, |
468 uint64_t token_hi, | 510 uint64_t token_hi, |
469 IPC::PlatformFileForTransit ipc_fd, | 511 IPC::PlatformFileForTransit ipc_fd, |
470 base::FilePath file_path) { | 512 base::FilePath file_path) { |
471 resolved_cb_.Run(ipc_fd, file_path); | 513 resolved_cb_.Run(ipc_fd, file_path); |
472 resolved_cb_.Reset(); | 514 resolved_cb_.Reset(); |
473 } | 515 } |
OLD | NEW |