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 <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