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 CONTENT_ZYGOTE_ZYGOTE_H_ 6 #define CONTENT_ZYGOTE_ZYGOTE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/containers/small_map.h" 12 #include "base/posix/global_descriptors.h" 13 #include "base/process/kill.h" 14 #include "base/process/process.h" 15 16 class Pickle; 17 class PickleIterator; 18 19 namespace content { 20 21 class ZygoteForkDelegate; 22 23 // This is the object which implements the zygote. The ZygoteMain function, 24 // which is called from ChromeMain, simply constructs one of these objects and 25 // runs it. 26 class Zygote { 27 public: 28 Zygote(int sandbox_flags, 29 ZygoteForkDelegate* helper); 30 ~Zygote(); 31 32 bool ProcessRequests(); 33 34 private: 35 struct ZygoteProcessInfo { 36 // Pid from inside the Zygote's PID namespace. 37 base::ProcessHandle internal_pid; 38 // Keeps track of whether or not a process was started from a fork 39 // delegate helper. 40 bool started_from_helper; 41 }; 42 typedef base::SmallMap< std::map<base::ProcessHandle, ZygoteProcessInfo> > 43 ZygoteProcessMap; 44 45 // Retrieve a ZygoteProcessInfo from the process_info_map_. 46 // Returns true and write to process_info if |pid| can be found, return 47 // false otherwise. 48 bool GetProcessInfo(base::ProcessHandle pid, 49 ZygoteProcessInfo* process_info); 50 51 // Returns true if the SUID sandbox is active. 52 bool UsingSUIDSandbox() const; 53 54 // --------------------------------------------------------------------------- 55 // Requests from the browser... 56 57 // Read and process a request from the browser. Returns true if we are in a 58 // new process and thus need to unwind back into ChromeMain. 59 bool HandleRequestFromBrowser(int fd); 60 61 void HandleReapRequest(int fd, const Pickle& pickle, PickleIterator iter); 62 63 // Get the termination status of |real_pid|. |real_pid| is the PID as it 64 // appears outside of the sandbox. 65 // Return true if it managed to get the termination status and return the 66 // status in |status| and the exit code in |exit_code|. 67 bool GetTerminationStatus(base::ProcessHandle real_pid, bool known_dead, 68 base::TerminationStatus* status, 69 int* exit_code); 70 71 void HandleGetTerminationStatus(int fd, 72 const Pickle& pickle, 73 PickleIterator iter); 74 75 // This is equivalent to fork(), except that, when using the SUID sandbox, it 76 // returns the real PID of the child process as it appears outside the 77 // sandbox, rather than returning the PID inside the sandbox. Optionally, it 78 // fills in uma_name et al with a report the helper wants to make via 79 // UMA_HISTOGRAM_ENUMERATION. 80 int ForkWithRealPid(const std::string& process_type, 81 const base::GlobalDescriptors::Mapping& fd_mapping, 82 const std::string& channel_switch, 83 std::string* uma_name, 84 int* uma_sample, 85 int* uma_boundary_value); 86 87 // Unpacks process type and arguments from |pickle| and forks a new process. 88 // Returns -1 on error, otherwise returns twice, returning 0 to the child 89 // process and the child process ID to the parent process, like fork(). 90 base::ProcessId ReadArgsAndFork(const Pickle& pickle, 91 PickleIterator iter, 92 std::vector<int>& fds, 93 std::string* uma_name, 94 int* uma_sample, 95 int* uma_boundary_value); 96 97 // Handle a 'fork' request from the browser: this means that the browser 98 // wishes to start a new renderer. Returns true if we are in a new process, 99 // otherwise writes the child_pid back to the browser via |fd|. Writes a 100 // child_pid of -1 on error. 101 bool HandleForkRequest(int fd, 102 const Pickle& pickle, 103 PickleIterator iter, 104 std::vector<int>& fds); 105 106 bool HandleGetSandboxStatus(int fd, 107 const Pickle& pickle, 108 PickleIterator iter); 109 110 // The Zygote needs to keep some information about each process. Most 111 // notably what the PID of the process is inside the PID namespace of 112 // the Zygote and whether or not a process was started by the 113 // ZygoteForkDelegate helper. 114 ZygoteProcessMap process_info_map_; 115 116 const int sandbox_flags_; 117 ZygoteForkDelegate* helper_; 118 119 // These might be set by helper_->InitialUMA. They supply a UMA enumeration 120 // sample we should report on the first fork. 121 std::string initial_uma_name_; 122 int initial_uma_sample_; 123 int initial_uma_boundary_value_; 124 }; 125 126 } // namespace content 127 128 #endif // CONTENT_ZYGOTE_ZYGOTE_H_ 129