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 |