| 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 nacl::NaClSandbox* nacl_sandbox, | 151 nacl::NaClSandbox* nacl_sandbox, |
| 152 const std::string& channel_id) { | 152 const std::string& channel_id) { |
| 153 DCHECK(child_fds.size() > | 153 DCHECK(child_fds.size() > |
| 154 std::max(content::ZygoteForkDelegate::kPIDOracleFDIndex, | 154 std::max(content::ZygoteForkDelegate::kPIDOracleFDIndex, |
| 155 content::ZygoteForkDelegate::kBrowserFDIndex)); | 155 content::ZygoteForkDelegate::kBrowserFDIndex)); |
| 156 | 156 |
| 157 // Ping the PID oracle socket. | 157 // Ping the PID oracle socket. |
| 158 CHECK(content::SendZygoteChildPing( | 158 CHECK(content::SendZygoteChildPing( |
| 159 child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex]->get())); | 159 child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex]->get())); |
| 160 | 160 |
| 161 CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 161 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 162 switches::kProcessChannelID, channel_id); | 162 switches::kProcessChannelID, channel_id); |
| 163 | 163 |
| 164 // Save the browser socket and close the rest. | 164 // Save the browser socket and close the rest. |
| 165 base::ScopedFD browser_fd( | 165 base::ScopedFD browser_fd( |
| 166 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]->Pass()); | 166 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]->Pass()); |
| 167 child_fds.clear(); | 167 child_fds.clear(); |
| 168 | 168 |
| 169 BecomeNaClLoader( | 169 BecomeNaClLoader( |
| 170 browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox); | 170 browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox); |
| 171 _exit(1); | 171 _exit(1); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 // after initialization. The parts that really matter to the | 355 // after initialization. The parts that really matter to the |
| 356 // debugger never change. So we just copy the contents of the | 356 // debugger never change. So we just copy the contents of the |
| 357 // dynamic linker's structure into the address provided by the option. | 357 // dynamic linker's structure into the address provided by the option. |
| 358 // Hereafter, if someone attaches a debugger (or examines a core dump), | 358 // Hereafter, if someone attaches a debugger (or examines a core dump), |
| 359 // the debugger will find all the symbols in the normal way. | 359 // the debugger will find all the symbols in the normal way. |
| 360 // | 360 // |
| 361 // Non-SFI mode does not use nacl_helper_bootstrap, so it doesn't need to | 361 // Non-SFI mode does not use nacl_helper_bootstrap, so it doesn't need to |
| 362 // process the --r_debug option. | 362 // process the --r_debug option. |
| 363 static void CheckRDebug(char* argv0) { | 363 static void CheckRDebug(char* argv0) { |
| 364 std::string r_debug_switch_value = | 364 std::string r_debug_switch_value = |
| 365 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kNaClHelperRDebug); | 365 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 366 kNaClHelperRDebug); |
| 366 if (!r_debug_switch_value.empty()) { | 367 if (!r_debug_switch_value.empty()) { |
| 367 char* endp; | 368 char* endp; |
| 368 uintptr_t r_debug_addr = strtoul(r_debug_switch_value.c_str(), &endp, 0); | 369 uintptr_t r_debug_addr = strtoul(r_debug_switch_value.c_str(), &endp, 0); |
| 369 if (r_debug_addr != 0 && *endp == '\0') { | 370 if (r_debug_addr != 0 && *endp == '\0') { |
| 370 r_debug* bootstrap_r_debug = reinterpret_cast<r_debug*>(r_debug_addr); | 371 r_debug* bootstrap_r_debug = reinterpret_cast<r_debug*>(r_debug_addr); |
| 371 *bootstrap_r_debug = _r_debug; | 372 *bootstrap_r_debug = _r_debug; |
| 372 | 373 |
| 373 // Since the main executable (the bootstrap program) does not | 374 // Since the main executable (the bootstrap program) does not |
| 374 // have a dynamic section, the debugger will not skip the | 375 // have a dynamic section, the debugger will not skip the |
| 375 // first element of the link_map list as it usually would for | 376 // first element of the link_map list as it usually would for |
| (...skipping 11 matching lines...) Expand all Loading... |
| 387 | 388 |
| 388 // The zygote passes --reserved_at_zero=0xXXXXXXXXXXXXXXXX. | 389 // The zygote passes --reserved_at_zero=0xXXXXXXXXXXXXXXXX. |
| 389 // nacl_helper_bootstrap replaces the Xs with the amount of prereserved | 390 // nacl_helper_bootstrap replaces the Xs with the amount of prereserved |
| 390 // sandbox memory. | 391 // sandbox memory. |
| 391 // | 392 // |
| 392 // CheckReservedAtZero parses the value of the argument reserved_at_zero | 393 // CheckReservedAtZero parses the value of the argument reserved_at_zero |
| 393 // and returns the amount of prereserved sandbox memory. | 394 // and returns the amount of prereserved sandbox memory. |
| 394 static size_t CheckReservedAtZero() { | 395 static size_t CheckReservedAtZero() { |
| 395 size_t prereserved_sandbox_size = 0; | 396 size_t prereserved_sandbox_size = 0; |
| 396 std::string reserved_at_zero_switch_value = | 397 std::string reserved_at_zero_switch_value = |
| 397 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 398 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 398 kNaClHelperReservedAtZero); | 399 kNaClHelperReservedAtZero); |
| 399 if (!reserved_at_zero_switch_value.empty()) { | 400 if (!reserved_at_zero_switch_value.empty()) { |
| 400 char* endp; | 401 char* endp; |
| 401 prereserved_sandbox_size = | 402 prereserved_sandbox_size = |
| 402 strtoul(reserved_at_zero_switch_value.c_str(), &endp, 0); | 403 strtoul(reserved_at_zero_switch_value.c_str(), &endp, 0); |
| 403 if (*endp != '\0') | 404 if (*endp != '\0') |
| 404 LOG(ERROR) << "Could not parse reserved_at_zero argument value of " | 405 LOG(ERROR) << "Could not parse reserved_at_zero argument value of " |
| 405 << reserved_at_zero_switch_value; | 406 << reserved_at_zero_switch_value; |
| 406 } | 407 } |
| 407 return prereserved_sandbox_size; | 408 return prereserved_sandbox_size; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 423 // The function isn't referenced from the executable itself. Make sure it isn't | 424 // The function isn't referenced from the executable itself. Make sure it isn't |
| 424 // stripped by the linker. | 425 // stripped by the linker. |
| 425 __attribute__((used)) | 426 __attribute__((used)) |
| 426 __attribute__((visibility("default"))) | 427 __attribute__((visibility("default"))) |
| 427 const char* __asan_default_options() { | 428 const char* __asan_default_options() { |
| 428 return kAsanDefaultOptionsNaCl; | 429 return kAsanDefaultOptionsNaCl; |
| 429 } | 430 } |
| 430 #endif | 431 #endif |
| 431 | 432 |
| 432 int main(int argc, char* argv[]) { | 433 int main(int argc, char* argv[]) { |
| 433 CommandLine::Init(argc, argv); | 434 base::CommandLine::Init(argc, argv); |
| 434 base::AtExitManager exit_manager; | 435 base::AtExitManager exit_manager; |
| 435 base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised | 436 base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised |
| 436 | 437 |
| 437 #if !defined(OS_NACL_NONSFI) | 438 #if !defined(OS_NACL_NONSFI) |
| 438 // NSS is only needed for SFI NaCl. | 439 // NSS is only needed for SFI NaCl. |
| 439 // Allows NSS to fopen() /dev/urandom. | 440 // Allows NSS to fopen() /dev/urandom. |
| 440 sandbox::InitLibcUrandomOverrides(); | 441 sandbox::InitLibcUrandomOverrides(); |
| 441 #if defined(USE_NSS) | 442 #if defined(USE_NSS) |
| 442 // Configure NSS for use inside the NaCl process. | 443 // Configure NSS for use inside the NaCl process. |
| 443 // The fork check has not caused problems for NaCl, but this appears to be | 444 // The fork check has not caused problems for NaCl, but this appears to be |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 // Now handle requests from the Zygote. | 493 // Now handle requests from the Zygote. |
| 493 while (true) { | 494 while (true) { |
| 494 bool request_handled = HandleZygoteRequest( | 495 bool request_handled = HandleZygoteRequest( |
| 495 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); | 496 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); |
| 496 // Do not turn this into a CHECK() without thinking about robustness | 497 // Do not turn this into a CHECK() without thinking about robustness |
| 497 // against malicious IPC requests. | 498 // against malicious IPC requests. |
| 498 DCHECK(request_handled); | 499 DCHECK(request_handled); |
| 499 } | 500 } |
| 500 NOTREACHED(); | 501 NOTREACHED(); |
| 501 } | 502 } |
| OLD | NEW |