Home | History | Annotate | Download | only in zygote
      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 <stddef.h>
      9 
     10 #include <string>
     11 
     12 #include "base/containers/small_map.h"
     13 #include "base/files/scoped_file.h"
     14 #include "base/memory/scoped_vector.h"
     15 #include "base/posix/global_descriptors.h"
     16 #include "base/process/kill.h"
     17 #include "base/process/process.h"
     18 
     19 class Pickle;
     20 class PickleIterator;
     21 
     22 namespace content {
     23 
     24 class ZygoteForkDelegate;
     25 
     26 // This is the object which implements the zygote. The ZygoteMain function,
     27 // which is called from ChromeMain, simply constructs one of these objects and
     28 // runs it.
     29 class Zygote {
     30  public:
     31   Zygote(int sandbox_flags, ScopedVector<ZygoteForkDelegate> helpers,
     32          const std::vector<base::ProcessHandle>& extra_children,
     33          const std::vector<int>& extra_fds);
     34   ~Zygote();
     35 
     36   bool ProcessRequests();
     37 
     38  private:
     39   struct ZygoteProcessInfo {
     40     // Pid from inside the Zygote's PID namespace.
     41     base::ProcessHandle internal_pid;
     42     // Keeps track of which fork delegate helper the process was started from.
     43     ZygoteForkDelegate* started_from_helper;
     44   };
     45   typedef base::SmallMap< std::map<base::ProcessHandle, ZygoteProcessInfo> >
     46       ZygoteProcessMap;
     47 
     48   // Retrieve a ZygoteProcessInfo from the process_info_map_.
     49   // Returns true and write to process_info if |pid| can be found, return
     50   // false otherwise.
     51   bool GetProcessInfo(base::ProcessHandle pid,
     52                       ZygoteProcessInfo* process_info);
     53 
     54   // Returns true if the SUID sandbox is active.
     55   bool UsingSUIDSandbox() const;
     56 
     57   // ---------------------------------------------------------------------------
     58   // Requests from the browser...
     59 
     60   // Read and process a request from the browser. Returns true if we are in a
     61   // new process and thus need to unwind back into ChromeMain.
     62   bool HandleRequestFromBrowser(int fd);
     63 
     64   void HandleReapRequest(int fd, const Pickle& pickle, PickleIterator iter);
     65 
     66   // Get the termination status of |real_pid|. |real_pid| is the PID as it
     67   // appears outside of the sandbox.
     68   // Return true if it managed to get the termination status and return the
     69   // status in |status| and the exit code in |exit_code|.
     70   bool GetTerminationStatus(base::ProcessHandle real_pid, bool known_dead,
     71                             base::TerminationStatus* status,
     72                             int* exit_code);
     73 
     74   void HandleGetTerminationStatus(int fd,
     75                                   const Pickle& pickle,
     76                                   PickleIterator iter);
     77 
     78   // This is equivalent to fork(), except that, when using the SUID sandbox, it
     79   // returns the real PID of the child process as it appears outside the
     80   // sandbox, rather than returning the PID inside the sandbox.  The child's
     81   // real PID is determined by having it call content::SendZygoteChildPing(int)
     82   // using the |pid_oracle| descriptor.
     83   // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|,
     84   // and |uma_boundary_value| may be set if the helper wants to make a UMA
     85   // report via UMA_HISTOGRAM_ENUMERATION.
     86   int ForkWithRealPid(const std::string& process_type,
     87                       const base::GlobalDescriptors::Mapping& fd_mapping,
     88                       const std::string& channel_id,
     89                       base::ScopedFD pid_oracle,
     90                       std::string* uma_name,
     91                       int* uma_sample,
     92                       int* uma_boundary_value);
     93 
     94   // Unpacks process type and arguments from |pickle| and forks a new process.
     95   // Returns -1 on error, otherwise returns twice, returning 0 to the child
     96   // process and the child process ID to the parent process, like fork().
     97   base::ProcessId ReadArgsAndFork(const Pickle& pickle,
     98                                   PickleIterator iter,
     99                                   ScopedVector<base::ScopedFD> fds,
    100                                   std::string* uma_name,
    101                                   int* uma_sample,
    102                                   int* uma_boundary_value);
    103 
    104   // Handle a 'fork' request from the browser: this means that the browser
    105   // wishes to start a new renderer. Returns true if we are in a new process,
    106   // otherwise writes the child_pid back to the browser via |fd|. Writes a
    107   // child_pid of -1 on error.
    108   bool HandleForkRequest(int fd,
    109                          const Pickle& pickle,
    110                          PickleIterator iter,
    111                          ScopedVector<base::ScopedFD> fds);
    112 
    113   bool HandleGetSandboxStatus(int fd,
    114                               const Pickle& pickle,
    115                               PickleIterator iter);
    116 
    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_;
    122 
    123   const int sandbox_flags_;
    124   ScopedVector<ZygoteForkDelegate> helpers_;
    125 
    126   // Count of how many fork delegates for which we've invoked InitialUMA().
    127   size_t initial_uma_index_;
    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_;
    139 };
    140 
    141 }  // namespace content
    142 
    143 #endif  // CONTENT_ZYGOTE_ZYGOTE_H_
    144