| 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 "base/process/launch.h" | 5 #include "base/process/launch.h" |
| 6 | 6 |
| 7 #include <dirent.h> | 7 #include <dirent.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <sched.h> | 10 #include <sched.h> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "base/process/process.h" | 37 #include "base/process/process.h" |
| 38 #include "base/process/process_metrics.h" | 38 #include "base/process/process_metrics.h" |
| 39 #include "base/strings/stringprintf.h" | 39 #include "base/strings/stringprintf.h" |
| 40 #include "base/synchronization/waitable_event.h" | 40 #include "base/synchronization/waitable_event.h" |
| 41 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 41 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 42 #include "base/third_party/valgrind/valgrind.h" | 42 #include "base/third_party/valgrind/valgrind.h" |
| 43 #include "base/threading/platform_thread.h" | 43 #include "base/threading/platform_thread.h" |
| 44 #include "base/threading/thread_restrictions.h" | 44 #include "base/threading/thread_restrictions.h" |
| 45 #include "build/build_config.h" | 45 #include "build/build_config.h" |
| 46 | 46 |
| 47 #if defined(OS_LINUX) | 47 #if defined(OS_LINUX) || defined(OS_AIX) |
| 48 #include <sys/prctl.h> | 48 #include <sys/prctl.h> |
| 49 #endif | 49 #endif |
| 50 | 50 |
| 51 #if defined(OS_CHROMEOS) | 51 #if defined(OS_CHROMEOS) |
| 52 #include <sys/ioctl.h> | 52 #include <sys/ioctl.h> |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 #if defined(OS_FREEBSD) | 55 #if defined(OS_FREEBSD) |
| 56 #include <sys/event.h> | 56 #include <sys/event.h> |
| 57 #include <sys/ucontext.h> | 57 #include <sys/ucontext.h> |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 // but Android's pthread_sigmask() was broken until 4.1: | 106 // but Android's pthread_sigmask() was broken until 4.1: |
| 107 // https://code.google.com/p/android/issues/detail?id=15337 | 107 // https://code.google.com/p/android/issues/detail?id=15337 |
| 108 // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-
working | 108 // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-
working |
| 109 RAW_CHECK(sigprocmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); | 109 RAW_CHECK(sigprocmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); |
| 110 #else | 110 #else |
| 111 RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); | 111 RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0); |
| 112 #endif | 112 #endif |
| 113 return old_sigmask; | 113 return old_sigmask; |
| 114 } | 114 } |
| 115 | 115 |
| 116 #if !defined(OS_LINUX) || \ | 116 #if (!defined(OS_LINUX) && !defined(OS_AIX)) || \ |
| 117 (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) | 117 (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) |
| 118 void ResetChildSignalHandlersToDefaults() { | 118 void ResetChildSignalHandlersToDefaults() { |
| 119 // The previous signal handlers are likely to be meaningless in the child's | 119 // The previous signal handlers are likely to be meaningless in the child's |
| 120 // context so we reset them to the defaults for now. http://crbug.com/44953 | 120 // context so we reset them to the defaults for now. http://crbug.com/44953 |
| 121 // These signal handlers are set up at least in browser_main_posix.cc: | 121 // These signal handlers are set up at least in browser_main_posix.cc: |
| 122 // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc: | 122 // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc: |
| 123 // EnableInProcessStackDumping. | 123 // EnableInProcessStackDumping. |
| 124 signal(SIGHUP, SIG_DFL); | 124 signal(SIGHUP, SIG_DFL); |
| 125 signal(SIGINT, SIG_DFL); | 125 signal(SIGINT, SIG_DFL); |
| 126 signal(SIGILL, SIG_DFL); | 126 signal(SIGILL, SIG_DFL); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 struct ScopedDIRClose { | 204 struct ScopedDIRClose { |
| 205 inline void operator()(DIR* x) const { | 205 inline void operator()(DIR* x) const { |
| 206 if (x) | 206 if (x) |
| 207 closedir(x); | 207 closedir(x); |
| 208 } | 208 } |
| 209 }; | 209 }; |
| 210 | 210 |
| 211 // Automatically closes |DIR*|s. | 211 // Automatically closes |DIR*|s. |
| 212 typedef std::unique_ptr<DIR, ScopedDIRClose> ScopedDIR; | 212 typedef std::unique_ptr<DIR, ScopedDIRClose> ScopedDIR; |
| 213 | 213 |
| 214 #if defined(OS_LINUX) | 214 #if defined(OS_LINUX) || defined(OS_AIX) |
| 215 static const char kFDDir[] = "/proc/self/fd"; | 215 static const char kFDDir[] = "/proc/self/fd"; |
| 216 #elif defined(OS_MACOSX) | 216 #elif defined(OS_MACOSX) |
| 217 static const char kFDDir[] = "/dev/fd"; | 217 static const char kFDDir[] = "/dev/fd"; |
| 218 #elif defined(OS_SOLARIS) | 218 #elif defined(OS_SOLARIS) |
| 219 static const char kFDDir[] = "/dev/fd"; | 219 static const char kFDDir[] = "/dev/fd"; |
| 220 #elif defined(OS_FREEBSD) | 220 #elif defined(OS_FREEBSD) |
| 221 static const char kFDDir[] = "/dev/fd"; | 221 static const char kFDDir[] = "/dev/fd"; |
| 222 #elif defined(OS_OPENBSD) | 222 #elif defined(OS_OPENBSD) |
| 223 static const char kFDDir[] = "/dev/fd"; | 223 static const char kFDDir[] = "/dev/fd"; |
| 224 #elif defined(OS_ANDROID) | 224 #elif defined(OS_ANDROID) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 sigset_t full_sigset; | 334 sigset_t full_sigset; |
| 335 sigfillset(&full_sigset); | 335 sigfillset(&full_sigset); |
| 336 const sigset_t orig_sigmask = SetSignalMask(full_sigset); | 336 const sigset_t orig_sigmask = SetSignalMask(full_sigset); |
| 337 | 337 |
| 338 const char* current_directory = nullptr; | 338 const char* current_directory = nullptr; |
| 339 if (!options.current_directory.empty()) { | 339 if (!options.current_directory.empty()) { |
| 340 current_directory = options.current_directory.value().c_str(); | 340 current_directory = options.current_directory.value().c_str(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 pid_t pid; | 343 pid_t pid; |
| 344 #if defined(OS_LINUX) | 344 #if defined(OS_LINUX) || defined(OS_AIX) |
| 345 if (options.clone_flags) { | 345 if (options.clone_flags) { |
| 346 // Signal handling in this function assumes the creation of a new | 346 // Signal handling in this function assumes the creation of a new |
| 347 // process, so we check that a thread is not being created by mistake | 347 // process, so we check that a thread is not being created by mistake |
| 348 // and that signal handling follows the process-creation rules. | 348 // and that signal handling follows the process-creation rules. |
| 349 RAW_CHECK( | 349 RAW_CHECK( |
| 350 !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM))); | 350 !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM))); |
| 351 | 351 |
| 352 // We specify a null ptid and ctid. | 352 // We specify a null ptid and ctid. |
| 353 RAW_CHECK( | 353 RAW_CHECK( |
| 354 !(options.clone_flags & | 354 !(options.clone_flags & |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 SetEnvironment(new_environ.get()); | 469 SetEnvironment(new_environ.get()); |
| 470 | 470 |
| 471 // fd_shuffle1 is mutated by this call because it cannot malloc. | 471 // fd_shuffle1 is mutated by this call because it cannot malloc. |
| 472 if (!ShuffleFileDescriptors(&fd_shuffle1)) | 472 if (!ShuffleFileDescriptors(&fd_shuffle1)) |
| 473 _exit(127); | 473 _exit(127); |
| 474 | 474 |
| 475 CloseSuperfluousFds(fd_shuffle2); | 475 CloseSuperfluousFds(fd_shuffle2); |
| 476 | 476 |
| 477 // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel | 477 // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel |
| 478 // 3.5+, do not check the return value of prctl here. | 478 // 3.5+, do not check the return value of prctl here. |
| 479 #if defined(OS_LINUX) | 479 #if defined(OS_LINUX) || defined(OS_AIX) |
| 480 #ifndef PR_SET_NO_NEW_PRIVS | 480 #ifndef PR_SET_NO_NEW_PRIVS |
| 481 #define PR_SET_NO_NEW_PRIVS 38 | 481 #define PR_SET_NO_NEW_PRIVS 38 |
| 482 #endif | 482 #endif |
| 483 if (!options.allow_new_privs) { | 483 if (!options.allow_new_privs) { |
| 484 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) { | 484 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) { |
| 485 // Only log if the error is not EINVAL (i.e. not supported). | 485 // Only log if the error is not EINVAL (i.e. not supported). |
| 486 RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed"); | 486 RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed"); |
| 487 } | 487 } |
| 488 } | 488 } |
| 489 | 489 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 bool GetAppOutputWithExitCode(const CommandLine& cl, | 674 bool GetAppOutputWithExitCode(const CommandLine& cl, |
| 675 std::string* output, | 675 std::string* output, |
| 676 int* exit_code) { | 676 int* exit_code) { |
| 677 // Run |execve()| with the current environment. | 677 // Run |execve()| with the current environment. |
| 678 return GetAppOutputInternal(cl.argv(), nullptr, false, output, true, | 678 return GetAppOutputInternal(cl.argv(), nullptr, false, output, true, |
| 679 exit_code); | 679 exit_code); |
| 680 } | 680 } |
| 681 | 681 |
| 682 #endif // !defined(OS_NACL_NONSFI) | 682 #endif // !defined(OS_NACL_NONSFI) |
| 683 | 683 |
| 684 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) | 684 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) || defined(OS_AIX) |
| 685 namespace { | 685 namespace { |
| 686 | 686 |
| 687 bool IsRunningOnValgrind() { | 687 bool IsRunningOnValgrind() { |
| 688 return RUNNING_ON_VALGRIND; | 688 return RUNNING_ON_VALGRIND; |
| 689 } | 689 } |
| 690 | 690 |
| 691 // This function runs on the stack specified on the clone call. It uses longjmp | 691 // This function runs on the stack specified on the clone call. It uses longjmp |
| 692 // to switch back to the original stack so the child can return from sys_clone. | 692 // to switch back to the original stack so the child can return from sys_clone. |
| 693 int CloneHelper(void* arg) { | 693 int CloneHelper(void* arg) { |
| 694 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg); | 694 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 jmp_buf env; | 766 jmp_buf env; |
| 767 if (setjmp(env) == 0) { | 767 if (setjmp(env) == 0) { |
| 768 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); | 768 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); |
| 769 } | 769 } |
| 770 | 770 |
| 771 return 0; | 771 return 0; |
| 772 } | 772 } |
| 773 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) | 773 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
| 774 | 774 |
| 775 } // namespace base | 775 } // namespace base |
| OLD | NEW |