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

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: Respond to mseaborn feedback 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"
31 #include "components/nacl/common/nacl_nonsfi_util.h"
30 #include "components/nacl/common/nacl_paths.h" 32 #include "components/nacl/common/nacl_paths.h"
31 #include "components/nacl/common/nacl_switches.h" 33 #include "components/nacl/common/nacl_switches.h"
32 #include "components/nacl/loader/nacl_helper_linux.h" 34 #include "components/nacl/loader/nacl_helper_linux.h"
33 #include "content/public/common/content_descriptors.h" 35 #include "content/public/common/content_descriptors.h"
34 #include "content/public/common/content_switches.h" 36 #include "content/public/common/content_switches.h"
35 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" 37 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
36 38
37 namespace { 39 namespace {
38 40
39 // Note these need to match up with their counterparts in nacl_helper_linux.c 41 // Note these need to match up with their counterparts in nacl_helper_linux.c
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 if (msg_len <= 0) { 103 if (msg_len <= 0) {
102 LOG(ERROR) << "SendIPCRequestAndReadReply: RecvMsg failed"; 104 LOG(ERROR) << "SendIPCRequestAndReadReply: RecvMsg failed";
103 return false; 105 return false;
104 } 106 }
105 *reply_size = msg_len; 107 *reply_size = msg_len;
106 return true; 108 return true;
107 } 109 }
108 110
109 } // namespace. 111 } // namespace.
110 112
111 NaClForkDelegate::NaClForkDelegate() 113 namespace nacl {
112 : status_(kNaClHelperUnused), 114
113 fd_(-1) {} 115 void AddNaClZygoteForkDelegates(
116 ScopedVector<content::ZygoteForkDelegate>* delegates) {
117 delegates->push_back(new NaClForkDelegate(false /* nonsfi_mode */));
118 delegates->push_back(new NaClForkDelegate(true /* nonsfi_mode */));
119 }
120
121 NaClForkDelegate::NaClForkDelegate(bool nonsfi_mode)
122 : nonsfi_mode_(nonsfi_mode), status_(kNaClHelperUnused), fd_(-1) {
123 }
114 124
115 void NaClForkDelegate::Init(const int sandboxdesc, 125 void NaClForkDelegate::Init(const int sandboxdesc,
116 const bool enable_layer1_sandbox) { 126 const bool enable_layer1_sandbox) {
117 VLOG(1) << "NaClForkDelegate::Init()"; 127 VLOG(1) << "NaClForkDelegate::Init()";
118 int fds[2]; 128
129 // Only launch the non-SFI helper process if non-SFI mode is enabled.
130 if (nonsfi_mode_ && !IsNonSFIModeEnabled()) {
131 return;
132 }
119 133
120 scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client( 134 scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client(
121 sandbox::SetuidSandboxClient::Create()); 135 sandbox::SetuidSandboxClient::Create());
122 136
123 // For communications between the NaCl loader process and 137 // For communications between the NaCl loader process and
124 // the SUID sandbox. 138 // the SUID sandbox.
125 int nacl_sandbox_descriptor = 139 int nacl_sandbox_descriptor =
126 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; 140 base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel;
127 // Confirm a hard-wired assumption. 141 // Confirm a hard-wired assumption.
128 DCHECK_EQ(sandboxdesc, nacl_sandbox_descriptor); 142 DCHECK_EQ(sandboxdesc, nacl_sandbox_descriptor);
129 143
130 CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); 144 int fds[2];
145 PCHECK(0 == socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds));
131 base::FileHandleMappingVector fds_to_map; 146 base::FileHandleMappingVector fds_to_map;
132 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor)); 147 fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
133 fds_to_map.push_back(std::make_pair(sandboxdesc, nacl_sandbox_descriptor)); 148 fds_to_map.push_back(std::make_pair(sandboxdesc, nacl_sandbox_descriptor));
134 149
135 // Using nacl_helper_bootstrap is not necessary on x86-64 because 150 // Using nacl_helper_bootstrap is not necessary on x86-64 because
136 // NaCl's x86-64 sandbox is not zero-address-based. Starting 151 // NaCl's x86-64 sandbox is not zero-address-based. Starting
137 // nacl_helper through nacl_helper_bootstrap works on x86-64, but it 152 // nacl_helper through nacl_helper_bootstrap works on x86-64, but it
138 // leaves nacl_helper_bootstrap mapped at a fixed address at the 153 // leaves nacl_helper_bootstrap mapped at a fixed address at the
139 // bottom of the address space, which is undesirable because it 154 // bottom of the address space, which is undesirable because it
140 // effectively defeats ASLR. 155 // 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 270 // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper
256 // becomes the default. 271 // becomes the default.
257 fd_ = -1; 272 fd_ = -1;
258 if (IGNORE_EINTR(close(fds[0])) != 0) 273 if (IGNORE_EINTR(close(fds[0])) != 0)
259 LOG(ERROR) << "close(fds[0]) failed"; 274 LOG(ERROR) << "close(fds[0]) failed";
260 } 275 }
261 276
262 void NaClForkDelegate::InitialUMA(std::string* uma_name, 277 void NaClForkDelegate::InitialUMA(std::string* uma_name,
263 int* uma_sample, 278 int* uma_sample,
264 int* uma_boundary_value) { 279 int* uma_boundary_value) {
265 *uma_name = "NaCl.Client.Helper.InitState"; 280 *uma_name = nonsfi_mode_ ? "NaCl.Client.HelperNonSFI.InitState"
281 : "NaCl.Client.Helper.InitState";
266 *uma_sample = status_; 282 *uma_sample = status_;
267 *uma_boundary_value = kNaClHelperStatusBoundary; 283 *uma_boundary_value = kNaClHelperStatusBoundary;
268 } 284 }
269 285
270 NaClForkDelegate::~NaClForkDelegate() { 286 NaClForkDelegate::~NaClForkDelegate() {
271 // side effect of close: delegate process will terminate 287 // side effect of close: delegate process will terminate
272 if (status_ == kNaClHelperSuccess) { 288 if (status_ == kNaClHelperSuccess) {
273 if (IGNORE_EINTR(close(fd_)) != 0) 289 if (IGNORE_EINTR(close(fd_)) != 0)
274 LOG(ERROR) << "close(fd_) failed"; 290 LOG(ERROR) << "close(fd_) failed";
275 } 291 }
276 } 292 }
277 293
278 bool NaClForkDelegate::CanHelp(const std::string& process_type, 294 bool NaClForkDelegate::CanHelp(const std::string& process_type,
279 std::string* uma_name, 295 std::string* uma_name,
280 int* uma_sample, 296 int* uma_sample,
281 int* uma_boundary_value) { 297 int* uma_boundary_value) {
282 if (process_type != switches::kNaClLoaderProcess && 298 // We can only help with a specific process type depending on nonsfi_mode_.
283 process_type != switches::kNaClLoaderNonSfiProcess) 299 const char* helpable_process_type = nonsfi_mode_
300 ? switches::kNaClLoaderNonSfiProcess
301 : switches::kNaClLoaderProcess;
302 if (process_type != helpable_process_type)
284 return false; 303 return false;
285 *uma_name = "NaCl.Client.Helper.StateOnFork"; 304 *uma_name = nonsfi_mode_ ? "NaCl.Client.HelperNonSFI.StateOnFork"
305 : "NaCl.Client.Helper.StateOnFork";
286 *uma_sample = status_; 306 *uma_sample = status_;
287 *uma_boundary_value = kNaClHelperStatusBoundary; 307 *uma_boundary_value = kNaClHelperStatusBoundary;
288 return true; 308 return true;
289 } 309 }
290 310
291 pid_t NaClForkDelegate::Fork(const std::string& process_type, 311 pid_t NaClForkDelegate::Fork(const std::string& process_type,
292 const std::vector<int>& fds, 312 const std::vector<int>& fds,
293 const std::string& channel_id) { 313 const std::string& channel_id) {
294 VLOG(1) << "NaClForkDelegate::Fork"; 314 VLOG(1) << "NaClForkDelegate::Fork";
295 315
296 DCHECK(fds.size() == kNumPassedFDs); 316 DCHECK(fds.size() == kNumPassedFDs);
297 317
298 if (status_ != kNaClHelperSuccess) { 318 if (status_ != kNaClHelperSuccess) {
299 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start"; 319 LOG(ERROR) << "Cannot launch NaCl process: nacl_helper failed to start";
300 return -1; 320 return -1;
301 } 321 }
302 322
303 // First, send a remote fork request. 323 // First, send a remote fork request.
304 Pickle write_pickle; 324 Pickle write_pickle;
305 write_pickle.WriteInt(nacl::kNaClForkRequest); 325 write_pickle.WriteInt(nacl::kNaClForkRequest);
306 // TODO(hamaji): When we split the helper binary for non-SFI mode 326 // TODO(hamaji): When we split the helper binary for non-SFI mode
307 // from nacl_helper, stop sending this information. 327 // from nacl_helper, stop sending this information.
308 const bool uses_nonsfi_mode = 328 write_pickle.WriteBool(nonsfi_mode_);
309 process_type == switches::kNaClLoaderNonSfiProcess;
310 write_pickle.WriteBool(uses_nonsfi_mode);
311 write_pickle.WriteString(channel_id); 329 write_pickle.WriteString(channel_id);
312 330
313 char reply_buf[kNaClMaxIPCMessageLength]; 331 char reply_buf[kNaClMaxIPCMessageLength];
314 ssize_t reply_size = 0; 332 ssize_t reply_size = 0;
315 bool got_reply = 333 bool got_reply =
316 SendIPCRequestAndReadReply(fd_, fds, write_pickle, 334 SendIPCRequestAndReadReply(fd_, fds, write_pickle,
317 reply_buf, sizeof(reply_buf), &reply_size); 335 reply_buf, sizeof(reply_buf), &reply_size);
318 if (!got_reply) { 336 if (!got_reply) {
319 LOG(ERROR) << "Could not perform remote fork."; 337 LOG(ERROR) << "Could not perform remote fork.";
320 return -1; 338 return -1;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 int remote_exit_code; 386 int remote_exit_code;
369 if (!iter.ReadInt(&remote_exit_code)) { 387 if (!iter.ReadInt(&remote_exit_code)) {
370 LOG(ERROR) << "GetTerminationStatus: pickle failed"; 388 LOG(ERROR) << "GetTerminationStatus: pickle failed";
371 return false; 389 return false;
372 } 390 }
373 391
374 *status = static_cast<base::TerminationStatus>(termination_status); 392 *status = static_cast<base::TerminationStatus>(termination_status);
375 *exit_code = remote_exit_code; 393 *exit_code = remote_exit_code;
376 return true; 394 return true;
377 } 395 }
396
397 } // 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