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