| OLD | NEW |
| 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/strings/string_split.h" |
| 29 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 30 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 30 #include "build/build_config.h" | 31 #include "build/build_config.h" |
| 31 #include "components/nacl/common/nacl_nonsfi_util.h" | 32 #include "components/nacl/common/nacl_nonsfi_util.h" |
| 32 #include "components/nacl/common/nacl_paths.h" | 33 #include "components/nacl/common/nacl_paths.h" |
| 33 #include "components/nacl/common/nacl_switches.h" | 34 #include "components/nacl/common/nacl_switches.h" |
| 34 #include "components/nacl/loader/nacl_helper_linux.h" | 35 #include "components/nacl/loader/nacl_helper_linux.h" |
| 35 #include "content/public/common/content_descriptors.h" | 36 #include "content/public/common/content_descriptors.h" |
| 36 #include "content/public/common/content_switches.h" | 37 #include "content/public/common/content_switches.h" |
| 37 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" | 38 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" |
| 38 | 39 |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 // Note these need to match up with their counterparts in nacl_helper_linux.c | 42 // Note these need to match up with their counterparts in nacl_helper_linux.c |
| 42 // and nacl_helper_bootstrap_linux.c. | 43 // and nacl_helper_bootstrap_linux.c. |
| 43 const char kNaClHelperReservedAtZero[] = | 44 const char kNaClHelperReservedAtZero[] = |
| 44 "--reserved_at_zero=0xXXXXXXXXXXXXXXXX"; | 45 "--reserved_at_zero=0xXXXXXXXXXXXXXXXX"; |
| 45 const char kNaClHelperRDebug[] = "--r_debug=0xXXXXXXXXXXXXXXXX"; | 46 const char kNaClHelperRDebug[] = "--r_debug=0xXXXXXXXXXXXXXXXX"; |
| 46 | 47 |
| 48 // This is an environment variable which controls which (if any) other |
| 49 // environment variables are passed through to NaCl processes. e.g., |
| 50 // NACL_ENV_PASSTHROUGH="PATH,CWD" would pass both $PATH and $CWD to the child |
| 51 // process. |
| 52 const char kNaClEnvPassthrough[] = "NACL_ENV_PASSTHROUGH"; |
| 53 char kNaClEnvPassthroughDelimiter = ','; |
| 54 |
| 55 // The following environment variables are always passed through if they exist |
| 56 // in the parent process. |
| 57 const char kNaClExeStderr[] = "NACL_EXE_STDERR"; |
| 58 const char kNaClExeStdout[] = "NACL_EXE_STDOUT"; |
| 59 const char kNaClVerbosity[] = "NACLVERBOSITY"; |
| 60 |
| 47 #if defined(ARCH_CPU_X86) | 61 #if defined(ARCH_CPU_X86) |
| 48 bool NonZeroSegmentBaseIsSlow() { | 62 bool NonZeroSegmentBaseIsSlow() { |
| 49 base::CPU cpuid; | 63 base::CPU cpuid; |
| 50 // Using a non-zero segment base is known to be very slow on Intel | 64 // Using a non-zero segment base is known to be very slow on Intel |
| 51 // Atom CPUs. See "Segmentation-based Memory Protection Mechanism | 65 // Atom CPUs. See "Segmentation-based Memory Protection Mechanism |
| 52 // on Intel Atom Microarchitecture: Coding Optimizations" (Leonardo | 66 // on Intel Atom Microarchitecture: Coding Optimizations" (Leonardo |
| 53 // Potenza, Intel). | 67 // Potenza, Intel). |
| 54 // | 68 // |
| 55 // The following list of CPU model numbers is taken from: | 69 // The following list of CPU model numbers is taken from: |
| 56 // "Intel 64 and IA-32 Architectures Software Developer's Manual" | 70 // "Intel 64 and IA-32 Architectures Software Developer's Manual" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 // The NaCl processes spawned may need to exceed the ambient soft limit | 250 // The NaCl processes spawned may need to exceed the ambient soft limit |
| 237 // on RLIMIT_AS to allocate the untrusted address space and its guard | 251 // on RLIMIT_AS to allocate the untrusted address space and its guard |
| 238 // regions. The nacl_helper itself cannot just raise its own limit, | 252 // regions. The nacl_helper itself cannot just raise its own limit, |
| 239 // because the existing limit may prevent the initial exec of | 253 // because the existing limit may prevent the initial exec of |
| 240 // nacl_helper_bootstrap from succeeding, with its large address space | 254 // nacl_helper_bootstrap from succeeding, with its large address space |
| 241 // reservation. | 255 // reservation. |
| 242 std::vector<int> max_these_limits; | 256 std::vector<int> max_these_limits; |
| 243 max_these_limits.push_back(RLIMIT_AS); | 257 max_these_limits.push_back(RLIMIT_AS); |
| 244 options.maximize_rlimits = &max_these_limits; | 258 options.maximize_rlimits = &max_these_limits; |
| 245 | 259 |
| 260 // To avoid information leaks in Non-SFI mode, clear the environment for |
| 261 // the NaCl Helper process. |
| 262 options.clear_environ = true; |
| 263 AddPassthroughEnvToOptions(&options); |
| 264 |
| 246 if (!base::LaunchProcess(argv_to_launch, options, NULL)) | 265 if (!base::LaunchProcess(argv_to_launch, options, NULL)) |
| 247 status_ = kNaClHelperLaunchFailed; | 266 status_ = kNaClHelperLaunchFailed; |
| 248 // parent and error cases are handled below | 267 // parent and error cases are handled below |
| 249 | 268 |
| 250 if (enable_layer1_sandbox) { | 269 if (enable_layer1_sandbox) { |
| 251 // Sanity check that dummy_fd was kept alive for LaunchProcess. | 270 // Sanity check that dummy_fd was kept alive for LaunchProcess. |
| 252 DCHECK(dummy_fd.is_valid()); | 271 DCHECK(dummy_fd.is_valid()); |
| 253 } | 272 } |
| 254 } | 273 } |
| 255 if (IGNORE_EINTR(close(fds[1])) != 0) | 274 if (IGNORE_EINTR(close(fds[1])) != 0) |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 if (!iter.ReadInt(&remote_exit_code)) { | 410 if (!iter.ReadInt(&remote_exit_code)) { |
| 392 LOG(ERROR) << "GetTerminationStatus: pickle failed"; | 411 LOG(ERROR) << "GetTerminationStatus: pickle failed"; |
| 393 return false; | 412 return false; |
| 394 } | 413 } |
| 395 | 414 |
| 396 *status = static_cast<base::TerminationStatus>(termination_status); | 415 *status = static_cast<base::TerminationStatus>(termination_status); |
| 397 *exit_code = remote_exit_code; | 416 *exit_code = remote_exit_code; |
| 398 return true; | 417 return true; |
| 399 } | 418 } |
| 400 | 419 |
| 420 // static |
| 421 void NaClForkDelegate::AddPassthroughEnvToOptions( |
| 422 base::LaunchOptions* options) { |
| 423 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 424 std::string pass_through_string; |
| 425 std::vector<std::string> pass_through_vars; |
| 426 if (env->GetVar(kNaClEnvPassthrough, &pass_through_string)) { |
| 427 base::SplitString( |
| 428 pass_through_string, kNaClEnvPassthroughDelimiter, &pass_through_vars); |
| 429 } |
| 430 pass_through_vars.push_back(kNaClExeStderr); |
| 431 pass_through_vars.push_back(kNaClExeStdout); |
| 432 pass_through_vars.push_back(kNaClVerbosity); |
| 433 for (size_t i = 0; i < pass_through_vars.size(); ++i) { |
| 434 std::string temp; |
| 435 if (env->GetVar(pass_through_vars[i].c_str(), &temp)) |
| 436 options->environ[pass_through_vars[i]] = temp; |
| 437 } |
| 438 } |
| 439 |
| 401 } // namespace nacl | 440 } // namespace nacl |
| OLD | NEW |