[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 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 | |
tfarina | bccc34c7 | 2015-02-27 21:32:15 | [diff] [blame] | 5 | #ifndef CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ |
| 6 | #define CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 7 | |
[email protected] | 54ad01a | 2014-05-11 01:17:47 | [diff] [blame] | 8 | #include <stddef.h> |
| 9 | |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 10 | #include <string> |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 11 | |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 12 | #include "base/containers/small_map.h" |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 13 | #include "base/files/scoped_file.h" |
| 14 | #include "base/memory/scoped_vector.h" |
[email protected] | 9e5a0a6 | 2013-10-11 19:39:41 | [diff] [blame] | 15 | #include "base/posix/global_descriptors.h" |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 16 | #include "base/process/kill.h" |
[email protected] | 54724e2 | 2013-07-25 13:02:15 | [diff] [blame] | 17 | #include "base/process/process.h" |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 18 | |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 19 | namespace base { |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 20 | class Pickle; |
| 21 | class PickleIterator; |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 22 | } |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 23 | |
| 24 | namespace content { |
| 25 | |
| 26 | class ZygoteForkDelegate; |
| 27 | |
| 28 | // This is the object which implements the zygote. The ZygoteMain function, |
| 29 | // which is called from ChromeMain, simply constructs one of these objects and |
| 30 | // runs it. |
| 31 | class Zygote { |
| 32 | public: |
[email protected] | 655abd52 | 2014-06-02 15:23:43 | [diff] [blame] | 33 | Zygote(int sandbox_flags, ScopedVector<ZygoteForkDelegate> helpers, |
| 34 | const std::vector<base::ProcessHandle>& extra_children, |
| 35 | const std::vector<int>& extra_fds); |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 36 | ~Zygote(); |
| 37 | |
| 38 | bool ProcessRequests(); |
| 39 | |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 40 | private: |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 41 | struct ZygoteProcessInfo { |
| 42 | // Pid from inside the Zygote's PID namespace. |
| 43 | base::ProcessHandle internal_pid; |
[email protected] | 54ad01a | 2014-05-11 01:17:47 | [diff] [blame] | 44 | // Keeps track of which fork delegate helper the process was started from. |
| 45 | ZygoteForkDelegate* started_from_helper; |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 46 | }; |
| 47 | typedef base::SmallMap< std::map<base::ProcessHandle, ZygoteProcessInfo> > |
| 48 | ZygoteProcessMap; |
| 49 | |
[email protected] | 500d24e | 2013-08-21 19:55:32 | [diff] [blame] | 50 | // Retrieve a ZygoteProcessInfo from the process_info_map_. |
| 51 | // Returns true and write to process_info if |pid| can be found, return |
| 52 | // false otherwise. |
| 53 | bool GetProcessInfo(base::ProcessHandle pid, |
| 54 | ZygoteProcessInfo* process_info); |
| 55 | |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 56 | // Returns true if the SUID sandbox is active. |
| 57 | bool UsingSUIDSandbox() const; |
jln | 151ebd7 | 2015-02-19 02:21:55 | [diff] [blame] | 58 | // Returns true if the NS sandbox is active. |
| 59 | bool UsingNSSandbox() const; |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 60 | |
| 61 | // --------------------------------------------------------------------------- |
| 62 | // Requests from the browser... |
| 63 | |
| 64 | // Read and process a request from the browser. Returns true if we are in a |
| 65 | // new process and thus need to unwind back into ChromeMain. |
| 66 | bool HandleRequestFromBrowser(int fd); |
| 67 | |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 68 | void HandleReapRequest(int fd, base::PickleIterator iter); |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 69 | |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 70 | // Get the termination status of |real_pid|. |real_pid| is the PID as it |
| 71 | // appears outside of the sandbox. |
| 72 | // Return true if it managed to get the termination status and return the |
| 73 | // status in |status| and the exit code in |exit_code|. |
| 74 | bool GetTerminationStatus(base::ProcessHandle real_pid, bool known_dead, |
| 75 | base::TerminationStatus* status, |
| 76 | int* exit_code); |
| 77 | |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 78 | void HandleGetTerminationStatus(int fd, |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 79 | base::PickleIterator iter); |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 80 | |
| 81 | // This is equivalent to fork(), except that, when using the SUID sandbox, it |
| 82 | // returns the real PID of the child process as it appears outside the |
[email protected] | 53cbbe25 | 2014-05-08 01:26:28 | [diff] [blame] | 83 | // sandbox, rather than returning the PID inside the sandbox. The child's |
| 84 | // real PID is determined by having it call content::SendZygoteChildPing(int) |
| 85 | // using the |pid_oracle| descriptor. |
| 86 | // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|, |
| 87 | // and |uma_boundary_value| may be set if the helper wants to make a UMA |
| 88 | // report via UMA_HISTOGRAM_ENUMERATION. |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 89 | int ForkWithRealPid(const std::string& process_type, |
[email protected] | 9e5a0a6 | 2013-10-11 19:39:41 | [diff] [blame] | 90 | const base::GlobalDescriptors::Mapping& fd_mapping, |
[email protected] | 3a16124 | 2014-04-18 00:07:33 | [diff] [blame] | 91 | const std::string& channel_id, |
[email protected] | 53cbbe25 | 2014-05-08 01:26:28 | [diff] [blame] | 92 | base::ScopedFD pid_oracle, |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 93 | std::string* uma_name, |
| 94 | int* uma_sample, |
| 95 | int* uma_boundary_value); |
| 96 | |
avi | 48fc13b | 2014-12-28 23:31:48 | [diff] [blame] | 97 | // Unpacks process type and arguments from |iter| and forks a new process. |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 98 | // Returns -1 on error, otherwise returns twice, returning 0 to the child |
| 99 | // process and the child process ID to the parent process, like fork(). |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 100 | base::ProcessId ReadArgsAndFork(base::PickleIterator iter, |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 101 | ScopedVector<base::ScopedFD> fds, |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 102 | std::string* uma_name, |
| 103 | int* uma_sample, |
| 104 | int* uma_boundary_value); |
| 105 | |
| 106 | // Handle a 'fork' request from the browser: this means that the browser |
| 107 | // wishes to start a new renderer. Returns true if we are in a new process, |
| 108 | // otherwise writes the child_pid back to the browser via |fd|. Writes a |
| 109 | // child_pid of -1 on error. |
| 110 | bool HandleForkRequest(int fd, |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 111 | base::PickleIterator iter, |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 112 | ScopedVector<base::ScopedFD> fds); |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 113 | |
| 114 | bool HandleGetSandboxStatus(int fd, |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame^] | 115 | base::PickleIterator iter); |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 116 | |
[email protected] | 9f2bdf12 | 2013-08-21 02:59:34 | [diff] [blame] | 117 | // The Zygote needs to keep some information about each process. Most |
| 118 | // notably what the PID of the process is inside the PID namespace of |
| 119 | // the Zygote and whether or not a process was started by the |
| 120 | // ZygoteForkDelegate helper. |
| 121 | ZygoteProcessMap process_info_map_; |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 122 | |
| 123 | const int sandbox_flags_; |
[email protected] | 54ad01a | 2014-05-11 01:17:47 | [diff] [blame] | 124 | ScopedVector<ZygoteForkDelegate> helpers_; |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 125 | |
[email protected] | 54ad01a | 2014-05-11 01:17:47 | [diff] [blame] | 126 | // Count of how many fork delegates for which we've invoked InitialUMA(). |
| 127 | size_t initial_uma_index_; |
[email protected] | 655abd52 | 2014-06-02 15:23:43 | [diff] [blame] | 128 | |
| 129 | // This vector contains the PIDs of any child processes which have been |
| 130 | // created prior to the construction of the Zygote object, and must be reaped |
| 131 | // before the Zygote exits. The Zygote will perform a blocking wait on these |
| 132 | // children, so they must be guaranteed to be exiting by the time the Zygote |
| 133 | // exits. |
| 134 | std::vector<base::ProcessHandle> extra_children_; |
| 135 | |
| 136 | // This vector contains the FDs that must be closed before reaping the extra |
| 137 | // children. |
| 138 | std::vector<int> extra_fds_; |
[email protected] | b75346c | 2012-05-13 03:48:38 | [diff] [blame] | 139 | }; |
| 140 | |
| 141 | } // namespace content |
| 142 | |
tfarina | bccc34c7 | 2015-02-27 21:32:15 | [diff] [blame] | 143 | #endif // CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ |