| 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); | 
|   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 |  101 #else | 
|  100     nacl::nonsfi::InitializeSignalHandler(); |  102   CHECK(!uses_nonsfi_mode); | 
|  101 #endif |  103 #endif | 
|  102   } |  | 
|  103  |  104  | 
|  104   // Always ignore SIGPIPE, for consistency with other Chrome processes and |  105   // Always ignore SIGPIPE, for consistency with other Chrome processes and | 
|  105   // because some IPC code, such as sync_socket_posix.cc, requires this. |  106   // because some IPC code, such as sync_socket_posix.cc, requires this. | 
|  106   // We do this before seccomp-bpf is initialized. |  107   // We do this before seccomp-bpf is initialized. | 
|  107   PCHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); |  108   PCHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); | 
|  108  |  109  | 
|  109   // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. |  110   // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. | 
|  110   CHECK(!nacl_sandbox->HasOpenDirectory()); |  111   CHECK(!nacl_sandbox->HasOpenDirectory()); | 
|  111   nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode); |  112   nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode); | 
|  112   nacl_sandbox->SealLayerOneSandbox(); |  113   nacl_sandbox->SealLayerOneSandbox(); | 
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  469   // Now handle requests from the Zygote. |  470   // Now handle requests from the Zygote. | 
|  470   while (true) { |  471   while (true) { | 
|  471     bool request_handled = HandleZygoteRequest( |  472     bool request_handled = HandleZygoteRequest( | 
|  472         kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); |  473         kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); | 
|  473     // Do not turn this into a CHECK() without thinking about robustness |  474     // Do not turn this into a CHECK() without thinking about robustness | 
|  474     // against malicious IPC requests. |  475     // against malicious IPC requests. | 
|  475     DCHECK(request_handled); |  476     DCHECK(request_handled); | 
|  476   } |  477   } | 
|  477   NOTREACHED(); |  478   NOTREACHED(); | 
|  478 } |  479 } | 
| OLD | NEW |