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_PUBLIC_COMMON_CHILD_PROCESS_HOST_H_
6 #define CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 
13 #include "base/files/scoped_file.h"
14 #include "base/optional.h"
15 #include "build/build_config.h"
16 #include "content/common/content_export.h"
17 #include "ipc/ipc_channel_proxy.h"
18 #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
19 #include "mojo/public/cpp/bindings/pending_receiver.h"
20 #include "services/service_manager/public/mojom/service.mojom.h"
21 
22 namespace base {
23 class FilePath;
24 }
25 
26 namespace IPC {
27 class MessageFilter;
28 }
29 
30 namespace mojo {
31 class OutgoingInvitation;
32 }
33 
34 namespace content {
35 
36 class ChildProcessHostDelegate;
37 
38 // This represents a non-browser process. This can include traditional child
39 // processes like plugins, or an embedder could even use this for long lived
40 // processes that run independent of the browser process.
41 class CONTENT_EXPORT ChildProcessHost : public IPC::Sender {
42  public:
~ChildProcessHost()43   ~ChildProcessHost() override {}
44 
45   // This is a value never returned as the unique id of any child processes of
46   // any kind, including the values returned by RenderProcessHost::GetID().
47   enum : int { kInvalidUniqueID = -1 };
48 
49   // Every ChildProcessHost provides a single primordial Mojo message pipe to
50   // the launched child process, with the other end held by the
51   // ChildProcessHost.
52   //
53   // This enum (given to |Create()|) determines how the ChildProcessHost uses
54   // the pipe.
55   enum class IpcMode {
56     // In this mode, the primordial pipe is a content.mojom.ChildProcess pipe.
57     // The ChildProcessHost is fully functional in this mode, and all new
58     // process hosts should prefer to use this mode.
59     kNormal,
60 
61     // In this mode, the primordial pipe is a legacy IPC Channel bootstrapping
62     // pipe (IPC.mojom.ChannelBootstrap). This should be used when the child
63     // process only uses legacy Chrome IPC (e.g. Chrome's NaCl processes.)
64     //
65     // In this mode, ChildProcessHost methods like |BindReceiver()| are not
66     // functional.
67     //
68     // DEPRECATED: Do not introduce new uses of this mode.
69     kLegacy,
70   };
71 
72   // Used to create a child process host. The delegate must outlive this object.
73   static std::unique_ptr<ChildProcessHost> Create(
74       ChildProcessHostDelegate* delegate,
75       IpcMode ipc_mode);
76 
77   // These flags may be passed to GetChildPath in order to alter its behavior,
78   // causing it to return a child path more suited to a specific task.
79   enum {
80     // No special behavior requested.
81     CHILD_NORMAL = 0,
82 
83 #if defined(OS_LINUX) || defined(OS_BSD)
84     // Indicates that the child execed after forking may be execced from
85     // /proc/self/exe rather than using the "real" app path. This prevents
86     // autoupdate from confusing us if it changes the file out from under us.
87     // You will generally want to set this on Linux, except when there is an
88     // override to the command line (for example, we're forking a renderer in
89     // gdb). In this case, you'd use GetChildPath to get the real executable
90     // file name, and then prepend the GDB command to the command line.
91     CHILD_ALLOW_SELF = 1 << 0,
92 #elif defined(OS_MACOSX)
93     // Note, on macOS these are not bitwise flags and each value is mutually
94     // exclusive with the others. Each one of these options should correspond
95     // to a value in //content/public/app/mac_helpers.gni.
96 
97     // Starts a child process with the macOS entitlement that allows JIT (i.e.
98     // memory that is writable and executable). In order to make use of this,
99     // memory cannot simply be allocated as read-write-execute; instead, the
100     // MAP_JIT flag must be passed to mmap() when allocating the memory region
101     // into which the writable-and-executable data are stored.
102     CHILD_RENDERER,
103 
104     // Starts a child process with the macOS entitlement that allows unsigned
105     // executable memory.
106     // TODO(https://crbug.com/985816): Change this to use MAP_JIT and the
107     // allow-jit entitlement instead.
108     CHILD_GPU,
109 
110     // Starts a child process with the macOS entitlement that ignores the
111     // library validation code signing enforcement. Library validation mandates
112     // that all executable pages be backed by a code signature that either 1)
113     // is signed by Apple, or 2) signed by the same Team ID as the main
114     // executable. Binary plug-ins that are not always signed by the same Team
115     // ID as the main binary, so this flag should be used when needing to load
116     // third-party plug-ins.
117     CHILD_PLUGIN,
118 #endif
119   };
120 
121   // Returns the pathname to be used for a child process.  If a subprocess
122   // pathname was specified on the command line, that will be used.  Otherwise,
123   // the default child process pathname will be returned.  On most platforms,
124   // this will be the same as the currently-executing process.
125   //
126   // The |flags| argument accepts one or more flags such as CHILD_ALLOW_SELF.
127   // Pass only CHILD_NORMAL if none of these special behaviors are required.
128   //
129   // On failure, returns an empty FilePath.
130   static base::FilePath GetChildPath(int flags);
131 
132   // Send the shutdown message to the child process.
133   virtual void ForceShutdown() = 0;
134 
135   // Exposes the outgoing Mojo invitation for this ChildProcessHost. The
136   // invitation can be given to ChildProcessLauncher to ensure that this
137   // ChildProcessHost's primordial Mojo IPC calls can properly communicate with
138   // the launched process.
139   //
140   // Always valid immediately after ChildProcessHost construction, but may be
141   // null if someone else has taken ownership.
142   virtual base::Optional<mojo::OutgoingInvitation>& GetMojoInvitation() = 0;
143 
144   // Creates the IPC channel over a Mojo message pipe. The pipe connection is
145   // brokered through the Service Manager like any other service connection.
146   virtual void CreateChannelMojo() = 0;
147 
148   // Returns true iff the IPC channel is currently being opened;
149   virtual bool IsChannelOpening() = 0;
150 
151   // Adds an IPC message filter.  A reference will be kept to the filter.
152   virtual void AddFilter(IPC::MessageFilter* filter) = 0;
153 
154   // Bind an interface exposed by the child process. Whether or not the
155   // interface in |receiver| can be bound depends on the process type and
156   // potentially on the Content embedder.
157   //
158   // Receivers passed to this call arrive in the child process and go through
159   // the following flow, stopping if any step decides to bind the receiver:
160   //
161   //   1. IO thread, ChildProcessImpl::BindReceiver.
162   //   2. IO thread, ContentClient::BindChildProcessInterface.
163   //   3. Main thread, ChildThreadImpl::BindReceiver (virtual).
164   virtual void BindReceiver(mojo::GenericPendingReceiver receiver) = 0;
165 
166   // Instructs the child process to run an instance of the named service.
167   virtual void RunService(
168       const std::string& service_name,
169       mojo::PendingReceiver<service_manager::mojom::Service> receiver) = 0;
170 };
171 
172 }  // namespace content
173 
174 #endif  // CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_H_
175