1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
6 #define SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/containers/small_map.h"
15 #include "base/files/scoped_file.h"
16 #include "base/posix/global_descriptors.h"
17 #include "base/process/kill.h"
18 #include "base/process/process.h"
19 #include "base/process/process_handle.h"
20 #include "base/time/time.h"
21 
22 namespace base {
23 class PickleIterator;
24 }
25 
26 namespace service_manager {
27 
28 class ZygoteForkDelegate;
29 
30 // This is the object which implements the zygote. The ZygoteMain function,
31 // which is called from ChromeMain, simply constructs one of these objects and
32 // runs it.
33 class Zygote {
34  public:
35   Zygote(int sandbox_flags,
36          std::vector<std::unique_ptr<ZygoteForkDelegate>> helpers,
37          const base::GlobalDescriptors::Descriptor& ipc_backchannel);
38   ~Zygote();
39 
40   bool ProcessRequests();
41 
42  private:
43   struct ZygoteProcessInfo {
44     // Pid from inside the Zygote's PID namespace.
45     base::ProcessHandle internal_pid;
46     // Keeps track of which fork delegate helper the process was started from.
47     ZygoteForkDelegate* started_from_helper;
48     // Records when the browser requested the zygote to reap this process.
49     base::TimeTicks time_of_reap_request;
50     // Notes whether the zygote has sent SIGKILL to this process.
51     bool sent_sigkill;
52   };
53   using ZygoteProcessMap =
54       base::small_map<std::map<base::ProcessHandle, ZygoteProcessInfo>>;
55 
56   // Retrieve a ZygoteProcessInfo from the process_info_map_.
57   // Returns true and write to process_info if |pid| can be found, return
58   // false otherwise.
59   bool GetProcessInfo(base::ProcessHandle pid, ZygoteProcessInfo* process_info);
60 
61   // Returns true if the SUID sandbox is active.
62   bool UsingSUIDSandbox() const;
63   // Returns true if the NS sandbox is active.
64   bool UsingNSSandbox() const;
65 
66   // ---------------------------------------------------------------------------
67   // Requests from the browser...
68 
69   // Read and process a request from the browser. Returns true if we are in a
70   // new process and thus need to unwind back into ChromeMain.
71   bool HandleRequestFromBrowser(int fd);
72 
73   void HandleReapRequest(int fd, base::PickleIterator iter);
74 
75   // Get the termination status of |real_pid|. |real_pid| is the PID as it
76   // appears outside of the sandbox.
77   // Return true if it managed to get the termination status and return the
78   // status in |status| and the exit code in |exit_code|.
79   bool GetTerminationStatus(base::ProcessHandle real_pid,
80                             bool known_dead,
81                             base::TerminationStatus* status,
82                             int* exit_code);
83 
84   void HandleGetTerminationStatus(int fd, base::PickleIterator iter);
85 
86   // This is equivalent to fork(), except that, when using the SUID sandbox, it
87   // returns the real PID of the child process as it appears outside the
88   // sandbox, rather than returning the PID inside the sandbox.  The child's
89   // real PID is determined by having it call
90   // service_manager::SendZygoteChildPing(int) using the |pid_oracle|
91   // descriptor.
92   // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|,
93   // and |uma_boundary_value| may be set if the helper wants to make a UMA
94   // report via UMA_HISTOGRAM_ENUMERATION.
95   int ForkWithRealPid(const std::string& process_type,
96                       const base::GlobalDescriptors::Mapping& fd_mapping,
97                       const std::string& channel_id,
98                       base::ScopedFD pid_oracle,
99                       std::string* uma_name,
100                       int* uma_sample,
101                       int* uma_boundary_value);
102 
103   // Unpacks process type and arguments from |iter| and forks a new process.
104   // Returns -1 on error, otherwise returns twice, returning 0 to the child
105   // process and the child process ID to the parent process, like fork().
106   base::ProcessId ReadArgsAndFork(base::PickleIterator iter,
107                                   std::vector<base::ScopedFD> fds,
108                                   std::string* uma_name,
109                                   int* uma_sample,
110                                   int* uma_boundary_value);
111 
112   // Handle a 'fork' request from the browser: this means that the browser
113   // wishes to start a new renderer. Returns true if we are in a new process,
114   // otherwise writes the child_pid back to the browser via |fd|. Writes a
115   // child_pid of -1 on error.
116   bool HandleForkRequest(int fd,
117                          base::PickleIterator iter,
118                          std::vector<base::ScopedFD> fds);
119 
120   bool HandleGetSandboxStatus(int fd, base::PickleIterator iter);
121 
122   // Attempt to reap the child process by calling waitpid, and return
123   // whether successful.  If the process has not terminated within
124   // 2 seconds of its reap request, send it SIGKILL.
125   bool ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child);
126 
127   // Attempt to reap all outstanding children in |to_reap_|.
128   void ReapChildren();
129 
130   // The Zygote needs to keep some information about each process. Most
131   // notably what the PID of the process is inside the PID namespace of
132   // the Zygote and whether or not a process was started by the
133   // ZygoteForkDelegate helper.
134   ZygoteProcessMap process_info_map_;
135 
136   const int sandbox_flags_;
137   std::vector<std::unique_ptr<ZygoteForkDelegate>> helpers_;
138 
139   // Count of how many fork delegates for which we've invoked InitialUMA().
140   size_t initial_uma_index_;
141 
142   // The vector contains the child processes that need to be reaped.
143   std::vector<ZygoteProcessInfo> to_reap_;
144 
145   // Sandbox IPC channel for renderers to invoke services from the browser. See
146   // https://chromium.googlesource.com/chromium/src/+/master/docs/linux/sandbox_ipc.md
147   base::GlobalDescriptors::Descriptor ipc_backchannel_;
148 };
149 
150 }  // namespace service_manager
151 
152 #endif  // SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
153