| 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 11 matching lines...) Expand all Loading... |
| 22 #include "components/nacl/common/nacl_renderer_messages.h" | 22 #include "components/nacl/common/nacl_renderer_messages.h" |
| 23 #include "components/nacl/loader/nacl_ipc_adapter.h" | 23 #include "components/nacl/loader/nacl_ipc_adapter.h" |
| 24 #include "components/nacl/loader/nacl_validation_db.h" | 24 #include "components/nacl/loader/nacl_validation_db.h" |
| 25 #include "components/nacl/loader/nacl_validation_query.h" | 25 #include "components/nacl/loader/nacl_validation_query.h" |
| 26 #include "ipc/ipc_channel_handle.h" | 26 #include "ipc/ipc_channel_handle.h" |
| 27 #include "ipc/ipc_switches.h" | 27 #include "ipc/ipc_switches.h" |
| 28 #include "ipc/ipc_sync_channel.h" | 28 #include "ipc/ipc_sync_channel.h" |
| 29 #include "ipc/ipc_sync_message_filter.h" | 29 #include "ipc/ipc_sync_message_filter.h" |
| 30 #include "native_client/src/public/chrome_main.h" | 30 #include "native_client/src/public/chrome_main.h" |
| 31 #include "native_client/src/public/nacl_app.h" | 31 #include "native_client/src/public/nacl_app.h" |
| 32 #include "native_client/src/public/nacl_desc.h" |
| 32 #include "native_client/src/public/nacl_file_info.h" | 33 #include "native_client/src/public/nacl_file_info.h" |
| 33 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" | |
| 34 | 34 |
| 35 #if defined(OS_POSIX) | 35 #if defined(OS_POSIX) |
| 36 #include "base/file_descriptor_posix.h" | 36 #include "base/file_descriptor_posix.h" |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #if defined(OS_LINUX) | 39 #if defined(OS_LINUX) |
| 40 #include "content/public/common/child_process_sandbox_support_linux.h" | 40 #include "content/public/common/child_process_sandbox_support_linux.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
| 44 #include <fcntl.h> | |
| 45 #include <io.h> | 44 #include <io.h> |
| 46 | 45 |
| 47 #include "content/public/common/sandbox_init.h" | 46 #include "content/public/common/sandbox_init.h" |
| 48 #endif | 47 #endif |
| 49 | 48 |
| 50 namespace { | 49 namespace { |
| 51 | 50 |
| 52 NaClListener* g_listener; | 51 NaClListener* g_listener; |
| 53 | 52 |
| 54 void FatalLogHandler(const char* data, size_t bytes) { | 53 void FatalLogHandler(const char* data, size_t bytes) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 return result; | 175 return result; |
| 177 } | 176 } |
| 178 | 177 |
| 179 virtual void SetKnownToValidate(const std::string& signature) override { | 178 virtual void SetKnownToValidate(const std::string& signature) override { |
| 180 // Caching is optional: NaCl will still work correctly if the IPC fails. | 179 // Caching is optional: NaCl will still work correctly if the IPC fails. |
| 181 if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { | 180 if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { |
| 182 LOG(ERROR) << "Failed to update NaCl validation cache."; | 181 LOG(ERROR) << "Failed to update NaCl validation cache."; |
| 183 } | 182 } |
| 184 } | 183 } |
| 185 | 184 |
| 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. | |
| 189 virtual bool ResolveFileToken(struct NaClFileToken* file_token, | |
| 190 int32* fd, std::string* path) override { | |
| 191 *fd = -1; | |
| 192 *path = ""; | |
| 193 if (!NaClFileTokenIsValid(file_token)) { | |
| 194 return false; | |
| 195 } | |
| 196 IPC::PlatformFileForTransit ipc_fd = IPC::InvalidPlatformFileForTransit(); | |
| 197 base::FilePath ipc_path; | |
| 198 if (!listener_->Send(new NaClProcessMsg_ResolveFileToken(file_token->lo, | |
| 199 file_token->hi, | |
| 200 &ipc_fd, | |
| 201 &ipc_path))) { | |
| 202 return false; | |
| 203 } | |
| 204 if (ipc_fd == IPC::InvalidPlatformFileForTransit()) { | |
| 205 return false; | |
| 206 } | |
| 207 base::PlatformFile handle = | |
| 208 IPC::PlatformFileForTransitToPlatformFile(ipc_fd); | |
| 209 #if defined(OS_WIN) | |
| 210 // On Windows, valid handles are 32 bit unsigned integers so this is safe. | |
| 211 *fd = reinterpret_cast<uintptr_t>(handle); | |
| 212 #else | |
| 213 *fd = handle; | |
| 214 #endif | |
| 215 // It doesn't matter if the path is invalid UTF8 as long as it's consistent | |
| 216 // and unforgeable. | |
| 217 *path = ipc_path.AsUTF8Unsafe(); | |
| 218 return true; | |
| 219 } | |
| 220 | |
| 221 private: | 185 private: |
| 222 // The listener never dies, otherwise this might be a dangling reference. | 186 // The listener never dies, otherwise this might be a dangling reference. |
| 223 NaClListener* listener_; | 187 NaClListener* listener_; |
| 224 }; | 188 }; |
| 225 | 189 |
| 226 | 190 |
| 227 NaClListener::NaClListener() : shutdown_event_(true, false), | 191 NaClListener::NaClListener() : shutdown_event_(true, false), |
| 228 io_thread_("NaCl_IOThread"), | 192 io_thread_("NaCl_IOThread"), |
| 229 #if defined(OS_LINUX) | 193 #if defined(OS_LINUX) |
| 230 prereserved_sandbox_size_(0), | 194 prereserved_sandbox_size_(0), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 258 | 222 |
| 259 // The NaClProcessMsg_ResolveFileTokenAsyncReply message must be | 223 // The NaClProcessMsg_ResolveFileTokenAsyncReply message must be |
| 260 // processed in a MessageFilter so it can be handled on the IO thread. | 224 // processed in a MessageFilter so it can be handled on the IO thread. |
| 261 // The main thread used by NaClListener is busy in | 225 // The main thread used by NaClListener is busy in |
| 262 // NaClChromeMainAppStart(), so it can't be used for servicing messages. | 226 // NaClChromeMainAppStart(), so it can't be used for servicing messages. |
| 263 class FileTokenMessageFilter : public IPC::MessageFilter { | 227 class FileTokenMessageFilter : public IPC::MessageFilter { |
| 264 public: | 228 public: |
| 265 virtual bool OnMessageReceived(const IPC::Message& msg) override { | 229 virtual bool OnMessageReceived(const IPC::Message& msg) override { |
| 266 bool handled = true; | 230 bool handled = true; |
| 267 IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) | 231 IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) |
| 268 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsyncReply, | 232 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenReply, |
| 269 OnResolveFileTokenAsyncReply) | 233 OnResolveFileTokenReply) |
| 270 IPC_MESSAGE_UNHANDLED(handled = false) | 234 IPC_MESSAGE_UNHANDLED(handled = false) |
| 271 IPC_END_MESSAGE_MAP() | 235 IPC_END_MESSAGE_MAP() |
| 272 return handled; | 236 return handled; |
| 273 } | 237 } |
| 274 | 238 |
| 275 void OnResolveFileTokenAsyncReply( | 239 void OnResolveFileTokenReply( |
| 276 uint64_t token_lo, | 240 uint64_t token_lo, |
| 277 uint64_t token_hi, | 241 uint64_t token_hi, |
| 278 IPC::PlatformFileForTransit ipc_fd, | 242 IPC::PlatformFileForTransit ipc_fd, |
| 279 base::FilePath file_path) { | 243 base::FilePath file_path) { |
| 280 CHECK(g_listener); | 244 CHECK(g_listener); |
| 281 g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); | 245 g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); |
| 282 } | 246 } |
| 283 private: | 247 private: |
| 284 virtual ~FileTokenMessageFilter() { } | 248 virtual ~FileTokenMessageFilter() { } |
| 285 }; | 249 }; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 #if defined(OS_WIN) | 411 #if defined(OS_WIN) |
| 448 args->broker_duplicate_handle_func = BrokerDuplicateHandle; | 412 args->broker_duplicate_handle_func = BrokerDuplicateHandle; |
| 449 args->attach_debug_exception_handler_func = AttachDebugExceptionHandler; | 413 args->attach_debug_exception_handler_func = AttachDebugExceptionHandler; |
| 450 args->debug_stub_server_port_selected_handler_func = | 414 args->debug_stub_server_port_selected_handler_func = |
| 451 DebugStubPortSelectedHandler; | 415 DebugStubPortSelectedHandler; |
| 452 #endif | 416 #endif |
| 453 #if defined(OS_LINUX) | 417 #if defined(OS_LINUX) |
| 454 args->prereserved_sandbox_size = prereserved_sandbox_size_; | 418 args->prereserved_sandbox_size = prereserved_sandbox_size_; |
| 455 #endif | 419 #endif |
| 456 | 420 |
| 457 NaClFileInfo nexe_file_info; | |
| 458 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( | 421 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( |
| 459 params.nexe_file); | 422 params.nexe_file); |
| 460 #if defined(OS_WIN) | 423 std::string file_path_str = params.nexe_file_path_metadata.AsUTF8Unsafe(); |
| 461 nexe_file_info.desc = | 424 args->nexe_desc = NaClDescCreateWithFilePathMetadata(nexe_file, |
| 462 _open_osfhandle(reinterpret_cast<intptr_t>(nexe_file), | 425 file_path_str.c_str()); |
| 463 _O_RDONLY | _O_BINARY); | |
| 464 #elif defined(OS_POSIX) | |
| 465 nexe_file_info.desc = nexe_file; | |
| 466 #else | |
| 467 #error Unsupported target platform. | |
| 468 #endif | |
| 469 nexe_file_info.file_token.lo = params.nexe_token_lo; | |
| 470 nexe_file_info.file_token.hi = params.nexe_token_hi; | |
| 471 args->nexe_desc = NaClDescIoFromFileInfo(nexe_file_info, NACL_ABI_O_RDONLY); | |
| 472 | 426 |
| 473 int exit_status; | 427 int exit_status; |
| 474 if (!NaClChromeMainStart(nap, args, &exit_status)) | 428 if (!NaClChromeMainStart(nap, args, &exit_status)) |
| 475 NaClExit(1); | 429 NaClExit(1); |
| 476 | 430 |
| 477 // Report the plugin's exit status if the application started successfully. | 431 // Report the plugin's exit status if the application started successfully. |
| 478 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); | 432 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
| 479 NaClExit(exit_status); | 433 NaClExit(exit_status); |
| 480 } | 434 } |
| 481 | 435 |
| 482 void NaClListener::ResolveFileToken( | 436 void NaClListener::ResolveFileToken( |
| 483 uint64_t token_lo, | 437 uint64_t token_lo, |
| 484 uint64_t token_hi, | 438 uint64_t token_hi, |
| 485 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { | 439 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
| 486 if (!Send(new NaClProcessMsg_ResolveFileTokenAsync(token_lo, token_hi))) { | 440 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { |
| 487 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); | 441 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
| 488 return; | 442 return; |
| 489 } | 443 } |
| 490 resolved_cb_ = cb; | 444 resolved_cb_ = cb; |
| 491 } | 445 } |
| 492 | 446 |
| 493 void NaClListener::OnFileTokenResolved( | 447 void NaClListener::OnFileTokenResolved( |
| 494 uint64_t token_lo, | 448 uint64_t token_lo, |
| 495 uint64_t token_hi, | 449 uint64_t token_hi, |
| 496 IPC::PlatformFileForTransit ipc_fd, | 450 IPC::PlatformFileForTransit ipc_fd, |
| 497 base::FilePath file_path) { | 451 base::FilePath file_path) { |
| 498 resolved_cb_.Run(ipc_fd, file_path); | 452 resolved_cb_.Run(ipc_fd, file_path); |
| 499 resolved_cb_.Reset(); | 453 resolved_cb_.Reset(); |
| 500 } | 454 } |
| OLD | NEW |