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 // A mini-zygote specifically for Native Client. | 5 // A mini-zygote specifically for Native Client. | 
| 6 | 6 | 
| 7 #include "components/nacl/loader/nacl_helper_linux.h" | 7 #include "components/nacl/loader/nacl_helper_linux.h" | 
| 8 | 8 | 
| 9 #include <errno.h> | 9 #include <errno.h> | 
| 10 #include <fcntl.h> | 10 #include <fcntl.h> | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "base/memory/scoped_ptr.h" | 25 #include "base/memory/scoped_ptr.h" | 
| 26 #include "base/memory/scoped_vector.h" | 26 #include "base/memory/scoped_vector.h" | 
| 27 #include "base/message_loop/message_loop.h" | 27 #include "base/message_loop/message_loop.h" | 
| 28 #include "base/posix/eintr_wrapper.h" | 28 #include "base/posix/eintr_wrapper.h" | 
| 29 #include "base/posix/global_descriptors.h" | 29 #include "base/posix/global_descriptors.h" | 
| 30 #include "base/posix/unix_domain_socket_linux.h" | 30 #include "base/posix/unix_domain_socket_linux.h" | 
| 31 #include "base/process/kill.h" | 31 #include "base/process/kill.h" | 
| 32 #include "base/process/process_handle.h" | 32 #include "base/process/process_handle.h" | 
| 33 #include "base/rand_util.h" | 33 #include "base/rand_util.h" | 
| 34 #include "components/nacl/common/nacl_switches.h" | 34 #include "components/nacl/common/nacl_switches.h" | 
| 35 #include "components/nacl/loader/nacl_listener.h" | |
| 36 #include "components/nacl/loader/nonsfi/nonsfi_listener.h" | |
| 37 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" | 35 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" | 
| 38 #include "content/public/common/content_descriptors.h" | 36 #include "content/public/common/content_descriptors.h" | 
| 39 #include "content/public/common/send_zygote_child_ping_linux.h" | 37 #include "content/public/common/send_zygote_child_ping_linux.h" | 
| 40 #include "content/public/common/zygote_fork_delegate_linux.h" | 38 #include "content/public/common/zygote_fork_delegate_linux.h" | 
| 41 #include "ipc/ipc_descriptors.h" | 39 #include "ipc/ipc_descriptors.h" | 
| 42 #include "ipc/ipc_switches.h" | 40 #include "ipc/ipc_switches.h" | 
| 43 #include "sandbox/linux/services/credentials.h" | 41 #include "sandbox/linux/services/credentials.h" | 
| 44 #include "sandbox/linux/services/namespace_sandbox.h" | 42 #include "sandbox/linux/services/namespace_sandbox.h" | 
| 45 | 43 | 
| 46 #if defined(OS_NACL_NONSFI) | 44 #if defined(OS_NACL_NONSFI) | 
| 45 #include "components/nacl/loader/nonsfi/nonsfi_listener.h" | |
| 47 #include "native_client/src/public/nonsfi/irt_exception_handling.h" | 46 #include "native_client/src/public/nonsfi/irt_exception_handling.h" | 
| 48 #else | 47 #else | 
| 49 #include <link.h> | 48 #include <link.h> | 
| 50 #include "components/nacl/loader/nonsfi/irt_exception_handling.h" | 49 #include "components/nacl/loader/nacl_listener.h" | 
| 51 #endif | 50 #endif | 
| 52 | 51 | 
| 53 namespace { | 52 namespace { | 
| 54 | 53 | 
| 55 struct NaClLoaderSystemInfo { | 54 struct NaClLoaderSystemInfo { | 
| 56 size_t prereserved_sandbox_size; | 55 size_t prereserved_sandbox_size; | 
| 57 long number_of_cores; | 56 long number_of_cores; | 
| 58 }; | 57 }; | 
| 59 | 58 | 
| 59 #if defined(OS_NACL_NONSFI) | |
| 60 // Replace |file_descriptor| with the reading end of a closed pipe. | 60 // Replace |file_descriptor| with the reading end of a closed pipe. | 
| 61 void ReplaceFDWithDummy(int file_descriptor) { | 61 void ReplaceFDWithDummy(int file_descriptor) { | 
| 62 // Make sure that file_descriptor is an open descriptor. | 62 // Make sure that file_descriptor is an open descriptor. | 
| 63 PCHECK(-1 != fcntl(file_descriptor, F_GETFD, 0)); | 63 PCHECK(-1 != fcntl(file_descriptor, F_GETFD, 0)); | 
| 64 int pipefd[2]; | 64 int pipefd[2]; | 
| 65 PCHECK(0 == pipe(pipefd)); | 65 PCHECK(0 == pipe(pipefd)); | 
| 66 PCHECK(-1 != dup2(pipefd[0], file_descriptor)); | 66 PCHECK(-1 != dup2(pipefd[0], file_descriptor)); | 
| 67 PCHECK(0 == IGNORE_EINTR(close(pipefd[0]))); | 67 PCHECK(0 == IGNORE_EINTR(close(pipefd[0]))); | 
| 68 PCHECK(0 == IGNORE_EINTR(close(pipefd[1]))); | 68 PCHECK(0 == IGNORE_EINTR(close(pipefd[1]))); | 
| 69 } | 69 } | 
| 70 #endif | |
| 70 | 71 | 
| 71 // The child must mimic the behavior of zygote_main_linux.cc on the child | 72 // The child must mimic the behavior of zygote_main_linux.cc on the child | 
| 72 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from | 73 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from | 
| 73 // if (!child) { | 74 // if (!child) { | 
| 74 void BecomeNaClLoader(base::ScopedFD browser_fd, | 75 void BecomeNaClLoader(base::ScopedFD browser_fd, | 
| 75 const NaClLoaderSystemInfo& system_info, | 76 const NaClLoaderSystemInfo& system_info, | 
| 76 bool uses_nonsfi_mode, | 77 bool uses_nonsfi_mode, | 
| 77 nacl::NaClSandbox* nacl_sandbox) { | 78 nacl::NaClSandbox* nacl_sandbox) { | 
| 78 DCHECK(nacl_sandbox); | 79 DCHECK(nacl_sandbox); | 
| 79 VLOG(1) << "NaCl loader: setting up IPC descriptor"; | 80 VLOG(1) << "NaCl loader: setting up IPC descriptor"; | 
| 80 // Close or shutdown IPC channels that we don't need anymore. | 81 // Close or shutdown IPC channels that we don't need anymore. | 
| 81 PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); | 82 PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); | 
| 83 | |
| 84 #if defined(OS_NACL_NONSFI) | |
| 82 // In Non-SFI mode, it's important to close any non-expected IPC channels. | 85 // In Non-SFI mode, it's important to close any non-expected IPC channels. | 
| 83 if (uses_nonsfi_mode) { | 86 CHECK(uses_nonsfi_mode); | 
| 
 
Mark Seaborn
2015/10/15 18:10:10
You could add:
#else
CHECK(!uses_nonsfi_mode);
o
 
hidehiko
2015/10/19 04:39:17
Done.
 
 | |
| 84 // The low-level kSandboxIPCChannel is used by renderers and NaCl for | 87 // The low-level kSandboxIPCChannel is used by renderers and NaCl for | 
| 85 // various operations. See the LinuxSandbox::METHOD_* methods. NaCl uses | 88 // various operations. See the LinuxSandbox::METHOD_* methods. NaCl uses | 
| 86 // LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT in SFI mode, so this | 89 // LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT in SFI mode, so this | 
| 87 // should only be closed in Non-SFI mode. | 90 // should only be closed in Non-SFI mode. | 
| 88 // This file descriptor is insidiously used by a number of APIs. Closing it | 91 // This file descriptor is insidiously used by a number of APIs. Closing it | 
| 89 // could lead to difficult to debug issues. Instead of closing it, replace | 92 // could lead to difficult to debug issues. Instead of closing it, replace | 
| 90 // it with a dummy. | 93 // it with a dummy. | 
| 91 const int sandbox_ipc_channel = | 94 const int sandbox_ipc_channel = | 
| 92 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; | 95 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; | 
| 93 | 96 | 
| 94 ReplaceFDWithDummy(sandbox_ipc_channel); | 97 ReplaceFDWithDummy(sandbox_ipc_channel); | 
| 95 | 98 | 
| 96 // Install crash signal handlers before disallowing system calls. | 99 // Install crash signal handlers before disallowing system calls. | 
| 97 #if defined(OS_NACL_NONSFI) | 100 nonsfi_initialize_signal_handler(); | 
| 98 nonsfi_initialize_signal_handler(); | |
| 99 #else | |
| 100 nacl::nonsfi::InitializeSignalHandler(); | |
| 101 #endif | 101 #endif | 
| 102 } | |
| 103 | 102 | 
| 104 // Always ignore SIGPIPE, for consistency with other Chrome processes and | 103 // Always ignore SIGPIPE, for consistency with other Chrome processes and | 
| 105 // because some IPC code, such as sync_socket_posix.cc, requires this. | 104 // because some IPC code, such as sync_socket_posix.cc, requires this. | 
| 106 // We do this before seccomp-bpf is initialized. | 105 // We do this before seccomp-bpf is initialized. | 
| 107 PCHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); | 106 PCHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); | 
| 108 | 107 | 
| 109 // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. | 108 // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. | 
| 110 CHECK(!nacl_sandbox->HasOpenDirectory()); | 109 CHECK(!nacl_sandbox->HasOpenDirectory()); | 
| 111 nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode); | 110 nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode); | 
| 112 nacl_sandbox->SealLayerOneSandbox(); | 111 nacl_sandbox->SealLayerOneSandbox(); | 
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 // Now handle requests from the Zygote. | 468 // Now handle requests from the Zygote. | 
| 470 while (true) { | 469 while (true) { | 
| 471 bool request_handled = HandleZygoteRequest( | 470 bool request_handled = HandleZygoteRequest( | 
| 472 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); | 471 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); | 
| 473 // Do not turn this into a CHECK() without thinking about robustness | 472 // Do not turn this into a CHECK() without thinking about robustness | 
| 474 // against malicious IPC requests. | 473 // against malicious IPC requests. | 
| 475 DCHECK(request_handled); | 474 DCHECK(request_handled); | 
| 476 } | 475 } | 
| 477 NOTREACHED(); | 476 NOTREACHED(); | 
| 478 } | 477 } | 
| OLD | NEW |