xref: /aosp_15_r20/external/libchrome/base/process/launch_posix.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/process/launch.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <dirent.h>
8*635a8641SAndroid Build Coastguard Worker #include <errno.h>
9*635a8641SAndroid Build Coastguard Worker #include <fcntl.h>
10*635a8641SAndroid Build Coastguard Worker #include <sched.h>
11*635a8641SAndroid Build Coastguard Worker #include <setjmp.h>
12*635a8641SAndroid Build Coastguard Worker #include <signal.h>
13*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
14*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
15*635a8641SAndroid Build Coastguard Worker #include <stdlib.h>
16*635a8641SAndroid Build Coastguard Worker #include <sys/resource.h>
17*635a8641SAndroid Build Coastguard Worker #include <sys/syscall.h>
18*635a8641SAndroid Build Coastguard Worker #include <sys/time.h>
19*635a8641SAndroid Build Coastguard Worker #include <sys/types.h>
20*635a8641SAndroid Build Coastguard Worker #include <sys/wait.h>
21*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
22*635a8641SAndroid Build Coastguard Worker 
23*635a8641SAndroid Build Coastguard Worker #include <iterator>
24*635a8641SAndroid Build Coastguard Worker #include <limits>
25*635a8641SAndroid Build Coastguard Worker #include <memory>
26*635a8641SAndroid Build Coastguard Worker #include <set>
27*635a8641SAndroid Build Coastguard Worker 
28*635a8641SAndroid Build Coastguard Worker #include "base/command_line.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/debug/debugger.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/files/dir_reader_posix.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
36*635a8641SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
37*635a8641SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
38*635a8641SAndroid Build Coastguard Worker #include "base/process/process.h"
39*635a8641SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
40*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
41*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
42*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
43*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
44*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
45*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event.h"
46*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
47*635a8641SAndroid Build Coastguard Worker 
48*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_AIX)
49*635a8641SAndroid Build Coastguard Worker #include <sys/prctl.h>
50*635a8641SAndroid Build Coastguard Worker #endif
51*635a8641SAndroid Build Coastguard Worker 
52*635a8641SAndroid Build Coastguard Worker #if defined(OS_CHROMEOS)
53*635a8641SAndroid Build Coastguard Worker #include <sys/ioctl.h>
54*635a8641SAndroid Build Coastguard Worker #endif
55*635a8641SAndroid Build Coastguard Worker 
56*635a8641SAndroid Build Coastguard Worker #if defined(OS_FREEBSD)
57*635a8641SAndroid Build Coastguard Worker #include <sys/event.h>
58*635a8641SAndroid Build Coastguard Worker #include <sys/ucontext.h>
59*635a8641SAndroid Build Coastguard Worker #endif
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
62*635a8641SAndroid Build Coastguard Worker #include <crt_externs.h>
63*635a8641SAndroid Build Coastguard Worker #include <sys/event.h>
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker #include "base/feature_list.h"
66*635a8641SAndroid Build Coastguard Worker #else
67*635a8641SAndroid Build Coastguard Worker extern char** environ;
68*635a8641SAndroid Build Coastguard Worker #endif
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker namespace base {
71*635a8641SAndroid Build Coastguard Worker 
72*635a8641SAndroid Build Coastguard Worker // Friend and derived class of ScopedAllowBaseSyncPrimitives which allows
73*635a8641SAndroid Build Coastguard Worker // GetAppOutputInternal() to join a process. GetAppOutputInternal() can't itself
74*635a8641SAndroid Build Coastguard Worker // be a friend of ScopedAllowBaseSyncPrimitives because it is in the anonymous
75*635a8641SAndroid Build Coastguard Worker // namespace.
76*635a8641SAndroid Build Coastguard Worker class GetAppOutputScopedAllowBaseSyncPrimitives
77*635a8641SAndroid Build Coastguard Worker     : public base::ScopedAllowBaseSyncPrimitives {};
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL_NONSFI)
80*635a8641SAndroid Build Coastguard Worker 
81*635a8641SAndroid Build Coastguard Worker namespace {
82*635a8641SAndroid Build Coastguard Worker 
83*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
84*635a8641SAndroid Build Coastguard Worker const Feature kMacLaunchProcessPosixSpawn{"MacLaunchProcessPosixSpawn",
85*635a8641SAndroid Build Coastguard Worker                                           FEATURE_ENABLED_BY_DEFAULT};
86*635a8641SAndroid Build Coastguard Worker #endif
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker // Get the process's "environment" (i.e. the thing that setenv/getenv
89*635a8641SAndroid Build Coastguard Worker // work with).
GetEnvironment()90*635a8641SAndroid Build Coastguard Worker char** GetEnvironment() {
91*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
92*635a8641SAndroid Build Coastguard Worker   return *_NSGetEnviron();
93*635a8641SAndroid Build Coastguard Worker #else
94*635a8641SAndroid Build Coastguard Worker   return environ;
95*635a8641SAndroid Build Coastguard Worker #endif
96*635a8641SAndroid Build Coastguard Worker }
97*635a8641SAndroid Build Coastguard Worker 
98*635a8641SAndroid Build Coastguard Worker // Set the process's "environment" (i.e. the thing that setenv/getenv
99*635a8641SAndroid Build Coastguard Worker // work with).
SetEnvironment(char ** env)100*635a8641SAndroid Build Coastguard Worker void SetEnvironment(char** env) {
101*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
102*635a8641SAndroid Build Coastguard Worker   *_NSGetEnviron() = env;
103*635a8641SAndroid Build Coastguard Worker #else
104*635a8641SAndroid Build Coastguard Worker   environ = env;
105*635a8641SAndroid Build Coastguard Worker #endif
106*635a8641SAndroid Build Coastguard Worker }
107*635a8641SAndroid Build Coastguard Worker 
108*635a8641SAndroid Build Coastguard Worker // Set the calling thread's signal mask to new_sigmask and return
109*635a8641SAndroid Build Coastguard Worker // the previous signal mask.
SetSignalMask(const sigset_t & new_sigmask)110*635a8641SAndroid Build Coastguard Worker sigset_t SetSignalMask(const sigset_t& new_sigmask) {
111*635a8641SAndroid Build Coastguard Worker   sigset_t old_sigmask;
112*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
113*635a8641SAndroid Build Coastguard Worker   // POSIX says pthread_sigmask() must be used in multi-threaded processes,
114*635a8641SAndroid Build Coastguard Worker   // but Android's pthread_sigmask() was broken until 4.1:
115*635a8641SAndroid Build Coastguard Worker   // https://code.google.com/p/android/issues/detail?id=15337
116*635a8641SAndroid Build Coastguard Worker   // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-working
117*635a8641SAndroid Build Coastguard Worker   RAW_CHECK(sigprocmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0);
118*635a8641SAndroid Build Coastguard Worker #else
119*635a8641SAndroid Build Coastguard Worker   RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0);
120*635a8641SAndroid Build Coastguard Worker #endif
121*635a8641SAndroid Build Coastguard Worker   return old_sigmask;
122*635a8641SAndroid Build Coastguard Worker }
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker #if (!defined(OS_LINUX) && !defined(OS_AIX)) || \
125*635a8641SAndroid Build Coastguard Worker     (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
ResetChildSignalHandlersToDefaults()126*635a8641SAndroid Build Coastguard Worker void ResetChildSignalHandlersToDefaults() {
127*635a8641SAndroid Build Coastguard Worker   // The previous signal handlers are likely to be meaningless in the child's
128*635a8641SAndroid Build Coastguard Worker   // context so we reset them to the defaults for now. http://crbug.com/44953
129*635a8641SAndroid Build Coastguard Worker   // These signal handlers are set up at least in browser_main_posix.cc:
130*635a8641SAndroid Build Coastguard Worker   // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc:
131*635a8641SAndroid Build Coastguard Worker   // EnableInProcessStackDumping.
132*635a8641SAndroid Build Coastguard Worker   signal(SIGHUP, SIG_DFL);
133*635a8641SAndroid Build Coastguard Worker   signal(SIGINT, SIG_DFL);
134*635a8641SAndroid Build Coastguard Worker   signal(SIGILL, SIG_DFL);
135*635a8641SAndroid Build Coastguard Worker   signal(SIGABRT, SIG_DFL);
136*635a8641SAndroid Build Coastguard Worker   signal(SIGFPE, SIG_DFL);
137*635a8641SAndroid Build Coastguard Worker   signal(SIGBUS, SIG_DFL);
138*635a8641SAndroid Build Coastguard Worker   signal(SIGSEGV, SIG_DFL);
139*635a8641SAndroid Build Coastguard Worker   signal(SIGSYS, SIG_DFL);
140*635a8641SAndroid Build Coastguard Worker   signal(SIGTERM, SIG_DFL);
141*635a8641SAndroid Build Coastguard Worker }
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker #else
144*635a8641SAndroid Build Coastguard Worker 
145*635a8641SAndroid Build Coastguard Worker // TODO(jln): remove the Linux special case once kernels are fixed.
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker // Internally the kernel makes sigset_t an array of long large enough to have
148*635a8641SAndroid Build Coastguard Worker // one bit per signal.
149*635a8641SAndroid Build Coastguard Worker typedef uint64_t kernel_sigset_t;
150*635a8641SAndroid Build Coastguard Worker 
151*635a8641SAndroid Build Coastguard Worker // This is what struct sigaction looks like to the kernel at least on X86 and
152*635a8641SAndroid Build Coastguard Worker // ARM. MIPS, for instance, is very different.
153*635a8641SAndroid Build Coastguard Worker struct kernel_sigaction {
154*635a8641SAndroid Build Coastguard Worker   void* k_sa_handler;  // For this usage it only needs to be a generic pointer.
155*635a8641SAndroid Build Coastguard Worker   unsigned long k_sa_flags;
156*635a8641SAndroid Build Coastguard Worker   void* k_sa_restorer;  // For this usage it only needs to be a generic pointer.
157*635a8641SAndroid Build Coastguard Worker   kernel_sigset_t k_sa_mask;
158*635a8641SAndroid Build Coastguard Worker };
159*635a8641SAndroid Build Coastguard Worker 
160*635a8641SAndroid Build Coastguard Worker // glibc's sigaction() will prevent access to sa_restorer, so we need to roll
161*635a8641SAndroid Build Coastguard Worker // our own.
sys_rt_sigaction(int sig,const struct kernel_sigaction * act,struct kernel_sigaction * oact)162*635a8641SAndroid Build Coastguard Worker int sys_rt_sigaction(int sig, const struct kernel_sigaction* act,
163*635a8641SAndroid Build Coastguard Worker                      struct kernel_sigaction* oact) {
164*635a8641SAndroid Build Coastguard Worker   return syscall(SYS_rt_sigaction, sig, act, oact, sizeof(kernel_sigset_t));
165*635a8641SAndroid Build Coastguard Worker }
166*635a8641SAndroid Build Coastguard Worker 
167*635a8641SAndroid Build Coastguard Worker // This function is intended to be used in between fork() and execve() and will
168*635a8641SAndroid Build Coastguard Worker // reset all signal handlers to the default.
169*635a8641SAndroid Build Coastguard Worker // The motivation for going through all of them is that sa_restorer can leak
170*635a8641SAndroid Build Coastguard Worker // from parents and help defeat ASLR on buggy kernels.  We reset it to null.
171*635a8641SAndroid Build Coastguard Worker // See crbug.com/177956.
ResetChildSignalHandlersToDefaults(void)172*635a8641SAndroid Build Coastguard Worker void ResetChildSignalHandlersToDefaults(void) {
173*635a8641SAndroid Build Coastguard Worker   for (int signum = 1; ; ++signum) {
174*635a8641SAndroid Build Coastguard Worker     struct kernel_sigaction act = {nullptr};
175*635a8641SAndroid Build Coastguard Worker     int sigaction_get_ret = sys_rt_sigaction(signum, nullptr, &act);
176*635a8641SAndroid Build Coastguard Worker     if (sigaction_get_ret && errno == EINVAL) {
177*635a8641SAndroid Build Coastguard Worker #if !defined(NDEBUG)
178*635a8641SAndroid Build Coastguard Worker       // Linux supports 32 real-time signals from 33 to 64.
179*635a8641SAndroid Build Coastguard Worker       // If the number of signals in the Linux kernel changes, someone should
180*635a8641SAndroid Build Coastguard Worker       // look at this code.
181*635a8641SAndroid Build Coastguard Worker       const int kNumberOfSignals = 64;
182*635a8641SAndroid Build Coastguard Worker       RAW_CHECK(signum == kNumberOfSignals + 1);
183*635a8641SAndroid Build Coastguard Worker #endif  // !defined(NDEBUG)
184*635a8641SAndroid Build Coastguard Worker       break;
185*635a8641SAndroid Build Coastguard Worker     }
186*635a8641SAndroid Build Coastguard Worker     // All other failures are fatal.
187*635a8641SAndroid Build Coastguard Worker     if (sigaction_get_ret) {
188*635a8641SAndroid Build Coastguard Worker       RAW_LOG(FATAL, "sigaction (get) failed.");
189*635a8641SAndroid Build Coastguard Worker     }
190*635a8641SAndroid Build Coastguard Worker 
191*635a8641SAndroid Build Coastguard Worker     // The kernel won't allow to re-set SIGKILL or SIGSTOP.
192*635a8641SAndroid Build Coastguard Worker     if (signum != SIGSTOP && signum != SIGKILL) {
193*635a8641SAndroid Build Coastguard Worker       act.k_sa_handler = reinterpret_cast<void*>(SIG_DFL);
194*635a8641SAndroid Build Coastguard Worker       act.k_sa_restorer = nullptr;
195*635a8641SAndroid Build Coastguard Worker       if (sys_rt_sigaction(signum, &act, nullptr)) {
196*635a8641SAndroid Build Coastguard Worker         RAW_LOG(FATAL, "sigaction (set) failed.");
197*635a8641SAndroid Build Coastguard Worker       }
198*635a8641SAndroid Build Coastguard Worker     }
199*635a8641SAndroid Build Coastguard Worker #if !defined(NDEBUG)
200*635a8641SAndroid Build Coastguard Worker     // Now ask the kernel again and check that no restorer will leak.
201*635a8641SAndroid Build Coastguard Worker     if (sys_rt_sigaction(signum, nullptr, &act) || act.k_sa_restorer) {
202*635a8641SAndroid Build Coastguard Worker       RAW_LOG(FATAL, "Cound not fix sa_restorer.");
203*635a8641SAndroid Build Coastguard Worker     }
204*635a8641SAndroid Build Coastguard Worker #endif  // !defined(NDEBUG)
205*635a8641SAndroid Build Coastguard Worker   }
206*635a8641SAndroid Build Coastguard Worker }
207*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_LINUX) ||
208*635a8641SAndroid Build Coastguard Worker         // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
209*635a8641SAndroid Build Coastguard Worker }  // anonymous namespace
210*635a8641SAndroid Build Coastguard Worker 
211*635a8641SAndroid Build Coastguard Worker // Functor for |ScopedDIR| (below).
212*635a8641SAndroid Build Coastguard Worker struct ScopedDIRClose {
operator ()base::ScopedDIRClose213*635a8641SAndroid Build Coastguard Worker   inline void operator()(DIR* x) const {
214*635a8641SAndroid Build Coastguard Worker     if (x)
215*635a8641SAndroid Build Coastguard Worker       closedir(x);
216*635a8641SAndroid Build Coastguard Worker   }
217*635a8641SAndroid Build Coastguard Worker };
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker // Automatically closes |DIR*|s.
220*635a8641SAndroid Build Coastguard Worker typedef std::unique_ptr<DIR, ScopedDIRClose> ScopedDIR;
221*635a8641SAndroid Build Coastguard Worker 
222*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_AIX)
223*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/proc/self/fd";
224*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX)
225*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/dev/fd";
226*635a8641SAndroid Build Coastguard Worker #elif defined(OS_SOLARIS)
227*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/dev/fd";
228*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FREEBSD)
229*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/dev/fd";
230*635a8641SAndroid Build Coastguard Worker #elif defined(OS_OPENBSD)
231*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/dev/fd";
232*635a8641SAndroid Build Coastguard Worker #elif defined(OS_ANDROID)
233*635a8641SAndroid Build Coastguard Worker static const char kFDDir[] = "/proc/self/fd";
234*635a8641SAndroid Build Coastguard Worker #endif
235*635a8641SAndroid Build Coastguard Worker 
CloseSuperfluousFds(const base::InjectiveMultimap & saved_mapping)236*635a8641SAndroid Build Coastguard Worker void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
237*635a8641SAndroid Build Coastguard Worker   // DANGER: no calls to malloc or locks are allowed from now on:
238*635a8641SAndroid Build Coastguard Worker   // http://crbug.com/36678
239*635a8641SAndroid Build Coastguard Worker 
240*635a8641SAndroid Build Coastguard Worker   // Get the maximum number of FDs possible.
241*635a8641SAndroid Build Coastguard Worker   size_t max_fds = GetMaxFds();
242*635a8641SAndroid Build Coastguard Worker 
243*635a8641SAndroid Build Coastguard Worker   DirReaderPosix fd_dir(kFDDir);
244*635a8641SAndroid Build Coastguard Worker   if (!fd_dir.IsValid()) {
245*635a8641SAndroid Build Coastguard Worker     // Fallback case: Try every possible fd.
246*635a8641SAndroid Build Coastguard Worker     for (size_t i = 0; i < max_fds; ++i) {
247*635a8641SAndroid Build Coastguard Worker       const int fd = static_cast<int>(i);
248*635a8641SAndroid Build Coastguard Worker       if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
249*635a8641SAndroid Build Coastguard Worker         continue;
250*635a8641SAndroid Build Coastguard Worker       // Cannot use STL iterators here, since debug iterators use locks.
251*635a8641SAndroid Build Coastguard Worker       size_t j;
252*635a8641SAndroid Build Coastguard Worker       for (j = 0; j < saved_mapping.size(); j++) {
253*635a8641SAndroid Build Coastguard Worker         if (fd == saved_mapping[j].dest)
254*635a8641SAndroid Build Coastguard Worker           break;
255*635a8641SAndroid Build Coastguard Worker       }
256*635a8641SAndroid Build Coastguard Worker       if (j < saved_mapping.size())
257*635a8641SAndroid Build Coastguard Worker         continue;
258*635a8641SAndroid Build Coastguard Worker 
259*635a8641SAndroid Build Coastguard Worker       // Since we're just trying to close anything we can find,
260*635a8641SAndroid Build Coastguard Worker       // ignore any error return values of close().
261*635a8641SAndroid Build Coastguard Worker       close(fd);
262*635a8641SAndroid Build Coastguard Worker     }
263*635a8641SAndroid Build Coastguard Worker     return;
264*635a8641SAndroid Build Coastguard Worker   }
265*635a8641SAndroid Build Coastguard Worker 
266*635a8641SAndroid Build Coastguard Worker   const int dir_fd = fd_dir.fd();
267*635a8641SAndroid Build Coastguard Worker 
268*635a8641SAndroid Build Coastguard Worker   for ( ; fd_dir.Next(); ) {
269*635a8641SAndroid Build Coastguard Worker     // Skip . and .. entries.
270*635a8641SAndroid Build Coastguard Worker     if (fd_dir.name()[0] == '.')
271*635a8641SAndroid Build Coastguard Worker       continue;
272*635a8641SAndroid Build Coastguard Worker 
273*635a8641SAndroid Build Coastguard Worker     char *endptr;
274*635a8641SAndroid Build Coastguard Worker     errno = 0;
275*635a8641SAndroid Build Coastguard Worker     const long int fd = strtol(fd_dir.name(), &endptr, 10);
276*635a8641SAndroid Build Coastguard Worker     if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
277*635a8641SAndroid Build Coastguard Worker       continue;
278*635a8641SAndroid Build Coastguard Worker     if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
279*635a8641SAndroid Build Coastguard Worker       continue;
280*635a8641SAndroid Build Coastguard Worker     // Cannot use STL iterators here, since debug iterators use locks.
281*635a8641SAndroid Build Coastguard Worker     size_t i;
282*635a8641SAndroid Build Coastguard Worker     for (i = 0; i < saved_mapping.size(); i++) {
283*635a8641SAndroid Build Coastguard Worker       if (fd == saved_mapping[i].dest)
284*635a8641SAndroid Build Coastguard Worker         break;
285*635a8641SAndroid Build Coastguard Worker     }
286*635a8641SAndroid Build Coastguard Worker     if (i < saved_mapping.size())
287*635a8641SAndroid Build Coastguard Worker       continue;
288*635a8641SAndroid Build Coastguard Worker     if (fd == dir_fd)
289*635a8641SAndroid Build Coastguard Worker       continue;
290*635a8641SAndroid Build Coastguard Worker 
291*635a8641SAndroid Build Coastguard Worker     int ret = IGNORE_EINTR(close(fd));
292*635a8641SAndroid Build Coastguard Worker     DPCHECK(ret == 0);
293*635a8641SAndroid Build Coastguard Worker   }
294*635a8641SAndroid Build Coastguard Worker }
295*635a8641SAndroid Build Coastguard Worker 
LaunchProcess(const CommandLine & cmdline,const LaunchOptions & options)296*635a8641SAndroid Build Coastguard Worker Process LaunchProcess(const CommandLine& cmdline,
297*635a8641SAndroid Build Coastguard Worker                       const LaunchOptions& options) {
298*635a8641SAndroid Build Coastguard Worker   return LaunchProcess(cmdline.argv(), options);
299*635a8641SAndroid Build Coastguard Worker }
300*635a8641SAndroid Build Coastguard Worker 
LaunchProcess(const std::vector<std::string> & argv,const LaunchOptions & options)301*635a8641SAndroid Build Coastguard Worker Process LaunchProcess(const std::vector<std::string>& argv,
302*635a8641SAndroid Build Coastguard Worker                       const LaunchOptions& options) {
303*635a8641SAndroid Build Coastguard Worker   TRACE_EVENT0("base", "LaunchProcess");
304*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
305*635a8641SAndroid Build Coastguard Worker   if (FeatureList::IsEnabled(kMacLaunchProcessPosixSpawn)) {
306*635a8641SAndroid Build Coastguard Worker     // TODO(rsesek): Do this unconditionally. There is one user for each of
307*635a8641SAndroid Build Coastguard Worker     // these two options. https://crbug.com/179923.
308*635a8641SAndroid Build Coastguard Worker     if (!options.pre_exec_delegate && options.current_directory.empty())
309*635a8641SAndroid Build Coastguard Worker       return LaunchProcessPosixSpawn(argv, options);
310*635a8641SAndroid Build Coastguard Worker   }
311*635a8641SAndroid Build Coastguard Worker #endif
312*635a8641SAndroid Build Coastguard Worker 
313*635a8641SAndroid Build Coastguard Worker   InjectiveMultimap fd_shuffle1;
314*635a8641SAndroid Build Coastguard Worker   InjectiveMultimap fd_shuffle2;
315*635a8641SAndroid Build Coastguard Worker   fd_shuffle1.reserve(options.fds_to_remap.size());
316*635a8641SAndroid Build Coastguard Worker   fd_shuffle2.reserve(options.fds_to_remap.size());
317*635a8641SAndroid Build Coastguard Worker 
318*635a8641SAndroid Build Coastguard Worker   std::vector<char*> argv_cstr;
319*635a8641SAndroid Build Coastguard Worker   argv_cstr.reserve(argv.size() + 1);
320*635a8641SAndroid Build Coastguard Worker   for (const auto& arg : argv)
321*635a8641SAndroid Build Coastguard Worker     argv_cstr.push_back(const_cast<char*>(arg.c_str()));
322*635a8641SAndroid Build Coastguard Worker   argv_cstr.push_back(nullptr);
323*635a8641SAndroid Build Coastguard Worker 
324*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<char* []> new_environ;
325*635a8641SAndroid Build Coastguard Worker   char* const empty_environ = nullptr;
326*635a8641SAndroid Build Coastguard Worker   char* const* old_environ = GetEnvironment();
327*635a8641SAndroid Build Coastguard Worker   if (options.clear_environ)
328*635a8641SAndroid Build Coastguard Worker     old_environ = &empty_environ;
329*635a8641SAndroid Build Coastguard Worker   if (!options.environ.empty())
330*635a8641SAndroid Build Coastguard Worker     new_environ = AlterEnvironment(old_environ, options.environ);
331*635a8641SAndroid Build Coastguard Worker 
332*635a8641SAndroid Build Coastguard Worker   sigset_t full_sigset;
333*635a8641SAndroid Build Coastguard Worker   sigfillset(&full_sigset);
334*635a8641SAndroid Build Coastguard Worker   const sigset_t orig_sigmask = SetSignalMask(full_sigset);
335*635a8641SAndroid Build Coastguard Worker 
336*635a8641SAndroid Build Coastguard Worker   const char* current_directory = nullptr;
337*635a8641SAndroid Build Coastguard Worker   if (!options.current_directory.empty()) {
338*635a8641SAndroid Build Coastguard Worker     current_directory = options.current_directory.value().c_str();
339*635a8641SAndroid Build Coastguard Worker   }
340*635a8641SAndroid Build Coastguard Worker 
341*635a8641SAndroid Build Coastguard Worker   pid_t pid;
342*635a8641SAndroid Build Coastguard Worker   base::TimeTicks before_fork = TimeTicks::Now();
343*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_AIX)
344*635a8641SAndroid Build Coastguard Worker   if (options.clone_flags) {
345*635a8641SAndroid Build Coastguard Worker     // Signal handling in this function assumes the creation of a new
346*635a8641SAndroid Build Coastguard Worker     // process, so we check that a thread is not being created by mistake
347*635a8641SAndroid Build Coastguard Worker     // and that signal handling follows the process-creation rules.
348*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(
349*635a8641SAndroid Build Coastguard Worker         !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM)));
350*635a8641SAndroid Build Coastguard Worker 
351*635a8641SAndroid Build Coastguard Worker     // We specify a null ptid and ctid.
352*635a8641SAndroid Build Coastguard Worker     RAW_CHECK(
353*635a8641SAndroid Build Coastguard Worker         !(options.clone_flags &
354*635a8641SAndroid Build Coastguard Worker           (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT_SETTID)));
355*635a8641SAndroid Build Coastguard Worker 
356*635a8641SAndroid Build Coastguard Worker     // Since we use waitpid, we do not support custom termination signals in the
357*635a8641SAndroid Build Coastguard Worker     // clone flags.
358*635a8641SAndroid Build Coastguard Worker     RAW_CHECK((options.clone_flags & 0xff) == 0);
359*635a8641SAndroid Build Coastguard Worker 
360*635a8641SAndroid Build Coastguard Worker     pid = ForkWithFlags(options.clone_flags | SIGCHLD, nullptr, nullptr);
361*635a8641SAndroid Build Coastguard Worker   } else
362*635a8641SAndroid Build Coastguard Worker #endif
363*635a8641SAndroid Build Coastguard Worker   {
364*635a8641SAndroid Build Coastguard Worker     pid = fork();
365*635a8641SAndroid Build Coastguard Worker   }
366*635a8641SAndroid Build Coastguard Worker 
367*635a8641SAndroid Build Coastguard Worker   // Always restore the original signal mask in the parent.
368*635a8641SAndroid Build Coastguard Worker   if (pid != 0) {
369*635a8641SAndroid Build Coastguard Worker     base::TimeTicks after_fork = TimeTicks::Now();
370*635a8641SAndroid Build Coastguard Worker     SetSignalMask(orig_sigmask);
371*635a8641SAndroid Build Coastguard Worker 
372*635a8641SAndroid Build Coastguard Worker     base::TimeDelta fork_time = after_fork - before_fork;
373*635a8641SAndroid Build Coastguard Worker     UMA_HISTOGRAM_TIMES("MPArch.ForkTime", fork_time);
374*635a8641SAndroid Build Coastguard Worker   }
375*635a8641SAndroid Build Coastguard Worker 
376*635a8641SAndroid Build Coastguard Worker   if (pid < 0) {
377*635a8641SAndroid Build Coastguard Worker     DPLOG(ERROR) << "fork";
378*635a8641SAndroid Build Coastguard Worker     return Process();
379*635a8641SAndroid Build Coastguard Worker   } else if (pid == 0) {
380*635a8641SAndroid Build Coastguard Worker     // Child process
381*635a8641SAndroid Build Coastguard Worker 
382*635a8641SAndroid Build Coastguard Worker     // DANGER: no calls to malloc or locks are allowed from now on:
383*635a8641SAndroid Build Coastguard Worker     // http://crbug.com/36678
384*635a8641SAndroid Build Coastguard Worker 
385*635a8641SAndroid Build Coastguard Worker     // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
386*635a8641SAndroid Build Coastguard Worker     // you call _exit() instead of exit(). This is because _exit() does not
387*635a8641SAndroid Build Coastguard Worker     // call any previously-registered (in the parent) exit handlers, which
388*635a8641SAndroid Build Coastguard Worker     // might do things like block waiting for threads that don't even exist
389*635a8641SAndroid Build Coastguard Worker     // in the child.
390*635a8641SAndroid Build Coastguard Worker 
391*635a8641SAndroid Build Coastguard Worker     // If a child process uses the readline library, the process block forever.
392*635a8641SAndroid Build Coastguard Worker     // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
393*635a8641SAndroid Build Coastguard Worker     // See http://crbug.com/56596.
394*635a8641SAndroid Build Coastguard Worker     base::ScopedFD null_fd(HANDLE_EINTR(open("/dev/null", O_RDONLY)));
395*635a8641SAndroid Build Coastguard Worker     if (!null_fd.is_valid()) {
396*635a8641SAndroid Build Coastguard Worker       RAW_LOG(ERROR, "Failed to open /dev/null");
397*635a8641SAndroid Build Coastguard Worker       _exit(127);
398*635a8641SAndroid Build Coastguard Worker     }
399*635a8641SAndroid Build Coastguard Worker 
400*635a8641SAndroid Build Coastguard Worker     int new_fd = HANDLE_EINTR(dup2(null_fd.get(), STDIN_FILENO));
401*635a8641SAndroid Build Coastguard Worker     if (new_fd != STDIN_FILENO) {
402*635a8641SAndroid Build Coastguard Worker       RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
403*635a8641SAndroid Build Coastguard Worker       _exit(127);
404*635a8641SAndroid Build Coastguard Worker     }
405*635a8641SAndroid Build Coastguard Worker 
406*635a8641SAndroid Build Coastguard Worker     if (options.new_process_group) {
407*635a8641SAndroid Build Coastguard Worker       // Instead of inheriting the process group ID of the parent, the child
408*635a8641SAndroid Build Coastguard Worker       // starts off a new process group with pgid equal to its process ID.
409*635a8641SAndroid Build Coastguard Worker       if (setpgid(0, 0) < 0) {
410*635a8641SAndroid Build Coastguard Worker         RAW_LOG(ERROR, "setpgid failed");
411*635a8641SAndroid Build Coastguard Worker         _exit(127);
412*635a8641SAndroid Build Coastguard Worker       }
413*635a8641SAndroid Build Coastguard Worker     }
414*635a8641SAndroid Build Coastguard Worker 
415*635a8641SAndroid Build Coastguard Worker     if (options.maximize_rlimits) {
416*635a8641SAndroid Build Coastguard Worker       // Some resource limits need to be maximal in this child.
417*635a8641SAndroid Build Coastguard Worker       for (size_t i = 0; i < options.maximize_rlimits->size(); ++i) {
418*635a8641SAndroid Build Coastguard Worker         const int resource = (*options.maximize_rlimits)[i];
419*635a8641SAndroid Build Coastguard Worker         struct rlimit limit;
420*635a8641SAndroid Build Coastguard Worker         if (getrlimit(resource, &limit) < 0) {
421*635a8641SAndroid Build Coastguard Worker           RAW_LOG(WARNING, "getrlimit failed");
422*635a8641SAndroid Build Coastguard Worker         } else if (limit.rlim_cur < limit.rlim_max) {
423*635a8641SAndroid Build Coastguard Worker           limit.rlim_cur = limit.rlim_max;
424*635a8641SAndroid Build Coastguard Worker           if (setrlimit(resource, &limit) < 0) {
425*635a8641SAndroid Build Coastguard Worker             RAW_LOG(WARNING, "setrlimit failed");
426*635a8641SAndroid Build Coastguard Worker           }
427*635a8641SAndroid Build Coastguard Worker         }
428*635a8641SAndroid Build Coastguard Worker       }
429*635a8641SAndroid Build Coastguard Worker     }
430*635a8641SAndroid Build Coastguard Worker 
431*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
432*635a8641SAndroid Build Coastguard Worker     RestoreDefaultExceptionHandler();
433*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_MACOSX)
434*635a8641SAndroid Build Coastguard Worker 
435*635a8641SAndroid Build Coastguard Worker     ResetChildSignalHandlersToDefaults();
436*635a8641SAndroid Build Coastguard Worker     SetSignalMask(orig_sigmask);
437*635a8641SAndroid Build Coastguard Worker 
438*635a8641SAndroid Build Coastguard Worker #if 0
439*635a8641SAndroid Build Coastguard Worker     // When debugging it can be helpful to check that we really aren't making
440*635a8641SAndroid Build Coastguard Worker     // any hidden calls to malloc.
441*635a8641SAndroid Build Coastguard Worker     void *malloc_thunk =
442*635a8641SAndroid Build Coastguard Worker         reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
443*635a8641SAndroid Build Coastguard Worker     mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
444*635a8641SAndroid Build Coastguard Worker     memset(reinterpret_cast<void*>(malloc), 0xff, 8);
445*635a8641SAndroid Build Coastguard Worker #endif  // 0
446*635a8641SAndroid Build Coastguard Worker 
447*635a8641SAndroid Build Coastguard Worker #if defined(OS_CHROMEOS)
448*635a8641SAndroid Build Coastguard Worker     if (options.ctrl_terminal_fd >= 0) {
449*635a8641SAndroid Build Coastguard Worker       // Set process' controlling terminal.
450*635a8641SAndroid Build Coastguard Worker       if (HANDLE_EINTR(setsid()) != -1) {
451*635a8641SAndroid Build Coastguard Worker         if (HANDLE_EINTR(
452*635a8641SAndroid Build Coastguard Worker                 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, nullptr)) == -1) {
453*635a8641SAndroid Build Coastguard Worker           RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
454*635a8641SAndroid Build Coastguard Worker         }
455*635a8641SAndroid Build Coastguard Worker       } else {
456*635a8641SAndroid Build Coastguard Worker         RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
457*635a8641SAndroid Build Coastguard Worker       }
458*635a8641SAndroid Build Coastguard Worker     }
459*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_CHROMEOS)
460*635a8641SAndroid Build Coastguard Worker 
461*635a8641SAndroid Build Coastguard Worker     // Cannot use STL iterators here, since debug iterators use locks.
462*635a8641SAndroid Build Coastguard Worker     for (size_t i = 0; i < options.fds_to_remap.size(); ++i) {
463*635a8641SAndroid Build Coastguard Worker       const FileHandleMappingVector::value_type& value =
464*635a8641SAndroid Build Coastguard Worker           options.fds_to_remap[i];
465*635a8641SAndroid Build Coastguard Worker       fd_shuffle1.push_back(InjectionArc(value.first, value.second, false));
466*635a8641SAndroid Build Coastguard Worker       fd_shuffle2.push_back(InjectionArc(value.first, value.second, false));
467*635a8641SAndroid Build Coastguard Worker     }
468*635a8641SAndroid Build Coastguard Worker 
469*635a8641SAndroid Build Coastguard Worker     if (!options.environ.empty() || options.clear_environ)
470*635a8641SAndroid Build Coastguard Worker       SetEnvironment(new_environ.get());
471*635a8641SAndroid Build Coastguard Worker 
472*635a8641SAndroid Build Coastguard Worker     // fd_shuffle1 is mutated by this call because it cannot malloc.
473*635a8641SAndroid Build Coastguard Worker     if (!ShuffleFileDescriptors(&fd_shuffle1))
474*635a8641SAndroid Build Coastguard Worker       _exit(127);
475*635a8641SAndroid Build Coastguard Worker 
476*635a8641SAndroid Build Coastguard Worker     CloseSuperfluousFds(fd_shuffle2);
477*635a8641SAndroid Build Coastguard Worker 
478*635a8641SAndroid Build Coastguard Worker     // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel
479*635a8641SAndroid Build Coastguard Worker     // 3.5+, do not check the return value of prctl here.
480*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_AIX)
481*635a8641SAndroid Build Coastguard Worker #ifndef PR_SET_NO_NEW_PRIVS
482*635a8641SAndroid Build Coastguard Worker #define PR_SET_NO_NEW_PRIVS 38
483*635a8641SAndroid Build Coastguard Worker #endif
484*635a8641SAndroid Build Coastguard Worker     if (!options.allow_new_privs) {
485*635a8641SAndroid Build Coastguard Worker       if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) {
486*635a8641SAndroid Build Coastguard Worker         // Only log if the error is not EINVAL (i.e. not supported).
487*635a8641SAndroid Build Coastguard Worker         RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed");
488*635a8641SAndroid Build Coastguard Worker       }
489*635a8641SAndroid Build Coastguard Worker     }
490*635a8641SAndroid Build Coastguard Worker 
491*635a8641SAndroid Build Coastguard Worker     if (options.kill_on_parent_death) {
492*635a8641SAndroid Build Coastguard Worker       if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0) {
493*635a8641SAndroid Build Coastguard Worker         RAW_LOG(ERROR, "prctl(PR_SET_PDEATHSIG) failed");
494*635a8641SAndroid Build Coastguard Worker         _exit(127);
495*635a8641SAndroid Build Coastguard Worker       }
496*635a8641SAndroid Build Coastguard Worker     }
497*635a8641SAndroid Build Coastguard Worker #endif
498*635a8641SAndroid Build Coastguard Worker 
499*635a8641SAndroid Build Coastguard Worker     if (current_directory != nullptr) {
500*635a8641SAndroid Build Coastguard Worker       RAW_CHECK(chdir(current_directory) == 0);
501*635a8641SAndroid Build Coastguard Worker     }
502*635a8641SAndroid Build Coastguard Worker 
503*635a8641SAndroid Build Coastguard Worker     if (options.pre_exec_delegate != nullptr) {
504*635a8641SAndroid Build Coastguard Worker       options.pre_exec_delegate->RunAsyncSafe();
505*635a8641SAndroid Build Coastguard Worker     }
506*635a8641SAndroid Build Coastguard Worker 
507*635a8641SAndroid Build Coastguard Worker     const char* executable_path = !options.real_path.empty() ?
508*635a8641SAndroid Build Coastguard Worker         options.real_path.value().c_str() : argv_cstr[0];
509*635a8641SAndroid Build Coastguard Worker 
510*635a8641SAndroid Build Coastguard Worker     execvp(executable_path, argv_cstr.data());
511*635a8641SAndroid Build Coastguard Worker 
512*635a8641SAndroid Build Coastguard Worker     RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
513*635a8641SAndroid Build Coastguard Worker     RAW_LOG(ERROR, argv_cstr[0]);
514*635a8641SAndroid Build Coastguard Worker     _exit(127);
515*635a8641SAndroid Build Coastguard Worker   } else {
516*635a8641SAndroid Build Coastguard Worker     // Parent process
517*635a8641SAndroid Build Coastguard Worker     if (options.wait) {
518*635a8641SAndroid Build Coastguard Worker       // While this isn't strictly disk IO, waiting for another process to
519*635a8641SAndroid Build Coastguard Worker       // finish is the sort of thing ThreadRestrictions is trying to prevent.
520*635a8641SAndroid Build Coastguard Worker       base::AssertBlockingAllowed();
521*635a8641SAndroid Build Coastguard Worker       pid_t ret = HANDLE_EINTR(waitpid(pid, nullptr, 0));
522*635a8641SAndroid Build Coastguard Worker       DPCHECK(ret > 0);
523*635a8641SAndroid Build Coastguard Worker     }
524*635a8641SAndroid Build Coastguard Worker   }
525*635a8641SAndroid Build Coastguard Worker 
526*635a8641SAndroid Build Coastguard Worker   return Process(pid);
527*635a8641SAndroid Build Coastguard Worker }
528*635a8641SAndroid Build Coastguard Worker 
RaiseProcessToHighPriority()529*635a8641SAndroid Build Coastguard Worker void RaiseProcessToHighPriority() {
530*635a8641SAndroid Build Coastguard Worker   // On POSIX, we don't actually do anything here.  We could try to nice() or
531*635a8641SAndroid Build Coastguard Worker   // setpriority() or sched_getscheduler, but these all require extra rights.
532*635a8641SAndroid Build Coastguard Worker }
533*635a8641SAndroid Build Coastguard Worker 
534*635a8641SAndroid Build Coastguard Worker // Executes the application specified by |argv| and wait for it to exit. Stores
535*635a8641SAndroid Build Coastguard Worker // the output (stdout) in |output|. If |do_search_path| is set, it searches the
536*635a8641SAndroid Build Coastguard Worker // path for the application; in that case, |envp| must be null, and it will use
537*635a8641SAndroid Build Coastguard Worker // the current environment. If |do_search_path| is false, |argv[0]| should fully
538*635a8641SAndroid Build Coastguard Worker // specify the path of the application, and |envp| will be used as the
539*635a8641SAndroid Build Coastguard Worker // environment. If |include_stderr| is true, includes stderr otherwise redirects
540*635a8641SAndroid Build Coastguard Worker // it to /dev/null.
541*635a8641SAndroid Build Coastguard Worker // The return value of the function indicates success or failure. In the case of
542*635a8641SAndroid Build Coastguard Worker // success, the application exit code will be returned in |*exit_code|, which
543*635a8641SAndroid Build Coastguard Worker // should be checked to determine if the application ran successfully.
GetAppOutputInternal(const std::vector<std::string> & argv,char * const envp[],bool include_stderr,std::string * output,bool do_search_path,int * exit_code)544*635a8641SAndroid Build Coastguard Worker static bool GetAppOutputInternal(
545*635a8641SAndroid Build Coastguard Worker     const std::vector<std::string>& argv,
546*635a8641SAndroid Build Coastguard Worker     char* const envp[],
547*635a8641SAndroid Build Coastguard Worker     bool include_stderr,
548*635a8641SAndroid Build Coastguard Worker     std::string* output,
549*635a8641SAndroid Build Coastguard Worker     bool do_search_path,
550*635a8641SAndroid Build Coastguard Worker     int* exit_code) {
551*635a8641SAndroid Build Coastguard Worker   base::AssertBlockingAllowed();
552*635a8641SAndroid Build Coastguard Worker   // exit_code must be supplied so calling function can determine success.
553*635a8641SAndroid Build Coastguard Worker   DCHECK(exit_code);
554*635a8641SAndroid Build Coastguard Worker   *exit_code = EXIT_FAILURE;
555*635a8641SAndroid Build Coastguard Worker 
556*635a8641SAndroid Build Coastguard Worker   // Declare and call reserve() here before calling fork() because the child
557*635a8641SAndroid Build Coastguard Worker   // process cannot allocate memory.
558*635a8641SAndroid Build Coastguard Worker   std::vector<char*> argv_cstr;
559*635a8641SAndroid Build Coastguard Worker   argv_cstr.reserve(argv.size() + 1);
560*635a8641SAndroid Build Coastguard Worker   InjectiveMultimap fd_shuffle1;
561*635a8641SAndroid Build Coastguard Worker   InjectiveMultimap fd_shuffle2;
562*635a8641SAndroid Build Coastguard Worker   fd_shuffle1.reserve(3);
563*635a8641SAndroid Build Coastguard Worker   fd_shuffle2.reserve(3);
564*635a8641SAndroid Build Coastguard Worker 
565*635a8641SAndroid Build Coastguard Worker   // Either |do_search_path| should be false or |envp| should be null, but not
566*635a8641SAndroid Build Coastguard Worker   // both.
567*635a8641SAndroid Build Coastguard Worker   DCHECK(!do_search_path ^ !envp);
568*635a8641SAndroid Build Coastguard Worker 
569*635a8641SAndroid Build Coastguard Worker   int pipe_fd[2];
570*635a8641SAndroid Build Coastguard Worker   if (pipe(pipe_fd) < 0)
571*635a8641SAndroid Build Coastguard Worker     return false;
572*635a8641SAndroid Build Coastguard Worker 
573*635a8641SAndroid Build Coastguard Worker   pid_t pid = fork();
574*635a8641SAndroid Build Coastguard Worker   switch (pid) {
575*635a8641SAndroid Build Coastguard Worker     case -1: {
576*635a8641SAndroid Build Coastguard Worker       // error
577*635a8641SAndroid Build Coastguard Worker       close(pipe_fd[0]);
578*635a8641SAndroid Build Coastguard Worker       close(pipe_fd[1]);
579*635a8641SAndroid Build Coastguard Worker       return false;
580*635a8641SAndroid Build Coastguard Worker     }
581*635a8641SAndroid Build Coastguard Worker     case 0: {
582*635a8641SAndroid Build Coastguard Worker       // child
583*635a8641SAndroid Build Coastguard Worker       //
584*635a8641SAndroid Build Coastguard Worker       // DANGER: no calls to malloc or locks are allowed from now on:
585*635a8641SAndroid Build Coastguard Worker       // http://crbug.com/36678
586*635a8641SAndroid Build Coastguard Worker 
587*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
588*635a8641SAndroid Build Coastguard Worker       RestoreDefaultExceptionHandler();
589*635a8641SAndroid Build Coastguard Worker #endif
590*635a8641SAndroid Build Coastguard Worker 
591*635a8641SAndroid Build Coastguard Worker       // Obscure fork() rule: in the child, if you don't end up doing exec*(),
592*635a8641SAndroid Build Coastguard Worker       // you call _exit() instead of exit(). This is because _exit() does not
593*635a8641SAndroid Build Coastguard Worker       // call any previously-registered (in the parent) exit handlers, which
594*635a8641SAndroid Build Coastguard Worker       // might do things like block waiting for threads that don't even exist
595*635a8641SAndroid Build Coastguard Worker       // in the child.
596*635a8641SAndroid Build Coastguard Worker       int dev_null = open("/dev/null", O_WRONLY);
597*635a8641SAndroid Build Coastguard Worker       if (dev_null < 0)
598*635a8641SAndroid Build Coastguard Worker         _exit(127);
599*635a8641SAndroid Build Coastguard Worker 
600*635a8641SAndroid Build Coastguard Worker       fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
601*635a8641SAndroid Build Coastguard Worker       fd_shuffle1.push_back(InjectionArc(include_stderr ? pipe_fd[1] : dev_null,
602*635a8641SAndroid Build Coastguard Worker                                          STDERR_FILENO, true));
603*635a8641SAndroid Build Coastguard Worker       fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
604*635a8641SAndroid Build Coastguard Worker       // Adding another element here? Remeber to increase the argument to
605*635a8641SAndroid Build Coastguard Worker       // reserve(), above.
606*635a8641SAndroid Build Coastguard Worker 
607*635a8641SAndroid Build Coastguard Worker       for (size_t i = 0; i < fd_shuffle1.size(); ++i)
608*635a8641SAndroid Build Coastguard Worker         fd_shuffle2.push_back(fd_shuffle1[i]);
609*635a8641SAndroid Build Coastguard Worker 
610*635a8641SAndroid Build Coastguard Worker       if (!ShuffleFileDescriptors(&fd_shuffle1))
611*635a8641SAndroid Build Coastguard Worker         _exit(127);
612*635a8641SAndroid Build Coastguard Worker 
613*635a8641SAndroid Build Coastguard Worker       CloseSuperfluousFds(fd_shuffle2);
614*635a8641SAndroid Build Coastguard Worker 
615*635a8641SAndroid Build Coastguard Worker       for (const auto& arg : argv)
616*635a8641SAndroid Build Coastguard Worker         argv_cstr.push_back(const_cast<char*>(arg.c_str()));
617*635a8641SAndroid Build Coastguard Worker       argv_cstr.push_back(nullptr);
618*635a8641SAndroid Build Coastguard Worker 
619*635a8641SAndroid Build Coastguard Worker       if (do_search_path)
620*635a8641SAndroid Build Coastguard Worker         execvp(argv_cstr[0], argv_cstr.data());
621*635a8641SAndroid Build Coastguard Worker       else
622*635a8641SAndroid Build Coastguard Worker         execve(argv_cstr[0], argv_cstr.data(), envp);
623*635a8641SAndroid Build Coastguard Worker       _exit(127);
624*635a8641SAndroid Build Coastguard Worker     }
625*635a8641SAndroid Build Coastguard Worker     default: {
626*635a8641SAndroid Build Coastguard Worker       // parent
627*635a8641SAndroid Build Coastguard Worker       //
628*635a8641SAndroid Build Coastguard Worker       // Close our writing end of pipe now. Otherwise later read would not
629*635a8641SAndroid Build Coastguard Worker       // be able to detect end of child's output (in theory we could still
630*635a8641SAndroid Build Coastguard Worker       // write to the pipe).
631*635a8641SAndroid Build Coastguard Worker       close(pipe_fd[1]);
632*635a8641SAndroid Build Coastguard Worker 
633*635a8641SAndroid Build Coastguard Worker       output->clear();
634*635a8641SAndroid Build Coastguard Worker 
635*635a8641SAndroid Build Coastguard Worker       while (true) {
636*635a8641SAndroid Build Coastguard Worker         char buffer[256];
637*635a8641SAndroid Build Coastguard Worker         ssize_t bytes_read =
638*635a8641SAndroid Build Coastguard Worker             HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
639*635a8641SAndroid Build Coastguard Worker         if (bytes_read <= 0)
640*635a8641SAndroid Build Coastguard Worker           break;
641*635a8641SAndroid Build Coastguard Worker         output->append(buffer, bytes_read);
642*635a8641SAndroid Build Coastguard Worker       }
643*635a8641SAndroid Build Coastguard Worker       close(pipe_fd[0]);
644*635a8641SAndroid Build Coastguard Worker 
645*635a8641SAndroid Build Coastguard Worker       // Always wait for exit code (even if we know we'll declare
646*635a8641SAndroid Build Coastguard Worker       // GOT_MAX_OUTPUT).
647*635a8641SAndroid Build Coastguard Worker       Process process(pid);
648*635a8641SAndroid Build Coastguard Worker       // A process launched with GetAppOutput*() usually doesn't wait on the
649*635a8641SAndroid Build Coastguard Worker       // process that launched it and thus chances of deadlock are low.
650*635a8641SAndroid Build Coastguard Worker       GetAppOutputScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
651*635a8641SAndroid Build Coastguard Worker       return process.WaitForExit(exit_code);
652*635a8641SAndroid Build Coastguard Worker     }
653*635a8641SAndroid Build Coastguard Worker   }
654*635a8641SAndroid Build Coastguard Worker }
655*635a8641SAndroid Build Coastguard Worker 
GetAppOutput(const CommandLine & cl,std::string * output)656*635a8641SAndroid Build Coastguard Worker bool GetAppOutput(const CommandLine& cl, std::string* output) {
657*635a8641SAndroid Build Coastguard Worker   return GetAppOutput(cl.argv(), output);
658*635a8641SAndroid Build Coastguard Worker }
659*635a8641SAndroid Build Coastguard Worker 
GetAppOutput(const std::vector<std::string> & argv,std::string * output)660*635a8641SAndroid Build Coastguard Worker bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
661*635a8641SAndroid Build Coastguard Worker   // Run |execve()| with the current environment.
662*635a8641SAndroid Build Coastguard Worker   int exit_code;
663*635a8641SAndroid Build Coastguard Worker   bool result =
664*635a8641SAndroid Build Coastguard Worker       GetAppOutputInternal(argv, nullptr, false, output, true, &exit_code);
665*635a8641SAndroid Build Coastguard Worker   return result && exit_code == EXIT_SUCCESS;
666*635a8641SAndroid Build Coastguard Worker }
667*635a8641SAndroid Build Coastguard Worker 
GetAppOutputAndError(const CommandLine & cl,std::string * output)668*635a8641SAndroid Build Coastguard Worker bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
669*635a8641SAndroid Build Coastguard Worker   // Run |execve()| with the current environment.
670*635a8641SAndroid Build Coastguard Worker   int exit_code;
671*635a8641SAndroid Build Coastguard Worker   bool result =
672*635a8641SAndroid Build Coastguard Worker       GetAppOutputInternal(cl.argv(), nullptr, true, output, true, &exit_code);
673*635a8641SAndroid Build Coastguard Worker   return result && exit_code == EXIT_SUCCESS;
674*635a8641SAndroid Build Coastguard Worker }
675*635a8641SAndroid Build Coastguard Worker 
GetAppOutputAndError(const std::vector<std::string> & argv,std::string * output)676*635a8641SAndroid Build Coastguard Worker bool GetAppOutputAndError(const std::vector<std::string>& argv,
677*635a8641SAndroid Build Coastguard Worker                           std::string* output) {
678*635a8641SAndroid Build Coastguard Worker   int exit_code;
679*635a8641SAndroid Build Coastguard Worker   bool result =
680*635a8641SAndroid Build Coastguard Worker       GetAppOutputInternal(argv, nullptr, true, output, true, &exit_code);
681*635a8641SAndroid Build Coastguard Worker   return result && exit_code == EXIT_SUCCESS;
682*635a8641SAndroid Build Coastguard Worker }
683*635a8641SAndroid Build Coastguard Worker 
GetAppOutputWithExitCode(const CommandLine & cl,std::string * output,int * exit_code)684*635a8641SAndroid Build Coastguard Worker bool GetAppOutputWithExitCode(const CommandLine& cl,
685*635a8641SAndroid Build Coastguard Worker                               std::string* output,
686*635a8641SAndroid Build Coastguard Worker                               int* exit_code) {
687*635a8641SAndroid Build Coastguard Worker   // Run |execve()| with the current environment.
688*635a8641SAndroid Build Coastguard Worker   return GetAppOutputInternal(cl.argv(), nullptr, false, output, true,
689*635a8641SAndroid Build Coastguard Worker                               exit_code);
690*635a8641SAndroid Build Coastguard Worker }
691*635a8641SAndroid Build Coastguard Worker 
692*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_NACL_NONSFI)
693*635a8641SAndroid Build Coastguard Worker 
694*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) || defined(OS_AIX)
695*635a8641SAndroid Build Coastguard Worker namespace {
696*635a8641SAndroid Build Coastguard Worker 
697*635a8641SAndroid Build Coastguard Worker // This function runs on the stack specified on the clone call. It uses longjmp
698*635a8641SAndroid Build Coastguard Worker // to switch back to the original stack so the child can return from sys_clone.
CloneHelper(void * arg)699*635a8641SAndroid Build Coastguard Worker int CloneHelper(void* arg) {
700*635a8641SAndroid Build Coastguard Worker   jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
701*635a8641SAndroid Build Coastguard Worker   longjmp(*env_ptr, 1);
702*635a8641SAndroid Build Coastguard Worker 
703*635a8641SAndroid Build Coastguard Worker   // Should not be reached.
704*635a8641SAndroid Build Coastguard Worker   RAW_CHECK(false);
705*635a8641SAndroid Build Coastguard Worker   return 1;
706*635a8641SAndroid Build Coastguard Worker }
707*635a8641SAndroid Build Coastguard Worker 
708*635a8641SAndroid Build Coastguard Worker // This function is noinline to ensure that stack_buf is below the stack pointer
709*635a8641SAndroid Build Coastguard Worker // that is saved when setjmp is called below. This is needed because when
710*635a8641SAndroid Build Coastguard Worker // compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
711*635a8641SAndroid Build Coastguard Worker // upwards. See crbug.com/442912 for more details.
712*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
713*635a8641SAndroid Build Coastguard Worker // Disable AddressSanitizer instrumentation for this function to make sure
714*635a8641SAndroid Build Coastguard Worker // |stack_buf| is allocated on thread stack instead of ASan's fake stack.
715*635a8641SAndroid Build Coastguard Worker // Under ASan longjmp() will attempt to clean up the area between the old and
716*635a8641SAndroid Build Coastguard Worker // new stack pointers and print a warning that may confuse the user.
717*635a8641SAndroid Build Coastguard Worker __attribute__((no_sanitize_address))
718*635a8641SAndroid Build Coastguard Worker #endif
CloneAndLongjmpInChild(unsigned long flags,pid_t * ptid,pid_t * ctid,jmp_buf * env)719*635a8641SAndroid Build Coastguard Worker NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
720*635a8641SAndroid Build Coastguard Worker                                       pid_t* ptid,
721*635a8641SAndroid Build Coastguard Worker                                       pid_t* ctid,
722*635a8641SAndroid Build Coastguard Worker                                       jmp_buf* env) {
723*635a8641SAndroid Build Coastguard Worker   // We use the libc clone wrapper instead of making the syscall
724*635a8641SAndroid Build Coastguard Worker   // directly because making the syscall may fail to update the libc's
725*635a8641SAndroid Build Coastguard Worker   // internal pid cache. The libc interface unfortunately requires
726*635a8641SAndroid Build Coastguard Worker   // specifying a new stack, so we use setjmp/longjmp to emulate
727*635a8641SAndroid Build Coastguard Worker   // fork-like behavior.
728*635a8641SAndroid Build Coastguard Worker   alignas(16) char stack_buf[PTHREAD_STACK_MIN];
729*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) ||   \
730*635a8641SAndroid Build Coastguard Worker     defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_S390_FAMILY) || \
731*635a8641SAndroid Build Coastguard Worker     defined(ARCH_CPU_PPC64_FAMILY) || defined(ARCH_CPU_LOONG_FAMILY) || \
732*635a8641SAndroid Build Coastguard Worker     defined(ARCH_CPU_RISCV_FAMILY)
733*635a8641SAndroid Build Coastguard Worker   // The stack grows downward.
734*635a8641SAndroid Build Coastguard Worker   void* stack = stack_buf + sizeof(stack_buf);
735*635a8641SAndroid Build Coastguard Worker #else
736*635a8641SAndroid Build Coastguard Worker #error "Unsupported architecture"
737*635a8641SAndroid Build Coastguard Worker #endif
738*635a8641SAndroid Build Coastguard Worker   return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
739*635a8641SAndroid Build Coastguard Worker }
740*635a8641SAndroid Build Coastguard Worker 
741*635a8641SAndroid Build Coastguard Worker }  // anonymous namespace
742*635a8641SAndroid Build Coastguard Worker 
ForkWithFlags(unsigned long flags,pid_t * ptid,pid_t * ctid)743*635a8641SAndroid Build Coastguard Worker pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
744*635a8641SAndroid Build Coastguard Worker   const bool clone_tls_used = flags & CLONE_SETTLS;
745*635a8641SAndroid Build Coastguard Worker   const bool invalid_ctid =
746*635a8641SAndroid Build Coastguard Worker       (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
747*635a8641SAndroid Build Coastguard Worker   const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
748*635a8641SAndroid Build Coastguard Worker 
749*635a8641SAndroid Build Coastguard Worker   // We do not support CLONE_VM.
750*635a8641SAndroid Build Coastguard Worker   const bool clone_vm_used = flags & CLONE_VM;
751*635a8641SAndroid Build Coastguard Worker 
752*635a8641SAndroid Build Coastguard Worker   if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
753*635a8641SAndroid Build Coastguard Worker     RAW_LOG(FATAL, "Invalid usage of ForkWithFlags");
754*635a8641SAndroid Build Coastguard Worker   }
755*635a8641SAndroid Build Coastguard Worker 
756*635a8641SAndroid Build Coastguard Worker   jmp_buf env;
757*635a8641SAndroid Build Coastguard Worker   if (setjmp(env) == 0) {
758*635a8641SAndroid Build Coastguard Worker     return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
759*635a8641SAndroid Build Coastguard Worker   }
760*635a8641SAndroid Build Coastguard Worker 
761*635a8641SAndroid Build Coastguard Worker   return 0;
762*635a8641SAndroid Build Coastguard Worker }
763*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
764*635a8641SAndroid Build Coastguard Worker 
765*635a8641SAndroid Build Coastguard Worker }  // namespace base
766