Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(890)

Side by Side Diff: components/nacl/loader/nacl_helper_linux.cc

Issue 250773003: NaCl Linux: create NaClSandbox class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/nacl/loader/OWNERS ('k') | components/nacl/loader/nacl_sandbox_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
25 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
26 #include "base/message_loop/message_loop.h" 26 #include "base/message_loop/message_loop.h"
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/sandbox_linux/nacl_sandbox_linux.h"
36 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h"
37 #include "content/public/common/content_descriptors.h" 36 #include "content/public/common/content_descriptors.h"
38 #include "content/public/common/zygote_fork_delegate_linux.h" 37 #include "content/public/common/zygote_fork_delegate_linux.h"
39 #include "crypto/nss_util.h" 38 #include "crypto/nss_util.h"
40 #include "ipc/ipc_descriptors.h" 39 #include "ipc/ipc_descriptors.h"
41 #include "ipc/ipc_switches.h" 40 #include "ipc/ipc_switches.h"
42 #include "sandbox/linux/services/credentials.h"
43 #include "sandbox/linux/services/libc_urandom_override.h" 41 #include "sandbox/linux/services/libc_urandom_override.h"
44 #include "sandbox/linux/services/thread_helpers.h"
45 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
46 42
47 namespace { 43 namespace {
48 44
49 struct NaClLoaderSystemInfo { 45 struct NaClLoaderSystemInfo {
50 size_t prereserved_sandbox_size; 46 size_t prereserved_sandbox_size;
51 long number_of_cores; 47 long number_of_cores;
52 }; 48 };
53 49
54 // This is a poor man's check on whether we are sandboxed.
55 bool IsSandboxed() {
56 int proc_fd = open("/proc/self/exe", O_RDONLY);
57 if (proc_fd >= 0) {
58 close(proc_fd);
59 return false;
60 }
61 return true;
62 }
63
64 void InitializeLayerOneSandbox() {
65 // Check that IsSandboxed() works. We should not be sandboxed at this point.
66 CHECK(!IsSandboxed()) << "Unexpectedly sandboxed!";
67 scoped_ptr<sandbox::SetuidSandboxClient>
68 setuid_sandbox_client(sandbox::SetuidSandboxClient::Create());
69 PCHECK(0 == IGNORE_EINTR(close(
70 setuid_sandbox_client->GetUniqueToChildFileDescriptor())));
71 const bool suid_sandbox_child = setuid_sandbox_client->IsSuidSandboxChild();
72 const bool is_init_process = 1 == getpid();
73 CHECK_EQ(is_init_process, suid_sandbox_child);
74
75 if (suid_sandbox_child) {
76 // Make sure that no directory file descriptor is open, as it would bypass
77 // the setuid sandbox model.
78 sandbox::Credentials credentials;
79 CHECK(!credentials.HasOpenDirectory(-1));
80
81 // Get sandboxed.
82 CHECK(setuid_sandbox_client->ChrootMe());
83 CHECK(IsSandboxed());
84 }
85 }
86
87 void InitializeLayerTwoSandbox(bool uses_nonsfi_mode) {
88 if (uses_nonsfi_mode) {
89 const bool can_be_no_sandbox = CommandLine::ForCurrentProcess()->HasSwitch(
90 switches::kNaClDangerousNoSandboxNonSfi);
91 const bool setuid_sandbox_enabled = IsSandboxed();
92 if (!setuid_sandbox_enabled) {
93 if (can_be_no_sandbox)
94 LOG(ERROR) << "DANGEROUS: Running non-SFI NaCl without SUID sandbox!";
95 else
96 LOG(FATAL) << "SUID sandbox is mandatory for non-SFI NaCl";
97 }
98 const bool bpf_sandbox_initialized = nacl::nonsfi::InitializeBPFSandbox();
99 if (!bpf_sandbox_initialized) {
100 if (can_be_no_sandbox) {
101 LOG(ERROR)
102 << "DANGEROUS: Running non-SFI NaCl without seccomp-bpf sandbox!";
103 } else {
104 LOG(FATAL) << "Could not initialize NaCl's second "
105 << "layer sandbox (seccomp-bpf) for non-SFI mode.";
106 }
107 }
108 } else {
109 const bool bpf_sandbox_initialized = InitializeBPFSandbox();
110 if (!bpf_sandbox_initialized) {
111 LOG(ERROR) << "Could not initialize NaCl's second "
112 << "layer sandbox (seccomp-bpf) for SFI mode.";
113 }
114 }
115 }
116
117 // Replace |file_descriptor| with the reading end of a closed pipe. 50 // Replace |file_descriptor| with the reading end of a closed pipe.
118 void ReplaceFDWithDummy(int file_descriptor) { 51 void ReplaceFDWithDummy(int file_descriptor) {
119 // Make sure that file_descriptor is an open descriptor. 52 // Make sure that file_descriptor is an open descriptor.
120 PCHECK(-1 != fcntl(file_descriptor, F_GETFD, 0)); 53 PCHECK(-1 != fcntl(file_descriptor, F_GETFD, 0));
121 int pipefd[2]; 54 int pipefd[2];
122 PCHECK(0 == pipe(pipefd)); 55 PCHECK(0 == pipe(pipefd));
123 PCHECK(-1 != dup2(pipefd[0], file_descriptor)); 56 PCHECK(-1 != dup2(pipefd[0], file_descriptor));
124 PCHECK(0 == IGNORE_EINTR(close(pipefd[0]))); 57 PCHECK(0 == IGNORE_EINTR(close(pipefd[0])));
125 PCHECK(0 == IGNORE_EINTR(close(pipefd[1]))); 58 PCHECK(0 == IGNORE_EINTR(close(pipefd[1])));
126 } 59 }
127 60
128 // The child must mimic the behavior of zygote_main_linux.cc on the child 61 // The child must mimic the behavior of zygote_main_linux.cc on the child
129 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from 62 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from
130 // if (!child) { 63 // if (!child) {
131 void BecomeNaClLoader(const std::vector<int>& child_fds, 64 void BecomeNaClLoader(const std::vector<int>& child_fds,
132 const NaClLoaderSystemInfo& system_info, 65 const NaClLoaderSystemInfo& system_info,
133 bool uses_nonsfi_mode) { 66 bool uses_nonsfi_mode,
67 nacl::NaClSandbox* nacl_sandbox) {
68 DCHECK(nacl_sandbox);
134 VLOG(1) << "NaCl loader: setting up IPC descriptor"; 69 VLOG(1) << "NaCl loader: setting up IPC descriptor";
135 // Close or shutdown IPC channels that we don't need anymore. 70 // Close or shutdown IPC channels that we don't need anymore.
136 PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); 71 PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor)));
137 // In Non-SFI mode, it's important to close any non-expected IPC channels. 72 // In Non-SFI mode, it's important to close any non-expected IPC channels.
138 if (uses_nonsfi_mode) { 73 if (uses_nonsfi_mode) {
139 // The low-level kSandboxIPCChannel is used by renderers and NaCl for 74 // The low-level kSandboxIPCChannel is used by renderers and NaCl for
140 // various operations. See the LinuxSandbox::METHOD_* methods. NaCl uses 75 // various operations. See the LinuxSandbox::METHOD_* methods. NaCl uses
141 // LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT in SFI mode, so this 76 // LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT in SFI mode, so this
142 // should only be closed in Non-SFI mode. 77 // should only be closed in Non-SFI mode.
143 // This file descriptor is insidiously used by a number of APIs. Closing it 78 // 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 79 // could lead to difficult to debug issues. Instead of closing it, replace
145 // it with a dummy. 80 // it with a dummy.
146 const int sandbox_ipc_channel = 81 const int sandbox_ipc_channel =
147 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; 82 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel;
148 83
149 ReplaceFDWithDummy(sandbox_ipc_channel); 84 ReplaceFDWithDummy(sandbox_ipc_channel);
150 } 85 }
151 86
152 InitializeLayerTwoSandbox(uses_nonsfi_mode); 87 // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox.
88 CHECK(!nacl_sandbox->HasOpenDirectory());
89 nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode);
90 nacl_sandbox->SealLayerOneSandbox();
91 nacl_sandbox->CheckSandboxingStateWithPolicy();
92
153 base::GlobalDescriptors::GetInstance()->Set( 93 base::GlobalDescriptors::GetInstance()->Set(
154 kPrimaryIPCChannel, 94 kPrimaryIPCChannel,
155 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); 95 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]);
156 96
157 base::MessageLoopForIO main_message_loop; 97 base::MessageLoopForIO main_message_loop;
158 NaClListener listener; 98 NaClListener listener;
159 listener.set_uses_nonsfi_mode(uses_nonsfi_mode); 99 listener.set_uses_nonsfi_mode(uses_nonsfi_mode);
160 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); 100 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size);
161 listener.set_number_of_cores(system_info.number_of_cores); 101 listener.set_number_of_cores(system_info.number_of_cores);
162 listener.Listen(); 102 listener.Listen();
163 _exit(0); 103 _exit(0);
164 } 104 }
165 105
166 // Start the NaCl loader in a child created by the NaCl loader Zygote. 106 // Start the NaCl loader in a child created by the NaCl loader Zygote.
167 void ChildNaClLoaderInit(const std::vector<int>& child_fds, 107 void ChildNaClLoaderInit(const std::vector<int>& child_fds,
168 const NaClLoaderSystemInfo& system_info, 108 const NaClLoaderSystemInfo& system_info,
169 bool uses_nonsfi_mode, 109 bool uses_nonsfi_mode,
110 nacl::NaClSandbox* nacl_sandbox,
170 const std::string& channel_id) { 111 const std::string& channel_id) {
171 const int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex]; 112 const int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex];
172 const int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex]; 113 const int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex];
173 114
174 bool validack = false; 115 bool validack = false;
175 base::ProcessId real_pid; 116 base::ProcessId real_pid;
176 // Wait until the parent process has discovered our PID. We 117 // Wait until the parent process has discovered our PID. We
177 // should not fork any child processes (which the seccomp 118 // should not fork any child processes (which the seccomp
178 // sandbox does) until then, because that can interfere with the 119 // sandbox does) until then, because that can interfere with the
179 // parent's discovery of our PID. 120 // parent's discovery of our PID.
(...skipping 12 matching lines...) Expand all
192 if (nread < 0) 133 if (nread < 0)
193 perror("read"); 134 perror("read");
194 LOG(ERROR) << "read returned " << nread; 135 LOG(ERROR) << "read returned " << nread;
195 } 136 }
196 137
197 if (IGNORE_EINTR(close(dummy_fd)) != 0) 138 if (IGNORE_EINTR(close(dummy_fd)) != 0)
198 LOG(ERROR) << "close(dummy_fd) failed"; 139 LOG(ERROR) << "close(dummy_fd) failed";
199 if (IGNORE_EINTR(close(parent_fd)) != 0) 140 if (IGNORE_EINTR(close(parent_fd)) != 0)
200 LOG(ERROR) << "close(parent_fd) failed"; 141 LOG(ERROR) << "close(parent_fd) failed";
201 if (validack) { 142 if (validack) {
202 BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode); 143 BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode, nacl_sandbox);
203 } else { 144 } else {
204 LOG(ERROR) << "Failed to synch with zygote"; 145 LOG(ERROR) << "Failed to synch with zygote";
205 } 146 }
206 _exit(1); 147 _exit(1);
207 } 148 }
208 149
209 // Handle a fork request from the Zygote. 150 // Handle a fork request from the Zygote.
210 // Some of this code was lifted from 151 // Some of this code was lifted from
211 // content/browser/zygote_main_linux.cc:ForkWithRealPid() 152 // content/browser/zygote_main_linux.cc:ForkWithRealPid()
212 bool HandleForkRequest(const std::vector<int>& child_fds, 153 bool HandleForkRequest(const std::vector<int>& child_fds,
213 const NaClLoaderSystemInfo& system_info, 154 const NaClLoaderSystemInfo& system_info,
155 nacl::NaClSandbox* nacl_sandbox,
214 PickleIterator* input_iter, 156 PickleIterator* input_iter,
215 Pickle* output_pickle) { 157 Pickle* output_pickle) {
216 bool uses_nonsfi_mode; 158 bool uses_nonsfi_mode;
217 if (!input_iter->ReadBool(&uses_nonsfi_mode)) { 159 if (!input_iter->ReadBool(&uses_nonsfi_mode)) {
218 LOG(ERROR) << "Could not read uses_nonsfi_mode status"; 160 LOG(ERROR) << "Could not read uses_nonsfi_mode status";
219 return false; 161 return false;
220 } 162 }
221 163
222 std::string channel_id; 164 std::string channel_id;
223 if (!input_iter->ReadString(&channel_id)) { 165 if (!input_iter->ReadString(&channel_id)) {
224 LOG(ERROR) << "Could not read channel_id string"; 166 LOG(ERROR) << "Could not read channel_id string";
225 return false; 167 return false;
226 } 168 }
227 169
228 if (content::ZygoteForkDelegate::kNumPassedFDs != child_fds.size()) { 170 if (content::ZygoteForkDelegate::kNumPassedFDs != child_fds.size()) {
229 LOG(ERROR) << "nacl_helper: unexpected number of fds, got " 171 LOG(ERROR) << "nacl_helper: unexpected number of fds, got "
230 << child_fds.size(); 172 << child_fds.size();
231 return false; 173 return false;
232 } 174 }
233 175
234 VLOG(1) << "nacl_helper: forking"; 176 VLOG(1) << "nacl_helper: forking";
235 pid_t child_pid = fork(); 177 pid_t child_pid = fork();
236 if (child_pid < 0) { 178 if (child_pid < 0) {
237 PLOG(ERROR) << "*** fork() failed."; 179 PLOG(ERROR) << "*** fork() failed.";
238 } 180 }
239 181
240 if (child_pid == 0) { 182 if (child_pid == 0) {
241 ChildNaClLoaderInit(child_fds, system_info, uses_nonsfi_mode, channel_id); 183 ChildNaClLoaderInit(
184 child_fds, system_info, uses_nonsfi_mode, nacl_sandbox, channel_id);
242 NOTREACHED(); 185 NOTREACHED();
243 } 186 }
244 187
245 // I am the parent. 188 // I am the parent.
246 // First, close the dummy_fd so the sandbox won't find me when 189 // First, close the dummy_fd so the sandbox won't find me when
247 // looking for the child's pid in /proc. Also close other fds. 190 // looking for the child's pid in /proc. Also close other fds.
248 for (size_t i = 0; i < child_fds.size(); i++) { 191 for (size_t i = 0; i < child_fds.size(); i++) {
249 if (IGNORE_EINTR(close(child_fds[i])) != 0) 192 if (IGNORE_EINTR(close(child_fds[i])) != 0)
250 LOG(ERROR) << "close(child_fds[i]) failed"; 193 LOG(ERROR) << "close(child_fds[i]) failed";
251 } 194 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 229 }
287 230
288 // Honor a command |command_type|. Eventual command parameters are 231 // Honor a command |command_type|. Eventual command parameters are
289 // available in |input_iter| and eventual file descriptors attached to 232 // available in |input_iter| and eventual file descriptors attached to
290 // the command are in |attached_fds|. 233 // the command are in |attached_fds|.
291 // Reply to the command on |reply_fds|. 234 // Reply to the command on |reply_fds|.
292 bool HonorRequestAndReply(int reply_fd, 235 bool HonorRequestAndReply(int reply_fd,
293 int command_type, 236 int command_type,
294 const std::vector<int>& attached_fds, 237 const std::vector<int>& attached_fds,
295 const NaClLoaderSystemInfo& system_info, 238 const NaClLoaderSystemInfo& system_info,
239 nacl::NaClSandbox* nacl_sandbox,
296 PickleIterator* input_iter) { 240 PickleIterator* input_iter) {
297 Pickle write_pickle; 241 Pickle write_pickle;
298 bool have_to_reply = false; 242 bool have_to_reply = false;
299 // Commands must write anything to send back to |write_pickle|. 243 // Commands must write anything to send back to |write_pickle|.
300 switch (command_type) { 244 switch (command_type) {
301 case nacl::kNaClForkRequest: 245 case nacl::kNaClForkRequest:
302 have_to_reply = HandleForkRequest(attached_fds, system_info, 246 have_to_reply = HandleForkRequest(
303 input_iter, &write_pickle); 247 attached_fds, system_info, nacl_sandbox, input_iter, &write_pickle);
304 break; 248 break;
305 case nacl::kNaClGetTerminationStatusRequest: 249 case nacl::kNaClGetTerminationStatusRequest:
306 have_to_reply = 250 have_to_reply =
307 HandleGetTerminationStatusRequest(input_iter, &write_pickle); 251 HandleGetTerminationStatusRequest(input_iter, &write_pickle);
308 break; 252 break;
309 default: 253 default:
310 LOG(ERROR) << "Unsupported command from Zygote"; 254 LOG(ERROR) << "Unsupported command from Zygote";
311 return false; 255 return false;
312 } 256 }
313 if (!have_to_reply) 257 if (!have_to_reply)
314 return false; 258 return false;
315 const std::vector<int> empty; // We never send file descriptors back. 259 const std::vector<int> empty; // We never send file descriptors back.
316 if (!UnixDomainSocket::SendMsg(reply_fd, write_pickle.data(), 260 if (!UnixDomainSocket::SendMsg(reply_fd, write_pickle.data(),
317 write_pickle.size(), empty)) { 261 write_pickle.size(), empty)) {
318 LOG(ERROR) << "*** send() to zygote failed"; 262 LOG(ERROR) << "*** send() to zygote failed";
319 return false; 263 return false;
320 } 264 }
321 return true; 265 return true;
322 } 266 }
323 267
324 // Read a request from the Zygote from |zygote_ipc_fd| and handle it. 268 // Read a request from the Zygote from |zygote_ipc_fd| and handle it.
325 // Die on EOF from |zygote_ipc_fd|. 269 // Die on EOF from |zygote_ipc_fd|.
326 bool HandleZygoteRequest(int zygote_ipc_fd, 270 bool HandleZygoteRequest(int zygote_ipc_fd,
327 const NaClLoaderSystemInfo& system_info) { 271 const NaClLoaderSystemInfo& system_info,
272 nacl::NaClSandbox* nacl_sandbox) {
328 std::vector<int> fds; 273 std::vector<int> fds;
329 char buf[kNaClMaxIPCMessageLength]; 274 char buf[kNaClMaxIPCMessageLength];
330 const ssize_t msglen = UnixDomainSocket::RecvMsg(zygote_ipc_fd, 275 const ssize_t msglen = UnixDomainSocket::RecvMsg(zygote_ipc_fd,
331 &buf, sizeof(buf), &fds); 276 &buf, sizeof(buf), &fds);
332 // If the Zygote has started handling requests, we should be sandboxed via 277 // If the Zygote has started handling requests, we should be sandboxed via
333 // the setuid sandbox. 278 // the setuid sandbox.
334 if (!IsSandboxed()) { 279 if (!nacl_sandbox->layer_one_enabled()) {
335 LOG(ERROR) << "NaCl helper process running without a sandbox!\n" 280 LOG(ERROR) << "NaCl helper process running without a sandbox!\n"
336 << "Most likely you need to configure your SUID sandbox " 281 << "Most likely you need to configure your SUID sandbox "
337 << "correctly"; 282 << "correctly";
338 } 283 }
339 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) { 284 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) {
340 // EOF from the browser. Goodbye! 285 // EOF from the browser. Goodbye!
341 _exit(0); 286 _exit(0);
342 } 287 }
343 if (msglen < 0) { 288 if (msglen < 0) {
344 PLOG(ERROR) << "nacl_helper: receive from zygote failed"; 289 PLOG(ERROR) << "nacl_helper: receive from zygote failed";
345 return false; 290 return false;
346 } 291 }
347 292
348 Pickle read_pickle(buf, msglen); 293 Pickle read_pickle(buf, msglen);
349 PickleIterator read_iter(read_pickle); 294 PickleIterator read_iter(read_pickle);
350 int command_type; 295 int command_type;
351 if (!read_iter.ReadInt(&command_type)) { 296 if (!read_iter.ReadInt(&command_type)) {
352 LOG(ERROR) << "Unable to read command from Zygote"; 297 LOG(ERROR) << "Unable to read command from Zygote";
353 return false; 298 return false;
354 } 299 }
355 return HonorRequestAndReply(zygote_ipc_fd, command_type, fds, system_info, 300 return HonorRequestAndReply(
356 &read_iter); 301 zygote_ipc_fd, command_type, fds, system_info, nacl_sandbox, &read_iter);
357 } 302 }
358 303
359 static const char kNaClHelperReservedAtZero[] = "reserved_at_zero"; 304 static const char kNaClHelperReservedAtZero[] = "reserved_at_zero";
360 static const char kNaClHelperRDebug[] = "r_debug"; 305 static const char kNaClHelperRDebug[] = "r_debug";
361 306
362 // Since we were started by nacl_helper_bootstrap rather than in the 307 // Since we were started by nacl_helper_bootstrap rather than in the
363 // usual way, the debugger cannot figure out where our executable 308 // usual way, the debugger cannot figure out where our executable
364 // or the dynamic linker or the shared libraries are in memory, 309 // or the dynamic linker or the shared libraries are in memory,
365 // so it won't find any symbols. But we can fake it out to find us. 310 // so it won't find any symbols. But we can fake it out to find us.
366 // 311 //
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 // NSS is needed to perform hashing for validation caching. 408 // NSS is needed to perform hashing for validation caching.
464 crypto::LoadNSSLibraries(); 409 crypto::LoadNSSLibraries();
465 #endif 410 #endif
466 const NaClLoaderSystemInfo system_info = { 411 const NaClLoaderSystemInfo system_info = {
467 CheckReservedAtZero(), 412 CheckReservedAtZero(),
468 sysconf(_SC_NPROCESSORS_ONLN) 413 sysconf(_SC_NPROCESSORS_ONLN)
469 }; 414 };
470 415
471 CheckRDebug(argv[0]); 416 CheckRDebug(argv[0]);
472 417
418 scoped_ptr<nacl::NaClSandbox> nacl_sandbox(new nacl::NaClSandbox);
473 // Make sure that the early initialization did not start any spurious 419 // Make sure that the early initialization did not start any spurious
474 // threads. 420 // threads.
475 #if !defined(THREAD_SANITIZER) 421 #if !defined(THREAD_SANITIZER)
476 CHECK(sandbox::ThreadHelpers::IsSingleThreaded(-1)); 422 CHECK(nacl_sandbox->IsSingleThreaded());
477 #endif 423 #endif
478 424
479 InitializeLayerOneSandbox(); 425 const bool is_init_process = 1 == getpid();
426 nacl_sandbox->InitializeLayerOneSandbox();
427 CHECK_EQ(is_init_process, nacl_sandbox->layer_one_enabled());
480 428
481 const std::vector<int> empty; 429 const std::vector<int> empty;
482 // Send the zygote a message to let it know we are ready to help 430 // Send the zygote a message to let it know we are ready to help
483 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor, 431 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor,
484 kNaClHelperStartupAck, 432 kNaClHelperStartupAck,
485 sizeof(kNaClHelperStartupAck), empty)) { 433 sizeof(kNaClHelperStartupAck), empty)) {
486 LOG(ERROR) << "*** send() to zygote failed"; 434 LOG(ERROR) << "*** send() to zygote failed";
487 } 435 }
488 436
489 // Now handle requests from the Zygote. 437 // Now handle requests from the Zygote.
490 while (true) { 438 while (true) {
491 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, 439 bool request_handled = HandleZygoteRequest(
492 system_info); 440 kNaClZygoteDescriptor, system_info, nacl_sandbox.get());
493 // Do not turn this into a CHECK() without thinking about robustness 441 // Do not turn this into a CHECK() without thinking about robustness
494 // against malicious IPC requests. 442 // against malicious IPC requests.
495 DCHECK(request_handled); 443 DCHECK(request_handled);
496 } 444 }
497 NOTREACHED(); 445 NOTREACHED();
498 } 446 }
OLDNEW
« no previous file with comments | « components/nacl/loader/OWNERS ('k') | components/nacl/loader/nacl_sandbox_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698