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 void SetKnownToValidate(const std::string& signature) override { | 178 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 bool ResolveFileToken(struct NaClFileToken* file_token, | |
190 int32* fd, | |
191 std::string* path) override { | |
192 *fd = -1; | |
193 *path = ""; | |
194 if (!NaClFileTokenIsValid(file_token)) { | |
195 return false; | |
196 } | |
197 IPC::PlatformFileForTransit ipc_fd = IPC::InvalidPlatformFileForTransit(); | |
198 base::FilePath ipc_path; | |
199 if (!listener_->Send(new NaClProcessMsg_ResolveFileToken(file_token->lo, | |
200 file_token->hi, | |
201 &ipc_fd, | |
202 &ipc_path))) { | |
203 return false; | |
204 } | |
205 if (ipc_fd == IPC::InvalidPlatformFileForTransit()) { | |
206 return false; | |
207 } | |
208 base::PlatformFile handle = | |
209 IPC::PlatformFileForTransitToPlatformFile(ipc_fd); | |
210 #if defined(OS_WIN) | |
211 // On Windows, valid handles are 32 bit unsigned integers so this is safe. | |
212 *fd = reinterpret_cast<int32>(handle); | |
213 #else | |
214 *fd = handle; | |
215 #endif | |
216 // It doesn't matter if the path is invalid UTF8 as long as it's consistent | |
217 // and unforgeable. | |
218 *path = ipc_path.AsUTF8Unsafe(); | |
219 return true; | |
220 } | |
221 | |
222 private: | 185 private: |
223 // The listener never dies, otherwise this might be a dangling reference. | 186 // The listener never dies, otherwise this might be a dangling reference. |
224 NaClListener* listener_; | 187 NaClListener* listener_; |
225 }; | 188 }; |
226 | 189 |
227 | 190 |
228 NaClListener::NaClListener() : shutdown_event_(true, false), | 191 NaClListener::NaClListener() : shutdown_event_(true, false), |
229 io_thread_("NaCl_IOThread"), | 192 io_thread_("NaCl_IOThread"), |
230 #if defined(OS_LINUX) | 193 #if defined(OS_LINUX) |
231 prereserved_sandbox_size_(0), | 194 prereserved_sandbox_size_(0), |
(...skipping 27 matching lines...) Expand all Loading... |
259 | 222 |
260 // The NaClProcessMsg_ResolveFileTokenAsyncReply message must be | 223 // The NaClProcessMsg_ResolveFileTokenAsyncReply message must be |
261 // 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. |
262 // The main thread used by NaClListener is busy in | 225 // The main thread used by NaClListener is busy in |
263 // NaClChromeMainAppStart(), so it can't be used for servicing messages. | 226 // NaClChromeMainAppStart(), so it can't be used for servicing messages. |
264 class FileTokenMessageFilter : public IPC::MessageFilter { | 227 class FileTokenMessageFilter : public IPC::MessageFilter { |
265 public: | 228 public: |
266 bool OnMessageReceived(const IPC::Message& msg) override { | 229 bool OnMessageReceived(const IPC::Message& msg) override { |
267 bool handled = true; | 230 bool handled = true; |
268 IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) | 231 IPC_BEGIN_MESSAGE_MAP(FileTokenMessageFilter, msg) |
269 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsyncReply, | 232 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenReply, |
270 OnResolveFileTokenAsyncReply) | 233 OnResolveFileTokenReply) |
271 IPC_MESSAGE_UNHANDLED(handled = false) | 234 IPC_MESSAGE_UNHANDLED(handled = false) |
272 IPC_END_MESSAGE_MAP() | 235 IPC_END_MESSAGE_MAP() |
273 return handled; | 236 return handled; |
274 } | 237 } |
275 | 238 |
276 void OnResolveFileTokenAsyncReply( | 239 void OnResolveFileTokenReply( |
277 uint64_t token_lo, | 240 uint64_t token_lo, |
278 uint64_t token_hi, | 241 uint64_t token_hi, |
279 IPC::PlatformFileForTransit ipc_fd, | 242 IPC::PlatformFileForTransit ipc_fd, |
280 base::FilePath file_path) { | 243 base::FilePath file_path) { |
281 CHECK(g_listener); | 244 CHECK(g_listener); |
282 g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); | 245 g_listener->OnFileTokenResolved(token_lo, token_hi, ipc_fd, file_path); |
283 } | 246 } |
284 private: | 247 private: |
285 ~FileTokenMessageFilter() override {} | 248 ~FileTokenMessageFilter() override {} |
286 }; | 249 }; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 #if defined(OS_WIN) | 410 #if defined(OS_WIN) |
448 args->broker_duplicate_handle_func = BrokerDuplicateHandle; | 411 args->broker_duplicate_handle_func = BrokerDuplicateHandle; |
449 args->attach_debug_exception_handler_func = AttachDebugExceptionHandler; | 412 args->attach_debug_exception_handler_func = AttachDebugExceptionHandler; |
450 args->debug_stub_server_port_selected_handler_func = | 413 args->debug_stub_server_port_selected_handler_func = |
451 DebugStubPortSelectedHandler; | 414 DebugStubPortSelectedHandler; |
452 #endif | 415 #endif |
453 #if defined(OS_LINUX) | 416 #if defined(OS_LINUX) |
454 args->prereserved_sandbox_size = prereserved_sandbox_size_; | 417 args->prereserved_sandbox_size = prereserved_sandbox_size_; |
455 #endif | 418 #endif |
456 | 419 |
457 NaClFileInfo nexe_file_info; | |
458 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( | 420 base::PlatformFile nexe_file = IPC::PlatformFileForTransitToPlatformFile( |
459 params.nexe_file); | 421 params.nexe_file); |
460 #if defined(OS_WIN) | 422 std::string file_path_str = params.nexe_file_path_metadata.AsUTF8Unsafe(); |
461 nexe_file_info.desc = | 423 args->nexe_desc = NaClDescCreateWithFilePathMetadata(nexe_file, |
462 _open_osfhandle(reinterpret_cast<intptr_t>(nexe_file), | 424 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 | 425 |
473 int exit_status; | 426 int exit_status; |
474 if (!NaClChromeMainStart(nap, args, &exit_status)) | 427 if (!NaClChromeMainStart(nap, args, &exit_status)) |
475 NaClExit(1); | 428 NaClExit(1); |
476 | 429 |
477 // Report the plugin's exit status if the application started successfully. | 430 // Report the plugin's exit status if the application started successfully. |
478 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); | 431 trusted_listener_->Send(new NaClRendererMsg_ReportExitStatus(exit_status)); |
479 NaClExit(exit_status); | 432 NaClExit(exit_status); |
480 } | 433 } |
481 | 434 |
482 void NaClListener::ResolveFileToken( | 435 void NaClListener::ResolveFileToken( |
483 uint64_t token_lo, | 436 uint64_t token_lo, |
484 uint64_t token_hi, | 437 uint64_t token_hi, |
485 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { | 438 base::Callback<void(IPC::PlatformFileForTransit, base::FilePath)> cb) { |
486 if (!Send(new NaClProcessMsg_ResolveFileTokenAsync(token_lo, token_hi))) { | 439 if (!Send(new NaClProcessMsg_ResolveFileToken(token_lo, token_hi))) { |
487 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); | 440 cb.Run(IPC::PlatformFileForTransit(), base::FilePath()); |
488 return; | 441 return; |
489 } | 442 } |
490 resolved_cb_ = cb; | 443 resolved_cb_ = cb; |
491 } | 444 } |
492 | 445 |
493 void NaClListener::OnFileTokenResolved( | 446 void NaClListener::OnFileTokenResolved( |
494 uint64_t token_lo, | 447 uint64_t token_lo, |
495 uint64_t token_hi, | 448 uint64_t token_hi, |
496 IPC::PlatformFileForTransit ipc_fd, | 449 IPC::PlatformFileForTransit ipc_fd, |
497 base::FilePath file_path) { | 450 base::FilePath file_path) { |
498 resolved_cb_.Run(ipc_fd, file_path); | 451 resolved_cb_.Run(ipc_fd, file_path); |
499 resolved_cb_.Reset(); | 452 resolved_cb_.Reset(); |
500 } | 453 } |
OLD | NEW |