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 16 matching lines...) Expand all Loading... | |
27 #include "base/posix/eintr_wrapper.h" | 27 #include "base/posix/eintr_wrapper.h" |
28 #include "base/posix/global_descriptors.h" | 28 #include "base/posix/global_descriptors.h" |
29 #include "base/posix/unix_domain_socket_linux.h" | 29 #include "base/posix/unix_domain_socket_linux.h" |
30 #include "base/process/kill.h" | 30 #include "base/process/kill.h" |
31 #include "base/process/process_handle.h" | 31 #include "base/process/process_handle.h" |
32 #include "base/rand_util.h" | 32 #include "base/rand_util.h" |
33 #include "components/nacl/common/nacl_switches.h" | 33 #include "components/nacl/common/nacl_switches.h" |
34 #include "components/nacl/loader/nacl_listener.h" | 34 #include "components/nacl/loader/nacl_listener.h" |
35 #include "components/nacl/loader/nacl_sandbox_linux.h" | 35 #include "components/nacl/loader/nacl_sandbox_linux.h" |
36 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" | 36 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" |
37 #include "content/public/common/content_descriptors.h" | |
37 #include "content/public/common/zygote_fork_delegate_linux.h" | 38 #include "content/public/common/zygote_fork_delegate_linux.h" |
38 #include "crypto/nss_util.h" | 39 #include "crypto/nss_util.h" |
39 #include "ipc/ipc_descriptors.h" | 40 #include "ipc/ipc_descriptors.h" |
40 #include "ipc/ipc_switches.h" | 41 #include "ipc/ipc_switches.h" |
41 #include "sandbox/linux/services/credentials.h" | 42 #include "sandbox/linux/services/credentials.h" |
42 #include "sandbox/linux/services/libc_urandom_override.h" | 43 #include "sandbox/linux/services/libc_urandom_override.h" |
43 #include "sandbox/linux/services/thread_helpers.h" | 44 #include "sandbox/linux/services/thread_helpers.h" |
44 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" | 45 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" |
45 | 46 |
46 namespace { | 47 namespace { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 } | 107 } |
107 } else { | 108 } else { |
108 const bool bpf_sandbox_initialized = InitializeBPFSandbox(); | 109 const bool bpf_sandbox_initialized = InitializeBPFSandbox(); |
109 if (!bpf_sandbox_initialized) { | 110 if (!bpf_sandbox_initialized) { |
110 LOG(ERROR) << "Could not initialize NaCl's second " | 111 LOG(ERROR) << "Could not initialize NaCl's second " |
111 << "layer sandbox (seccomp-bpf) for SFI mode."; | 112 << "layer sandbox (seccomp-bpf) for SFI mode."; |
112 } | 113 } |
113 } | 114 } |
114 } | 115 } |
115 | 116 |
117 // Replace |file_descriptor| with the reading end of a closed pipe. | |
118 void ReplaceFDWithDummy(int file_descriptor) { | |
119 // Make sure that file_descriptor is an open descriptor. | |
120 PCHECK(-1 != fcntl(file_descriptor, F_GETFD, 0)); | |
121 int pipefd[2]; | |
122 PCHECK(0 == pipe(pipefd)); | |
123 PCHECK(-1 != dup2(pipefd[0], file_descriptor)); | |
124 PCHECK(0 == IGNORE_EINTR(close(pipefd[0]))); | |
125 PCHECK(0 == IGNORE_EINTR(close(pipefd[1]))); | |
126 } | |
127 | |
116 // The child must mimic the behavior of zygote_main_linux.cc on the child | 128 // The child must mimic the behavior of zygote_main_linux.cc on the child |
117 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from | 129 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from |
118 // if (!child) { | 130 // if (!child) { |
119 void BecomeNaClLoader(const std::vector<int>& child_fds, | 131 void BecomeNaClLoader(const std::vector<int>& child_fds, |
120 const NaClLoaderSystemInfo& system_info, | 132 const NaClLoaderSystemInfo& system_info, |
121 bool uses_nonsfi_mode) { | 133 bool uses_nonsfi_mode) { |
122 VLOG(1) << "NaCl loader: setting up IPC descriptor"; | 134 VLOG(1) << "NaCl loader: setting up IPC descriptor"; |
123 // don't need zygote FD any more | 135 // Close or shutdown IPC channels that we don't need anymore. |
124 if (IGNORE_EINTR(close(kNaClZygoteDescriptor)) != 0) | 136 PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); |
125 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed."; | 137 // In Non-SFI mode, it's important to close any non-expected IPC channels. |
138 if (uses_nonsfi_mode) { | |
139 // The low-level kSandboxIPCChannel is used by renderers and NaCl for | |
140 // various operations. See the LinuxSandbox::METHOD_* methods. NaCl uses | |
141 // LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT in SFI mode, so this | |
142 // should only be close in Non-SFI mode. | |
Mark Seaborn
2014/04/25 22:59:55
"closed"
jln (very slow on Chromium)
2014/04/25 23:40:55
Done.
| |
143 // This file descriptor is insidiously used by a number of APIs. Closing it | |
144 // could lead to difficult to debug issues. Instead of closing it, replace | |
145 // it with a dummy. | |
146 const int sandbox_ipc_channel = | |
147 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; | |
148 | |
149 ReplaceFDWithDummy(sandbox_ipc_channel); | |
150 } | |
151 | |
126 InitializeLayerTwoSandbox(uses_nonsfi_mode); | 152 InitializeLayerTwoSandbox(uses_nonsfi_mode); |
127 base::GlobalDescriptors::GetInstance()->Set( | 153 base::GlobalDescriptors::GetInstance()->Set( |
128 kPrimaryIPCChannel, | 154 kPrimaryIPCChannel, |
129 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); | 155 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); |
130 | 156 |
131 base::MessageLoopForIO main_message_loop; | 157 base::MessageLoopForIO main_message_loop; |
132 NaClListener listener; | 158 NaClListener listener; |
133 listener.set_uses_nonsfi_mode(uses_nonsfi_mode); | 159 listener.set_uses_nonsfi_mode(uses_nonsfi_mode); |
134 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); | 160 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); |
135 listener.set_number_of_cores(system_info.number_of_cores); | 161 listener.set_number_of_cores(system_info.number_of_cores); |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 // Now handle requests from the Zygote. | 489 // Now handle requests from the Zygote. |
464 while (true) { | 490 while (true) { |
465 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, | 491 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, |
466 system_info); | 492 system_info); |
467 // Do not turn this into a CHECK() without thinking about robustness | 493 // Do not turn this into a CHECK() without thinking about robustness |
468 // against malicious IPC requests. | 494 // against malicious IPC requests. |
469 DCHECK(request_handled); | 495 DCHECK(request_handled); |
470 } | 496 } |
471 NOTREACHED(); | 497 NOTREACHED(); |
472 } | 498 } |
OLD | NEW |