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

Side by Side Diff: components/nacl/zygote/nacl_fork_delegate_linux.cc

Issue 279693002: Split NaCl SFI and non-SFI helpers into separate processes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix preprocessor logic (|| -> &&) and tweak a little bit 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/zygote/nacl_fork_delegate_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/zygote/nacl_fork_delegate_linux.h" 5 #include "components/nacl/zygote/nacl_fork_delegate_linux.h"
6 6
7 #include <signal.h> 7 #include <signal.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/resource.h> 9 #include <sys/resource.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
11 11
12 #include <set> 12 #include <set>
13 13
14 #include "base/basictypes.h" 14 #include "base/basictypes.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/cpu.h" 16 #include "base/cpu.h"
17 #include "base/files/file_path.h" 17 #include "base/files/file_path.h"
18 #include "base/files/scoped_file.h" 18 #include "base/files/scoped_file.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/scoped_vector.h" 21 #include "base/memory/scoped_vector.h"
22 #include "base/path_service.h" 22 #include "base/path_service.h"
23 #include "base/pickle.h" 23 #include "base/pickle.h"
24 #include "base/posix/eintr_wrapper.h" 24 #include "base/posix/eintr_wrapper.h"
25 #include "base/posix/global_descriptors.h" 25 #include "base/posix/global_descriptors.h"
26 #include "base/posix/unix_domain_socket_linux.h" 26 #include "base/posix/unix_domain_socket_linux.h"
27 #include "base/process/kill.h" 27 #include "base/process/kill.h"
28 #include "base/process/launch.h" 28 #include "base/process/launch.h"
29 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 29 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
30 #include "build/build_config.h"
30 #include "components/nacl/common/nacl_paths.h" 31 #include "components/nacl/common/nacl_paths.h"
31 #include "components/nacl/common/nacl_switches.h" 32 #include "components/nacl/common/nacl_switches.h"
32 #include "components/nacl/loader/nacl_helper_linux.h" 33 #include "components/nacl/loader/nacl_helper_linux.h"
33 #include "content/public/common/content_descriptors.h" 34 #include "content/public/common/content_descriptors.h"
34 #include "content/public/common/content_switches.h" 35 #include "content/public/common/content_switches.h"
35 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" 36 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
36 37
37 namespace { 38 namespace {
38 39
39 // Note these need to match up with their counterparts in nacl_helper_linux.c 40 // Note these need to match up with their counterparts in nacl_helper_linux.c
40 // and nacl_helper_bootstrap_linux.c. 41 // and nacl_helper_bootstrap_linux.c.
41 const char kNaClHelperReservedAtZero[] = 42 const char kNaClHelperReservedAtZero[] =
42 "--reserved_at_zero=0xXXXXXXXXXXXXXXXX"; 43 "--reserved_at_zero=0xXXXXXXXXXXXXXXXX";
43 const char kNaClHelperRDebug[] = "--r_debug=0xXXXXXXXXXXXXXXXX"; 44 const char kNaClHelperRDebug[] = "--r_debug=0xXXXXXXXXXXXXXXXX";
44 45
46 bool NonSFIModeIsEnabled() {
47 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
48 const bool kEnabledByDefault = true;
49 #else
50 const bool kEnabledByDefault = false;
51 #endif
52
53 return kEnabledByDefault ||
54 CommandLine::ForCurrentProcess()->HasSwitch(
55 switches::kEnableNaClNonSfiMode);
mdempsky 2014/05/10 03:01:50 Argh, this switch isn't passed down to the zygote
mdempsky 2014/05/12 22:38:31 Done.
56 }
57
45 #if defined(ARCH_CPU_X86) 58 #if defined(ARCH_CPU_X86)
46 bool NonZeroSegmentBaseIsSlow() { 59 bool NonZeroSegmentBaseIsSlow() {
47 base::CPU cpuid; 60 base::CPU cpuid;
48 // Using a non-zero segment base is known to be very slow on Intel 61 // Using a non-zero segment base is known to be very slow on Intel
49 // Atom CPUs. See "Segmentation-based Memory Protection Mechanism 62 // Atom CPUs. See "Segmentation-based Memory Protection Mechanism
50 // on Intel Atom Microarchitecture: Coding Optimizations" (Leonardo 63 // on Intel Atom Microarchitecture: Coding Optimizations" (Leonardo
51 // Potenza, Intel). 64 // Potenza, Intel).
52 // 65 //
53 // The following list of CPU model numbers is taken from: 66 // The following list of CPU model numbers is taken from:
54 // "Intel 64 and IA-32 Architectures Software Developer's Manual" 67 // "Intel 64 and IA-32 Architectures Software Developer's Manual"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 if (msg_len <= 0) { 114 if (msg_len <= 0) {
102 LOG(ERROR) << "SendIPCRequestAndReadReply: RecvMsg failed"; 115 LOG(ERROR) << "SendIPCRequestAndReadReply: RecvMsg failed";
103 return false; 116 return false;
104 } 117 }
105 *reply_size = msg_len; 118 *reply_size = msg_len;
106 return true; 119 return true;
107 } 120 }
108 121
109 } // namespace. 122 } // namespace.
110 123
111 NaClForkDelegate::NaClForkDelegate() 124 namespace nacl {
112 : status_(kNaClHelperUnused), 125
113 fd_(-1) {} 126 void AddNaClZygoteForkDelegates(
127 ScopedVector<content::ZygoteForkDelegate>* delegates) {
128 delegates->push_back(new NaClForkDelegate(false /* nonsfi_mode */));
129 delegates->push_back(new NaClForkDelegate(true /* nonsfi_mode */));
130 }
131
132 NaClForkDelegate::NaClForkDelegate(bool nonsfi_mode)
133 : nonsfi_mode_(nonsfi_mode), status_(kNaClHelperUnused), fd_(-1) {
134 }
114 135
115 void NaClForkDelegate::Init(const int sandboxdesc, 136 void NaClForkDelegate::Init(const int sandboxdesc,
116 const bool enable_layer1_sandbox) { 137 const bool enable_layer1_sandbox) {
117 VLOG(1) << "NaClForkDelegate::Init()"; 138 VLOG(1) << "NaClForkDelegate::Init()";
118 int fds[2]; 139
140 // Only launch the non-SFI helper process if non-SFI mode is enabled.
141 if (nonsfi_mode_ && !NonSFIModeIsEnabled()) {
142 return;
143 }
119 144
120 scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client( 145 scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client(
121 sandbox::SetuidSandboxClient::Create()); 146 sandbox::SetuidSandboxClient::Create());
122 147
123 // For communications between the NaCl loader process and 148 // For communications between the NaCl loader process and
124 // the SUID sandbox. 149 // the SUID sandbox.
125 int nacl_sandbox_descriptor = 150 int nacl_sandbox_descriptor =
126 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; 151 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel;
127 // Confirm a hard-wired assumption. 152 // Confirm a hard-wired assumption.
128 DCHECK_EQ(sandboxdesc, nacl_sandbox_descriptor); 153 DCHECK_EQ(sandboxdesc, nacl_sandbox_descriptor);
129 154
130 CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); 155 int fds[2];
156 PCHECK(0 == socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds));
131 base::FileHandleMappingVector fds_to_map; 157 base::FileHandleMappingVector fds_to_map;
132 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor)); 158 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
133 fds_to_map.push_back(std::make_pair(sandboxdesc, nacl_sandbox_descriptor)); 159 fds_to_map.push_back(std::make_pair(sandboxdesc, nacl_sandbox_descriptor));
134 160
135 // Using nacl_helper_bootstrap is not necessary on x86-64 because 161 // Using nacl_helper_bootstrap is not necessary on x86-64 because
136 // NaCl's x86-64 sandbox is not zero-address-based. Starting 162 // NaCl's x86-64 sandbox is not zero-address-based. Starting
137 // nacl_helper through nacl_helper_bootstrap works on x86-64, but it 163 // nacl_helper through nacl_helper_bootstrap works on x86-64, but it
138 // leaves nacl_helper_bootstrap mapped at a fixed address at the 164 // leaves nacl_helper_bootstrap mapped at a fixed address at the
139 // bottom of the address space, which is undesirable because it 165 // bottom of the address space, which is undesirable because it
140 // effectively defeats ASLR. 166 // effectively defeats ASLR.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper 281 // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper
256 // becomes the default. 282 // becomes the default.
257 fd_ = -1; 283 fd_ = -1;
258 if (IGNORE_EINTR(close(fds[0])) != 0) 284 if (IGNORE_EINTR(close(fds[0])) != 0)
259 LOG(ERROR) << "close(fds[0]) failed"; 285 LOG(ERROR) << "close(fds[0]) failed";
260 } 286 }
261 287
262 void NaClForkDelegate::InitialUMA(std::string* uma_name, 288 void NaClForkDelegate::InitialUMA(std::string* uma_name,
263 int* uma_sample, 289 int* uma_sample,
264 int* uma_boundary_value) { 290 int* uma_boundary_value) {
265 *uma_name = "NaCl.Client.Helper.InitState"; 291 *uma_name = nonsfi_mode_ ? "NaCl.Client.HelperNonSFI.InitState"
292 : "NaCl.Client.Helper.InitState";
266 *uma_sample = status_; 293 *uma_sample = status_;
267 *uma_boundary_value = kNaClHelperStatusBoundary; 294 *uma_boundary_value = kNaClHelperStatusBoundary;
268 } 295 }
269 296
270 NaClForkDelegate::~NaClForkDelegate() { 297 NaClForkDelegate::~NaClForkDelegate() {
271 // side effect of close: delegate process will terminate 298 // side effect of close: delegate process will terminate
272 if (status_ == kNaClHelperSuccess) { 299 if (status_ == kNaClHelperSuccess) {
273 if (IGNORE_EINTR(close(fd_)) != 0) 300 if (IGNORE_EINTR(close(fd_)) != 0)
274 LOG(ERROR) << "close(fd_) failed"; 301 LOG(ERROR) << "close(fd_) failed";
275 } 302 }
276 } 303 }
277 304
278 bool NaClForkDelegate::CanHelp(const std::string& process_type, 305 bool NaClForkDelegate::CanHelp(const std::string& process_type,
279 std::string* uma_name, 306 std::string* uma_name,
280 int* uma_sample, 307 int* uma_sample,
281 int* uma_boundary_value) { 308 int* uma_boundary_value) {
282 if (process_type != switches::kNaClLoaderProcess && 309 // We can only help with a specific process type depending on nonsfi_mode_.
283 process_type != switches::kNaClLoaderNonSfiProcess) 310 const char* helpable_process_type = nonsfi_mode_
311 ? switches::kNaClLoaderNonSfiProcess
312 : switches::kNaClLoaderProcess;
313 if (process_type != helpable_process_type)
284 return false; 314 return false;
285 *uma_name = "NaCl.Client.Helper.StateOnFork"; 315 *uma_name = nonsfi_mode_ ? "NaCl.Client.HelperNonSFI.StateOnFork"
316 : "NaCl.Client.Helper.StateOnFork";
286 *uma_sample = status_; 317 *uma_sample = status_;
287 *uma_boundary_value = kNaClHelperStatusBoundary; 318 *uma_boundary_value = kNaClHelperStatusBoundary;
288 return true; 319 return true;
289 } 320 }
290 321
291 pid_t NaClForkDelegate::Fork(const std::string& process_type, 322 pid_t NaClForkDelegate::Fork(const std::string& process_type,
292 const std::vector<int>& fds, 323 const std::vector<int>& fds,
293 const std::string& channel_id) { 324 const std::string& channel_id) {
294 VLOG(1) << "NaClForkDelegate::Fork"; 325 VLOG(1) << "NaClForkDelegate::Fork";
295 326
296 DCHECK(fds.size() == kNumPassedFDs); 327 DCHECK(fds.size() == kNumPassedFDs);
297 328
298 if (status_ != kNaClHelperSuccess) { 329 if (status_ != kNaClHelperSuccess) {
299 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start"; 330 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start";
300 return -1; 331 return -1;
301 } 332 }
302 333
303 // First, send a remote fork request. 334 // First, send a remote fork request.
304 Pickle write_pickle; 335 Pickle write_pickle;
305 write_pickle.WriteInt(nacl::kNaClForkRequest); 336 write_pickle.WriteInt(nacl::kNaClForkRequest);
306 // TODO(hamaji): When we split the helper binary for non-SFI mode 337 // TODO(hamaji): When we split the helper binary for non-SFI mode
307 // from nacl_helper, stop sending this information. 338 // from nacl_helper, stop sending this information.
308 const bool uses_nonsfi_mode = 339 write_pickle.WriteBool(nonsfi_mode_);
309 process_type == switches::kNaClLoaderNonSfiProcess;
310 write_pickle.WriteBool(uses_nonsfi_mode);
311 write_pickle.WriteString(channel_id); 340 write_pickle.WriteString(channel_id);
312 341
313 char reply_buf[kNaClMaxIPCMessageLength]; 342 char reply_buf[kNaClMaxIPCMessageLength];
314 ssize_t reply_size = 0; 343 ssize_t reply_size = 0;
315 bool got_reply = 344 bool got_reply =
316 SendIPCRequestAndReadReply(fd_, fds, write_pickle, 345 SendIPCRequestAndReadReply(fd_, fds, write_pickle,
317 reply_buf, sizeof(reply_buf), &reply_size); 346 reply_buf, sizeof(reply_buf), &reply_size);
318 if (!got_reply) { 347 if (!got_reply) {
319 LOG(ERROR) << "Could not perform remote fork."; 348 LOG(ERROR) << "Could not perform remote fork.";
320 return -1; 349 return -1;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 int remote_exit_code; 397 int remote_exit_code;
369 if (!iter.ReadInt(&remote_exit_code)) { 398 if (!iter.ReadInt(&remote_exit_code)) {
370 LOG(ERROR) << "GetTerminationStatus: pickle failed"; 399 LOG(ERROR) << "GetTerminationStatus: pickle failed";
371 return false; 400 return false;
372 } 401 }
373 402
374 *status = static_cast<base::TerminationStatus>(termination_status); 403 *status = static_cast<base::TerminationStatus>(termination_status);
375 *exit_code = remote_exit_code; 404 *exit_code = remote_exit_code;
376 return true; 405 return true;
377 } 406 }
407
408 } // namespace nacl
OLDNEW
« no previous file with comments | « components/nacl/zygote/nacl_fork_delegate_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698