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 |