| 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 g_listener->Send(new NaClProcessHostMsg_DebugStubPortSelected(port)); | 129 g_listener->Send(new NaClProcessHostMsg_DebugStubPortSelected(port)); |
| 130 } | 130 } |
| 131 | 131 |
| 132 #endif | 132 #endif |
| 133 | 133 |
| 134 // Creates the PPAPI IPC channel between the NaCl IRT and the host | 134 // Creates the PPAPI IPC channel between the NaCl IRT and the host |
| 135 // (browser/renderer) process, and starts to listen it on the thread where | 135 // (browser/renderer) process, and starts to listen it on the thread where |
| 136 // the given message_loop_proxy runs. | 136 // the given message_loop_proxy runs. |
| 137 // Also, creates and sets the corresponding NaClDesc to the given nap with | 137 // Also, creates and sets the corresponding NaClDesc to the given nap with |
| 138 // the FD #. | 138 // the FD #. |
| 139 void SetUpIPCAdapter(IPC::ChannelHandle* handle, | 139 scoped_refptr<NaClIPCAdapter> SetUpIPCAdapter( |
| 140 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 140 IPC::ChannelHandle* handle, |
| 141 struct NaClApp* nap, | 141 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
| 142 int nacl_fd) { | 142 struct NaClApp* nap, |
| 143 int nacl_fd) { |
| 143 scoped_refptr<NaClIPCAdapter> ipc_adapter( | 144 scoped_refptr<NaClIPCAdapter> ipc_adapter( |
| 144 new NaClIPCAdapter(*handle, message_loop_proxy.get())); | 145 new NaClIPCAdapter(*handle, message_loop_proxy.get())); |
| 145 ipc_adapter->ConnectChannel(); | 146 ipc_adapter->ConnectChannel(); |
| 146 #if defined(OS_POSIX) | 147 #if defined(OS_POSIX) |
| 147 handle->socket = | 148 handle->socket = |
| 148 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor(), true); | 149 base::FileDescriptor(ipc_adapter->TakeClientFileDescriptor(), true); |
| 149 #endif | 150 #endif |
| 150 | 151 |
| 151 // Pass a NaClDesc to the untrusted side. This will hold a ref to the | 152 // Pass a NaClDesc to the untrusted side. This will hold a ref to the |
| 152 // NaClIPCAdapter. | 153 // NaClIPCAdapter. |
| 153 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); | 154 NaClAppSetDesc(nap, nacl_fd, ipc_adapter->MakeNaClDesc()); |
| 155 return ipc_adapter; |
| 154 } | 156 } |
| 155 | 157 |
| 156 } // namespace | 158 } // namespace |
| 157 | 159 |
| 158 class BrowserValidationDBProxy : public NaClValidationDB { | 160 class BrowserValidationDBProxy : public NaClValidationDB { |
| 159 public: | 161 public: |
| 160 explicit BrowserValidationDBProxy(NaClListener* listener) | 162 explicit BrowserValidationDBProxy(NaClListener* listener) |
| 161 : listener_(listener) { | 163 : listener_(listener) { |
| 162 } | 164 } |
| 163 | 165 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 174 return result; | 176 return result; |
| 175 } | 177 } |
| 176 | 178 |
| 177 virtual void SetKnownToValidate(const std::string& signature) OVERRIDE { | 179 virtual void SetKnownToValidate(const std::string& signature) OVERRIDE { |
| 178 // Caching is optional: NaCl will still work correctly if the IPC fails. | 180 // Caching is optional: NaCl will still work correctly if the IPC fails. |
| 179 if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { | 181 if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { |
| 180 LOG(ERROR) << "Failed to update NaCl validation cache."; | 182 LOG(ERROR) << "Failed to update NaCl validation cache."; |
| 181 } | 183 } |
| 182 } | 184 } |
| 183 | 185 |
| 186 // This is the "old" code path for resolving file tokens. It's only |
| 187 // used for resolving the main nexe. |
| 188 // TODO(teravest): Remove this. |
| 184 virtual bool ResolveFileToken(struct NaClFileToken* file_token, | 189 virtual bool ResolveFileToken(struct NaClFileToken* file_token, |
| 185 int32* fd, std::string* path) OVERRIDE { | 190 int32* fd, std::string* path) OVERRIDE { |
| 186 *fd = -1; | 191 *fd = -1; |
| 187 *path = ""; | 192 *path = ""; |
| 188 if (!NaClFileTokenIsValid(file_token)) { | 193 if (!NaClFileTokenIsValid(file_token)) { |
| 189 return false; | 194 return false; |
| 190 } | 195 } |
| 191 IPC::PlatformFileForTransit ipc_fd = IPC::InvalidPlatformFileForTransit(); | 196 IPC::PlatformFileForTransit ipc_fd = IPC::InvalidPlatformFileForTransit(); |
| 192 base::FilePath ipc_path; | 197 base::FilePath ipc_path; |
| 193 if (!listener_->Send(new NaClProcessMsg_ResolveFileToken(file_token->lo, | 198 if (!listener_->Send(new NaClProcessMsg_ResolveFileToken(file_token->lo, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 DCHECK(main_loop_ != NULL); | 249 DCHECK(main_loop_ != NULL); |
| 245 if (base::MessageLoop::current() == main_loop_) { | 250 if (base::MessageLoop::current() == main_loop_) { |
| 246 // This thread owns the channel. | 251 // This thread owns the channel. |
| 247 return channel_->Send(msg); | 252 return channel_->Send(msg); |
| 248 } else { | 253 } else { |
| 249 // This thread does not own the channel. | 254 // This thread does not own the channel. |
| 250 return filter_->Send(msg); | 255 return filter_->Send(msg); |
| 251 } | 256 } |
| 252 } | 257 } |
| 253 | 258 |
| 259 // The NaClProcessMsg_ResolveFileTokenAsyncReply message must be |
| 260 // processed in a MessageFilter so it can be handled on the IO thread. |
| 261 // The main thread used by NaClListener is busy in |
| 262 // NaClChromeMainAppStart(), so it can't be used for servicing messages. |
| 263 class FileTokenMessageFilter : public IPC::MessageFilter { |
| 264 public: |
| 265 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { |
| 266 bool handled = true; |
| 267 IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) |
| 268 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsyncReply, |
| 269 OnResolveFileTokenAsyncReply) |
| 270 IPC_MESSAGE_UNHANDLED(handled = false) |
| 271 IPC_END_MESSAGE_MAP() |
| 272 return handled; |
| 273 } |
| 274 |
| 275 void OnResolveFileTokenAsyncReply( |
| 276 uint64_t token_lo, |
| 277 uint64_t token_hi, |
| 278 IPC::PlatformFileForTransit ipc_fd, |
| 279 base::FilePath file_path) { |
| 280 CHECK(g_listener); |
| 281 g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); |
| 282 } |
| 283 private: |
| 284 virtual ~FileTokenMessageFilter() { } |
| 285 }; |
| 286 |
| 254 void NaClListener::Listen() { | 287 void NaClListener::Listen() { |
| 255 std::string channel_name = | 288 std::string channel_name = |
| 256 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 289 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 257 switches::kProcessChannelID); | 290 switches::kProcessChannelID); |
| 258 channel_ = IPC::SyncChannel::Create( | 291 channel_ = IPC::SyncChannel::Create( |
| 259 this, io_thread_.message_loop_proxy().get(), &shutdown_event_); | 292 this, io_thread_.message_loop_proxy().get(), &shutdown_event_); |
| 260 filter_ = new IPC::SyncMessageFilter(&shutdown_event_); | 293 filter_ = new IPC::SyncMessageFilter(&shutdown_event_); |
| 261 channel_->AddFilter(filter_.get()); | 294 channel_->AddFilter(filter_.get()); |
| 295 channel_->AddFilter(new FileTokenMessageFilter()); |
| 262 channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); | 296 channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); |
| 263 main_loop_ = base::MessageLoop::current(); | 297 main_loop_ = base::MessageLoop::current(); |
| 264 main_loop_->Run(); | 298 main_loop_->Run(); |
| 265 } | 299 } |
| 266 | 300 |
| 267 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { | 301 bool NaClListener::OnMessageReceived(const IPC::Message& msg) { |
| 268 bool handled = true; | 302 bool handled = true; |
| 269 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) | 303 IPC_BEGIN_MESSAGE_MAP(NaClListener, msg) |
| 270 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) | 304 IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStart) |
| 271 IPC_MESSAGE_UNHANDLED(handled = false) | 305 IPC_MESSAGE_UNHANDLED(handled = false) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 291 NaClSetFatalErrorCallback(&FatalLogHandler); | 325 NaClSetFatalErrorCallback(&FatalLogHandler); |
| 292 | 326 |
| 293 nap = NaClAppCreate(); | 327 nap = NaClAppCreate(); |
| 294 if (nap == NULL) { | 328 if (nap == NULL) { |
| 295 LOG(ERROR) << "NaClAppCreate() failed"; | 329 LOG(ERROR) << "NaClAppCreate() failed"; |
| 296 return; | 330 return; |
| 297 } | 331 } |
| 298 | 332 |
| 299 IPC::ChannelHandle browser_handle; | 333 IPC::ChannelHandle browser_handle; |
| 300 IPC::ChannelHandle ppapi_renderer_handle; | 334 IPC::ChannelHandle ppapi_renderer_handle; |
| 335 IPC::ChannelHandle manifest_service_handle; |
| 301 | 336 |
| 302 if (params.enable_ipc_proxy) { | 337 if (params.enable_ipc_proxy) { |
| 303 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 338 browser_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 304 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | 339 ppapi_renderer_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 340 manifest_service_handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); |
| 305 | 341 |
| 306 // Create the PPAPI IPC channels between the NaCl IRT and the host | 342 // Create the PPAPI IPC channels between the NaCl IRT and the host |
| 307 // (browser/renderer) processes. The IRT uses these channels to | 343 // (browser/renderer) processes. The IRT uses these channels to |
| 308 // communicate with the host and to initialize the IPC dispatchers. | 344 // communicate with the host and to initialize the IPC dispatchers. |
| 309 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), | 345 SetUpIPCAdapter(&browser_handle, io_thread_.message_loop_proxy(), |
| 310 nap, NACL_CHROME_DESC_BASE); | 346 nap, NACL_CHROME_DESC_BASE); |
| 311 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), | 347 SetUpIPCAdapter(&ppapi_renderer_handle, io_thread_.message_loop_proxy(), |
| 312 nap, NACL_CHROME_DESC_BASE + 1); | 348 nap, NACL_CHROME_DESC_BASE + 1); |
| 349 |
| 350 scoped_refptr<NaClIPCAdapter> manifest_ipc_adapter = |
| 351 SetUpIPCAdapter(&manifest_service_handle, |
| 352 io_thread_.message_loop_proxy(), |
| 353 nap, |
| 354 NACL_CHROME_DESC_BASE + 2); |
| 355 manifest_ipc_adapter->set_resolve_file_token_callback( |
| 356 base::Bind(&NaClListener::ResolveFileToken, base::Unretained(this))); |
| 313 } | 357 } |
| 314 | 358 |
| 315 trusted_listener_ = new NaClTrustedListener( | 359 trusted_listener_ = new NaClTrustedListener( |
| 316 IPC::Channel::GenerateVerifiedChannelID("nacl"), | 360 IPC::Channel::GenerateVerifiedChannelID("nacl"), |
| 317 io_thread_.message_loop_proxy().get(), | 361 io_thread_.message_loop_proxy().get(), |
| 318 &shutdown_event_); | 362 &shutdown_event_); |
| 319 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( | 363 if (!Send(new NaClProcessHostMsg_PpapiChannelsCreated( |
| 320 browser_handle, | 364 browser_handle, |
| 321 ppapi_renderer_handle, | 365 ppapi_renderer_handle, |
| 322 trusted_listener_->TakeClientChannelHandle(), | 366 trusted_listener_->TakeClientChannelHandle(), |
| 323 IPC::ChannelHandle()))) | 367 manifest_service_handle))) |
| 324 LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; | 368 LOG(ERROR) << "Failed to send IPC channel handle to NaClProcessHost."; |
| 325 | 369 |
| 326 std::vector<nacl::FileDescriptor> handles = params.handles; | 370 std::vector<nacl::FileDescriptor> handles = params.handles; |
| 327 struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate(); | 371 struct NaClChromeMainArgs* args = NaClChromeMainArgsCreate(); |
| 328 if (args == NULL) { | 372 if (args == NULL) { |
| 329 LOG(ERROR) << "NaClChromeMainArgsCreate() failed"; | 373 LOG(ERROR) << "NaClChromeMainArgsCreate() failed"; |
| 330 return; | 374 return; |
| 331 } | 375 } |
| 332 | 376 |
| 333 #if defined(OS_LINUX) || defined(OS_MACOSX) | 377 #if defined(OS_LINUX) || defined(OS_MACOSX) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 args->nexe_desc = NaClDescIoFromFileInfo(nexe_file_info, NACL_ABI_O_RDONLY); | 464 args->nexe_desc = NaClDescIoFromFileInfo(nexe_file_info, NACL_ABI_O_RDONLY); |
| 421 | 465 |
| 422 int exit_status; | 466 int exit_status; |
| 423 if (!NaClChromeMainStart(nap, args, &exit_status)) | 467 if (!NaClChromeMainStart(nap, args, &exit_status)) |
| 424 NaClExit(1); | 468 NaClExit(1); |
| 425 | 469 |
| 426 // Report the plugin's exit status if the application started successfully. | 470 // Report the plugin's exit status if the application started successfully. |
| 427 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); | 471 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
| 428 NaClExit(exit_status); | 472 NaClExit(exit_status); |
| 429 } | 473 } |
| 474 |
| 475 void NaClListener::ResolveFileToken( |
| 476 uint64_t token_lo, |
| 477 uint64_t token_hi, |
| 478 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
| 479 if (!Send(new NaClProcessMsg_ResolveFileTokenAsync(token_lo, token_hi))) { |
| 480 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
| 481 return; |
| 482 } |
| 483 resolved_cb_ = cb; |
| 484 } |
| 485 |
| 486 void NaClListener::OnFileTokenResolved( |
| 487 uint64_t token_lo, |
| 488 uint64_t token_hi, |
| 489 IPC::PlatformFileForTransit ipc_fd, |
| 490 base::FilePath file_path) { |
| 491 resolved_cb_.Run(ipc_fd, file_path); |
| 492 resolved_cb_.Reset(); |
| 493 } |
| OLD | NEW |