1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "perfetto/ext/base/subprocess.h"
18 
19 #include <poll.h>
20 #include <signal.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <thread>
28 
29 #include "perfetto/base/build_config.h"
30 #include "perfetto/base/logging.h"
31 #include "perfetto/base/time.h"
32 #include "perfetto/ext/base/utils.h"
33 
34 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FREEBSD) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
35     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
36 #include <sys/prctl.h>
37 #endif
38 
39 // In MacOS this is not defined in any header.
40 extern "C" char** environ;
41 
42 namespace perfetto {
43 namespace base {
44 
45 namespace {
46 
47 struct ChildProcessArgs {
48   Subprocess::Args* create_args;
49   const char* exec_cmd = nullptr;
50   std::vector<char*> argv;
51   std::vector<char*> env;
52   int stdin_pipe_rd = -1;
53   int stdouterr_pipe_wr = -1;
54 };
55 
56 // Don't add any dynamic allocation in this function. This will be invoked
57 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)58 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
59 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FREEBSD) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
60     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
61   // In no case we want a child process to outlive its parent process. This is
62   // relevant for tests, so that a test failure/crash doesn't leave child
63   // processes around that get reparented to init.
64   prctl(PR_SET_PDEATHSIG, SIGKILL);
65 #endif
66 
67   auto die = [args](const char* err) __attribute__((noreturn)) {
68     base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
69     base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
70     // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
71     // "In particular, the value 128 is used to indicate failure to execute
72     // another program in a subprocess. This convention is not universally
73     // obeyed, but it is a good idea to follow it in your programs."
74     _exit(128);
75   };
76 
77   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
78     int flags = fcntl(fd, F_GETFD, 0);
79     if (flags < 0)
80       die("fcntl(F_GETFD) failed");
81     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
82     if (fcntl(fd, F_SETFD, flags) < 0)
83       die("fcntl(F_SETFD) failed");
84   };
85 
86   if (getppid() == 1)
87     die("terminating because parent process died");
88 
89   if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
90     die("Failed to dup2(STDIN)");
91   close(args->stdin_pipe_rd);
92 
93   switch (args->create_args->stdout_mode) {
94     case Subprocess::kInherit:
95       break;
96     case Subprocess::kDevNull: {
97       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
98         die("Failed to dup2(STDOUT)");
99       break;
100     }
101     case Subprocess::kBuffer:
102       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
103         die("Failed to dup2(STDOUT)");
104       break;
105   }
106 
107   switch (args->create_args->stderr_mode) {
108     case Subprocess::kInherit:
109       break;
110     case Subprocess::kDevNull: {
111       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
112         die("Failed to dup2(STDERR)");
113       break;
114     }
115     case Subprocess::kBuffer:
116       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
117         die("Failed to dup2(STDERR)");
118       break;
119   }
120 
121   // Close all FDs % stdin/out/err and the ones that the client explicitly
122   // asked to retain. The reason for this is twofold:
123   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
124   //    that didn't get marked as O_CLOEXEC by accident.
125   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
126   //    that would prevent the parent process to receive EOFs (tests usually use
127   //    pipes as a synchronization mechanism between subprocesses).
128   const auto& preserve_fds = args->create_args->preserve_fds;
129   for (int i = 0; i < 512; i++) {
130     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
131         i != args->stdouterr_pipe_wr &&
132         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
133       close(i);
134     }
135   }
136 
137   // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
138   // to be preserved after the exec().
139   set_fd_close_on_exec(STDIN_FILENO, false);
140   set_fd_close_on_exec(STDOUT_FILENO, false);
141   set_fd_close_on_exec(STDERR_FILENO, false);
142 
143   // If the caller specified a std::function entrypoint, run that first.
144   if (args->create_args->entrypoint_for_testing)
145     args->create_args->entrypoint_for_testing();
146 
147   // If the caller specified only an entrypoint, without any args, exit now.
148   // Otherwise proceed with the exec() below.
149   if (!args->exec_cmd)
150     _exit(0);
151 
152   // If |args[0]| is a path use execv() (which takes a path), othewise use
153   // exevp(), which uses the shell and follows PATH.
154   if (strchr(args->exec_cmd, '/')) {
155     char** env = args->env.empty() ? environ : args->env.data();
156     execve(args->exec_cmd, args->argv.data(), env);
157   } else {
158     // There is no execvpe() on Mac.
159     if (!args->env.empty())
160       die("A full path is required for |exec_cmd| when setting |env|");
161     execvp(args->exec_cmd, args->argv.data());
162   }
163 
164   // Reached only if execv fails.
165   die("execve() failed");
166 }
167 
168 }  // namespace
169 
Subprocess(std::initializer_list<std::string> _args)170 Subprocess::Subprocess(std::initializer_list<std::string> _args)
171     : args(_args) {}
172 
173 Subprocess::Subprocess(Subprocess&&) = default;
174 Subprocess& Subprocess::operator=(Subprocess&&) = default;
175 
~Subprocess()176 Subprocess::~Subprocess() {
177   if (status_ == kRunning)
178     KillAndWaitForTermination();
179   PERFETTO_CHECK(!waitpid_thread_.joinable());
180 }
181 
Start()182 void Subprocess::Start() {
183   ChildProcessArgs proc_args;
184   proc_args.create_args = &args;
185 
186   // Setup argv.
187   if (!args.exec_cmd.empty()) {
188     proc_args.exec_cmd = args.exec_cmd[0].c_str();
189     for (const std::string& arg : args.exec_cmd)
190       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
191     proc_args.argv.push_back(nullptr);
192 
193     if (!args.argv0_override.empty())
194       proc_args.argv[0] = const_cast<char*>(args.argv0_override.c_str());
195   }
196 
197   // Setup env.
198   if (!args.env.empty()) {
199     for (const std::string& str : args.env)
200       proc_args.env.push_back(const_cast<char*>(str.c_str()));
201     proc_args.env.push_back(nullptr);
202   }
203 
204   // Setup the pipes for stdin/err redirection.
205   stdin_pipe_ = base::Pipe::Create(base::Pipe::kWrNonBlock);
206   proc_args.stdin_pipe_rd = *stdin_pipe_.rd;
207   stdouterr_pipe_ = base::Pipe::Create(base::Pipe::kRdNonBlock);
208   proc_args.stdouterr_pipe_wr = *stdouterr_pipe_.wr;
209 
210   // Spawn the child process that will exec().
211   pid_ = fork();
212   PERFETTO_CHECK(pid_ >= 0);
213   if (pid_ == 0) {
214     // Close the parent-ends of the pipes.
215     stdin_pipe_.wr.reset();
216     stdouterr_pipe_.rd.reset();
217     ChildProcess(&proc_args);
218     // ChildProcess() doesn't return, not even in case of failures.
219     PERFETTO_FATAL("not reached");
220   }
221 
222   status_ = kRunning;
223 
224   // Close the child-end of the pipes.
225   // Deliberately NOT closing the stdin_pipe_.rd. This is to avoid crashing
226   // with a SIGPIPE if the process exits without consuming its stdin, while
227   // the parent tries to write() on the other end of the stdin pipe.
228   stdouterr_pipe_.wr.reset();
229 
230   // Spawn a thread that is blocked on waitpid() and writes the termination
231   // status onto a pipe. The problem here is that waipid() doesn't have a
232   // timeout option and can't be passed to poll(). The alternative would be
233   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
234   // problems than what they solve.
235   exit_status_pipe_ = base::Pipe::Create(base::Pipe::kRdNonBlock);
236 
237   // Both ends of the pipe are closed after the thread.join().
238   int pid = pid_;
239   int exit_status_pipe_wr = exit_status_pipe_.wr.release();
240   waitpid_thread_ = std::thread([pid, exit_status_pipe_wr] {
241     int pid_stat = -1;
242     int wait_res = PERFETTO_EINTR(waitpid(pid, &pid_stat, 0));
243     PERFETTO_CHECK(wait_res == pid);
244     base::ignore_result(PERFETTO_EINTR(
245         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
246     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
247   });
248 }
249 
Poll()250 Subprocess::Status Subprocess::Poll() {
251   if (status_ != kRunning)
252     return status_;  // Nothing to poll.
253   while (PollInternal(0 /* don't block*/)) {
254   }
255   return status_;
256 }
257 
258 // |timeout_ms| semantic:
259 //   -1: Block indefinitely.
260 //    0: Don't block, return immediately.
261 //   >0: Block for at most X ms.
262 // Returns:
263 //  True: Read at least one fd (so there might be more queued).
264 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)265 bool Subprocess::PollInternal(int poll_timeout_ms) {
266   struct pollfd fds[3]{};
267   size_t num_fds = 0;
268   if (exit_status_pipe_.rd) {
269     fds[num_fds].fd = *exit_status_pipe_.rd;
270     fds[num_fds].events = POLLIN;
271     num_fds++;
272   }
273   if (stdouterr_pipe_.rd) {
274     fds[num_fds].fd = *stdouterr_pipe_.rd;
275     fds[num_fds].events = POLLIN;
276     num_fds++;
277   }
278   if (stdin_pipe_.wr) {
279     fds[num_fds].fd = *stdin_pipe_.wr;
280     fds[num_fds].events = POLLOUT;
281     num_fds++;
282   }
283 
284   if (num_fds == 0)
285     return false;
286 
287   auto nfds = static_cast<nfds_t>(num_fds);
288   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
289   PERFETTO_CHECK(poll_res >= 0);
290 
291   TryReadStdoutAndErr();
292   TryPushStdin();
293   TryReadExitStatus();
294 
295   return poll_res > 0;
296 }
297 
Wait(int timeout_ms)298 bool Subprocess::Wait(int timeout_ms) {
299   PERFETTO_CHECK(status_ != kNotStarted);
300 
301   // Break out of the loop only after both conditions are satisfied:
302   // - All stdout/stderr data has been read (if kBuffer).
303   // - The process exited.
304   // Note that the two events can happen arbitrary order. After the process
305   // exits, there might be still data in the pipe buffer, which we want to
306   // read fully.
307   //
308   // Instead, don't wait on the stdin to be fully written. The child process
309   // might exit prematurely (or crash). If that happens, we can end up in a
310   // state where the write(stdin_pipe_.wr) will never unblock.
311 
312   const int64_t t_start = base::GetWallTimeMs().count();
313   while (exit_status_pipe_.rd || stdouterr_pipe_.rd) {
314     int poll_timeout_ms = -1;  // Block until a FD is ready.
315     if (timeout_ms > 0) {
316       const int64_t now = GetWallTimeMs().count();
317       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
318       if (poll_timeout_ms <= 0)
319         return false;
320     }
321     PollInternal(poll_timeout_ms);
322   }  // while(...)
323   return true;
324 }
325 
Call(int timeout_ms)326 bool Subprocess::Call(int timeout_ms) {
327   PERFETTO_CHECK(status_ == kNotStarted);
328   Start();
329 
330   if (!Wait(timeout_ms)) {
331     KillAndWaitForTermination();
332     // TryReadExitStatus must have joined the thread.
333     PERFETTO_DCHECK(!waitpid_thread_.joinable());
334   }
335   PERFETTO_DCHECK(status_ != kRunning);
336   return status_ == kExited && returncode_ == 0;
337 }
338 
TryReadExitStatus()339 void Subprocess::TryReadExitStatus() {
340   if (!exit_status_pipe_.rd)
341     return;
342 
343   int pid_stat = -1;
344   int64_t rsize =
345       PERFETTO_EINTR(read(*exit_status_pipe_.rd, &pid_stat, sizeof(pid_stat)));
346   if (rsize < 0 && errno == EAGAIN)
347     return;
348 
349   if (rsize > 0) {
350     PERFETTO_CHECK(rsize == sizeof(pid_stat));
351   } else if (rsize < 0) {
352     PERFETTO_PLOG("Subprocess read(exit_status_pipe_) failed");
353   }
354   waitpid_thread_.join();
355   exit_status_pipe_.rd.reset();
356 
357   if (WIFEXITED(pid_stat)) {
358     returncode_ = WEXITSTATUS(pid_stat);
359     status_ = kExited;
360   } else if (WIFSIGNALED(pid_stat)) {
361     returncode_ = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
362     status_ = kKilledBySignal;
363   } else {
364     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
365   }
366 }
367 
368 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()369 void Subprocess::TryPushStdin() {
370   if (!stdin_pipe_.wr)
371     return;
372 
373   PERFETTO_DCHECK(args.input.empty() || input_written_ < args.input.size());
374   if (args.input.size()) {
375     int64_t wsize =
376         PERFETTO_EINTR(write(*stdin_pipe_.wr, &args.input[input_written_],
377                              args.input.size() - input_written_));
378     if (wsize < 0 && errno == EAGAIN)
379       return;
380 
381     if (wsize >= 0) {
382       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
383       // Just ignore it.
384       input_written_ += static_cast<size_t>(wsize);
385     } else {
386       PERFETTO_PLOG("Subprocess write(stdin) failed");
387       stdin_pipe_.wr.reset();
388     }
389   }
390   PERFETTO_DCHECK(input_written_ <= args.input.size());
391   if (input_written_ == args.input.size())
392     stdin_pipe_.wr.reset();  // Close stdin.
393 }
394 
TryReadStdoutAndErr()395 void Subprocess::TryReadStdoutAndErr() {
396   if (!stdouterr_pipe_.rd)
397     return;
398   char buf[4096];
399   int64_t rsize = PERFETTO_EINTR(read(*stdouterr_pipe_.rd, buf, sizeof(buf)));
400   if (rsize < 0 && errno == EAGAIN)
401     return;
402 
403   if (rsize > 0) {
404     output_.append(buf, static_cast<size_t>(rsize));
405   } else if (rsize == 0 /* EOF */) {
406     stdouterr_pipe_.rd.reset();
407   } else {
408     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
409     stdouterr_pipe_.rd.reset();
410   }
411 }
412 
KillAndWaitForTermination()413 void Subprocess::KillAndWaitForTermination() {
414   kill(pid_, SIGKILL);
415   Wait();
416 }
417 
GetCmdString() const418 std::string Subprocess::Args::GetCmdString() const {
419   std::string str;
420   for (size_t i = 0; i < exec_cmd.size(); i++) {
421     str += i > 0 ? " \"" : "";
422     str += exec_cmd[i];
423     str += i > 0 ? "\"" : "";
424   }
425   return str;
426 }
427 
428 }  // namespace base
429 }  // namespace perfetto
430