| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 // Creates the PPAPI IPC channel between the NaCl IRT and the host | 139 // Creates the PPAPI IPC channel between the NaCl IRT and the host |
| 140 // (browser/renderer) process, and starts to listen it on the thread where | 140 // (browser/renderer) process, and starts to listen it on the thread where |
| 141 // the given message_loop_proxy runs. | 141 // the given message_loop_proxy runs. |
| 142 // Also, creates and sets the corresponding NaClDesc to the given nap with | 142 // Also, creates and sets the corresponding NaClDesc to the given nap with |
| 143 // the FD #. | 143 // the FD #. |
| 144 void SetUpIPCAdapter( | 144 void SetUpIPCAdapter( |
| 145 IPC::ChannelHandle* handle, | 145 IPC::ChannelHandle* handle, |
| 146 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 146 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 147 struct NaClApp* nap, | 147 struct NaClApp* nap, |
| 148 int nacl_fd, | 148 int nacl_fd, |
| 149 NaClIPCAdapter::ResolveFileTokenCallback resolve_file_token_cb) { | 149 NaClIPCAdapter::ResolveFileTokenCallback resolve_file_token_cb, |
| 150 NaClIPCAdapter::OpenResourceCallback open_resource_cb) { |
| 150 scoped_refptr<NaClIPCAdapter> ipc_adapter( | 151 scoped_refptr<NaClIPCAdapter> ipc_adapter( |
| 151 new NaClIPCAdapter(*handle, | 152 new NaClIPCAdapter(*handle, |
| 152 message_loop_proxy.get(), | 153 message_loop_proxy.get(), |
| 153 resolve_file_token_cb)); | 154 resolve_file_token_cb, |
| 155 open_resource_cb)); |
| 154 ipc_adapter->ConnectChannel(); | 156 ipc_adapter->ConnectChannel(); |
| 155 #if defined(OS_POSIX) | 157 #if defined(OS_POSIX) |
| 156 handle->socket = | 158 handle->socket = |
| 157 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor()); | 159 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor()); |
| 158 #endif | 160 #endif |
| 159 | 161 |
| 160 // Pass a NaClDesc to the untrusted side. This will hold a ref to the | 162 // Pass a NaClDesc to the untrusted side. This will hold a ref to the |
| 161 // NaClIPCAdapter. | 163 // NaClIPCAdapter. |
| 162 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); | 164 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); |
| 163 } | 165 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 | 274 |
| 273 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { | 275 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { |
| 274 bool handled = true; | 276 bool handled = true; |
| 275 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) | 277 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) |
| 276 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) | 278 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) |
| 277 IPC_MESSAGE_UNHANDLED(handled = false) | 279 IPC_MESSAGE_UNHANDLED(handled = false) |
| 278 IPC_END_MESSAGE_MAP() | 280 IPC_END_MESSAGE_MAP() |
| 279 return handled; | 281 return handled; |
| 280 } | 282 } |
| 281 | 283 |
| 284 bool NaClListener::OnOpenResource( |
| 285 const IPC::Message& msg, |
| 286 const std::string& key, |
| 287 NaClIPCAdapter::OpenResourceReplyCallback cb) { |
| 288 // This callback is executed only on |io_thread_| with NaClIPCAdapter's |
| 289 // |lock_| not being held. |
| 290 DCHECK(!cb.is_null()); |
| 291 PrefetchedResourceFilesMap::iterator it = |
| 292 prefetched_resource_files_.find(key); |
| 293 |
| 294 if (it != prefetched_resource_files_.end()) { |
| 295 // Fast path for prefetched FDs. |
| 296 IPC::PlatformFileForTransit file = it->second.first; |
| 297 base::FilePath path = it->second.second; |
| 298 prefetched_resource_files_.erase(it); |
| 299 // A pre-opened resource descriptor is available. Run the reply callback |
| 300 // and return true. |
| 301 cb.Run(msg, file, path); |
| 302 return true; |
| 303 } |
| 304 |
| 305 // Return false to fall back to the slow path. Let NaClIPCAdapter issue an |
| 306 // IPC to the renderer. |
| 307 return false; |
| 308 } |
| 309 |
| 282 void NaClListener::OnStart(const nacl::NaClStartParams& params) { | 310 void NaClListener::OnStart(const nacl::NaClStartParams& params) { |
| 283 #if defined(OS_LINUX) || defined(OS_MACOSX) | 311 #if defined(OS_LINUX) || defined(OS_MACOSX) |
| 284 int urandom_fd = dup(base::GetUrandomFD()); | 312 int urandom_fd = dup(base::GetUrandomFD()); |
| 285 if (urandom_fd < 0) { | 313 if (urandom_fd < 0) { |
| 286 LOG(ERROR) << "Failed to dup() the urandom FD"; | 314 LOG(ERROR) << "Failed to dup() the urandom FD"; |
| 287 return; | 315 return; |
| 288 } | 316 } |
| 289 NaClChromeMainSetUrandomFd(urandom_fd); | 317 NaClChromeMainSetUrandomFd(urandom_fd); |
| 290 #endif | 318 #endif |
| 291 struct NaClApp* nap = NULL; | 319 struct NaClApp* nap = NULL; |
| 292 NaClChromeMainInit(); | 320 NaClChromeMainInit(); |
| 293 | 321 |
| 294 CHECK(base::SharedMemory::IsHandleValid(params.crash_info_shmem_handle)); | 322 CHECK(base::SharedMemory::IsHandleValid(params.crash_info_shmem_handle)); |
| 295 crash_info_shmem_.reset(new base::SharedMemory( | 323 crash_info_shmem_.reset(new base::SharedMemory( |
| 296 params.crash_info_shmem_handle, false /* not readonly */)); | 324 params.crash_info_shmem_handle, false /* not readonly */)); |
| 297 CHECK(crash_info_shmem_->Map(nacl::kNaClCrashInfoShmemSize)); | 325 CHECK(crash_info_shmem_->Map(nacl::kNaClCrashInfoShmemSize)); |
| 298 NaClSetFatalErrorCallback(&FatalLogHandler); | 326 NaClSetFatalErrorCallback(&FatalLogHandler); |
| 299 | 327 |
| 300 nap = NaClAppCreate(); | 328 nap = NaClAppCreate(); |
| 301 if (nap == NULL) { | 329 if (nap == NULL) { |
| 302 LOG(ERROR) << "NaClAppCreate() failed"; | 330 LOG(ERROR) << "NaClAppCreate() failed"; |
| 303 return; | 331 return; |
| 304 } | 332 } |
| 305 | 333 |
| 306 IPC::ChannelHandle browser_handle; | 334 IPC::ChannelHandle browser_handle; |
| 307 IPC::ChannelHandle ppapi_renderer_handle; | 335 IPC::ChannelHandle ppapi_renderer_handle; |
| 308 IPC::ChannelHandle manifest_service_handle; | 336 IPC::ChannelHandle manifest_service_handle; |
| 309 | 337 |
| 338 for (size_t i = 0; i < params.prefetched_resource_files.size(); ++i) { |
| 339 bool result = prefetched_resource_files_.insert(std::make_pair( |
| 340 params.prefetched_resource_files[i].file_key, |
| 341 std::make_pair( |
| 342 params.prefetched_resource_files[i].file, |
| 343 params.prefetched_resource_files[i].file_path_metadata))).second; |
| 344 if (!result) { |
| 345 LOG(FATAL) << "Duplicated open_resource key: " |
| 346 << params.prefetched_resource_files[i].file_key; |
| 347 } |
| 348 } |
| 349 |
| 310 if (params.enable_ipc_proxy) { | 350 if (params.enable_ipc_proxy) { |
| 311 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 351 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 312 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 352 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 313 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 353 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 314 | 354 |
| 315 // Create the PPAPI IPC channels between the NaCl IRT and the host | 355 // Create the PPAPI IPC channels between the NaCl IRT and the host |
| 316 // (browser/renderer) processes. The IRT uses these channels to | 356 // (browser/renderer) processes. The IRT uses these channels to |
| 317 // communicate with the host and to initialize the IPC dispatchers. | 357 // communicate with the host and to initialize the IPC dispatchers. |
| 318 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), | 358 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), |
| 319 nap, NACL_CHROME_DESC_BASE, | 359 nap, NACL_CHROME_DESC_BASE, |
| 320 NaClIPCAdapter::ResolveFileTokenCallback()); | 360 NaClIPCAdapter::ResolveFileTokenCallback(), |
| 361 NaClIPCAdapter::OpenResourceCallback()); |
| 321 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), | 362 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), |
| 322 nap, NACL_CHROME_DESC_BASE + 1, | 363 nap, NACL_CHROME_DESC_BASE + 1, |
| 323 NaClIPCAdapter::ResolveFileTokenCallback()); | 364 NaClIPCAdapter::ResolveFileTokenCallback(), |
| 365 NaClIPCAdapter::OpenResourceCallback()); |
| 324 SetUpIPCAdapter(&manifest_service_handle, | 366 SetUpIPCAdapter(&manifest_service_handle, |
| 325 io_thread_.message_loop_proxy(), | 367 io_thread_.message_loop_proxy(), |
| 326 nap, | 368 nap, |
| 327 NACL_CHROME_DESC_BASE + 2, | 369 NACL_CHROME_DESC_BASE + 2, |
| 328 base::Bind(&NaClListener::ResolveFileToken, | 370 base::Bind(&NaClListener::ResolveFileToken, |
| 371 base::Unretained(this)), |
| 372 base::Bind(&NaClListener::OnOpenResource, |
| 329 base::Unretained(this))); | 373 base::Unretained(this))); |
| 330 } | 374 } |
| 331 | 375 |
| 332 trusted_listener_ = new NaClTrustedListener( | 376 trusted_listener_ = new NaClTrustedListener( |
| 333 IPC::Channel::GenerateVerifiedChannelID("nacl"), | 377 IPC::Channel::GenerateVerifiedChannelID("nacl"), |
| 334 io_thread_.message_loop_proxy().get(), | 378 io_thread_.message_loop_proxy().get(), |
| 335 &shutdown_event_); | 379 &shutdown_event_); |
| 336 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( | 380 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( |
| 337 browser_handle, | 381 browser_handle, |
| 338 ppapi_renderer_handle, | 382 ppapi_renderer_handle, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 #if defined(OS_LINUX) | 471 #if defined(OS_LINUX) |
| 428 args->prereserved_sandbox_size = prereserved_sandbox_size_; | 472 args->prereserved_sandbox_size = prereserved_sandbox_size_; |
| 429 #endif | 473 #endif |
| 430 | 474 |
| 431 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( | 475 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( |
| 432 params.nexe_file); | 476 params.nexe_file); |
| 433 std::string file_path_str = params.nexe_file_path_metadata.AsUTF8Unsafe(); | 477 std::string file_path_str = params.nexe_file_path_metadata.AsUTF8Unsafe(); |
| 434 args->nexe_desc = NaClDescCreateWithFilePathMetadata(nexe_file, | 478 args->nexe_desc = NaClDescCreateWithFilePathMetadata(nexe_file, |
| 435 file_path_str.c_str()); | 479 file_path_str.c_str()); |
| 436 | 480 |
| 437 // TODO(yusukes): Support pre-opening resource files. | |
| 438 CHECK(params.prefetched_resource_files.empty()); | |
| 439 | |
| 440 int exit_status; | 481 int exit_status; |
| 441 if (!NaClChromeMainStart(nap, args, &exit_status)) | 482 if (!NaClChromeMainStart(nap, args, &exit_status)) |
| 442 NaClExit(1); | 483 NaClExit(1); |
| 443 | 484 |
| 444 // Report the plugin's exit status if the application started successfully. | 485 // Report the plugin's exit status if the application started successfully. |
| 445 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); | 486 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
| 446 NaClExit(exit_status); | 487 NaClExit(exit_status); |
| 447 } | 488 } |
| 448 | 489 |
| 449 void NaClListener::ResolveFileToken( | 490 void NaClListener::ResolveFileToken( |
| 450 uint64_t token_lo, | 491 uint64_t token_lo, |
| 451 uint64_t token_hi, | 492 uint64_t token_hi, |
| 452 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { | 493 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
| 453 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { | 494 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { |
| 454 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); | 495 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
| 455 return; | 496 return; |
| 456 } | 497 } |
| 457 resolved_cb_ = cb; | 498 resolved_cb_ = cb; |
| 458 } | 499 } |
| 459 | 500 |
| 460 void NaClListener::OnFileTokenResolved( | 501 void NaClListener::OnFileTokenResolved( |
| 461 uint64_t token_lo, | 502 uint64_t token_lo, |
| 462 uint64_t token_hi, | 503 uint64_t token_hi, |
| 463 IPC::PlatformFileForTransit ipc_fd, | 504 IPC::PlatformFileForTransit ipc_fd, |
| 464 base::FilePath file_path) { | 505 base::FilePath file_path) { |
| 465 resolved_cb_.Run(ipc_fd, file_path); | 506 resolved_cb_.Run(ipc_fd, file_path); |
| 466 resolved_cb_.Reset(); | 507 resolved_cb_.Reset(); |
| 467 } | 508 } |
| OLD | NEW |