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/hash_tables.h" 12 #include "base/process/process.h" 13 14 class Pickle; 15 class PickleIterator; 16 17 namespace content { 18 19 class ZygoteForkDelegate; 20 21 // This is the object which implements the zygote. The ZygoteMain function, 22 // which is called from ChromeMain, simply constructs one of these objects and 23 // runs it. 24 class Zygote { 25 public: 26 Zygote(int sandbox_flags, 27 ZygoteForkDelegate* helper); 28 ~Zygote(); 29 30 bool ProcessRequests(); 31 32 static const int kBrowserDescriptor = 3; 33 static const int kMagicSandboxIPCDescriptor = 5; 34 35 private: 36 // Returns true if the SUID sandbox is active. 37 bool UsingSUIDSandbox() const; 38 39 // --------------------------------------------------------------------------- 40 // Requests from the browser... 41 42 // Read and process a request from the browser. Returns true if we are in a 43 // new process and thus need to unwind back into ChromeMain. 44 bool HandleRequestFromBrowser(int fd); 45 46 void HandleReapRequest(int fd, const Pickle& pickle, PickleIterator iter); 47 48 void HandleGetTerminationStatus(int fd, 49 const Pickle& pickle, 50 PickleIterator iter); 51 52 // This is equivalent to fork(), except that, when using the SUID sandbox, it 53 // returns the real PID of the child process as it appears outside the 54 // sandbox, rather than returning the PID inside the sandbox. Optionally, it 55 // fills in uma_name et al with a report the helper wants to make via 56 // UMA_HISTOGRAM_ENUMERATION. 57 int ForkWithRealPid(const std::string& process_type, 58 std::vector<int>& fds, 59 const std::string& channel_switch, 60 std::string* uma_name, 61 int* uma_sample, 62 int* uma_boundary_value); 63 64 // Unpacks process type and arguments from |pickle| and forks a new process. 65 // Returns -1 on error, otherwise returns twice, returning 0 to the child 66 // process and the child process ID to the parent process, like fork(). 67 base::ProcessId ReadArgsAndFork(const Pickle& pickle, 68 PickleIterator iter, 69 std::vector<int>& fds, 70 std::string* uma_name, 71 int* uma_sample, 72 int* uma_boundary_value); 73 74 // Handle a 'fork' request from the browser: this means that the browser 75 // wishes to start a new renderer. Returns true if we are in a new process, 76 // otherwise writes the child_pid back to the browser via |fd|. Writes a 77 // child_pid of -1 on error. 78 bool HandleForkRequest(int fd, 79 const Pickle& pickle, 80 PickleIterator iter, 81 std::vector<int>& fds); 82 83 bool HandleGetSandboxStatus(int fd, 84 const Pickle& pickle, 85 PickleIterator iter); 86 87 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs 88 // fork() returns are not the real PIDs, so we need to map the Real PIDS 89 // into the sandbox PID namespace. 90 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; 91 ProcessMap real_pids_to_sandbox_pids; 92 93 const int sandbox_flags_; 94 ZygoteForkDelegate* helper_; 95 96 // These might be set by helper_->InitialUMA. They supply a UMA enumeration 97 // sample we should report on the first fork. 98 std::string initial_uma_name_; 99 int initial_uma_sample_; 100 int initial_uma_boundary_value_; 101 }; 102 103 } // namespace content 104 105 #endif // CONTENT_ZYGOTE_ZYGOTE_H_ 106