Chromium Code Reviews| 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 |