Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/ipc/GeckoChildProcessHost.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
8
#define __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
9
10
#include "base/file_path.h"
11
#include "base/process_util.h"
12
#include "base/waitable_event.h"
13
#include "chrome/common/child_process_host.h"
14
15
#include "mozilla/DebugOnly.h"
16
#include "mozilla/ipc/FileDescriptor.h"
17
#include "mozilla/Monitor.h"
18
#include "mozilla/StaticPtr.h"
19
#include "mozilla/UniquePtr.h"
20
21
#include "nsCOMPtr.h"
22
#include "nsXULAppAPI.h"        // for GeckoProcessType
23
#include "nsString.h"
24
25
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
26
#include "sandboxBroker.h"
27
#endif
28
29
namespace mozilla {
30
namespace ipc {
31
32
class GeckoChildProcessHost : public ChildProcessHost
33
{
34
protected:
35
  typedef mozilla::Monitor Monitor;
36
  typedef std::vector<std::string> StringVector;
37
38
public:
39
  typedef base::ProcessHandle ProcessHandle;
40
41
  explicit GeckoChildProcessHost(GeckoProcessType aProcessType,
42
                                 bool aIsFileContent = false);
43
44
  ~GeckoChildProcessHost();
45
46
  static uint32_t GetUniqueID();
47
48
  // Does not block.  The IPC channel may not be initialized yet, and
49
  // the child process may or may not have been created when this
50
  // method returns.
51
  bool AsyncLaunch(StringVector aExtraOpts=StringVector());
52
53
  virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0);
54
55
  // Block until the IPC channel for our subprocess is initialized and
56
  // the OS process is created.  The subprocess may or may not have
57
  // connected back to us when this method returns.
58
  //
59
  // NB: on POSIX, this method is relatively cheap, and doesn't
60
  // require disk IO.  On win32 however, it requires at least the
61
  // analogue of stat().  This difference induces a semantic
62
  // difference in this method: on POSIX, when we return, we know the
63
  // subprocess has been created, but we don't know whether its
64
  // executable image can be loaded.  On win32, we do know that when
65
  // we return.  But we don't know if dynamic linking succeeded on
66
  // either platform.
67
  bool LaunchAndWaitForProcessHandle(StringVector aExtraOpts=StringVector());
68
69
  // Block until the child process has been created and it connects to
70
  // the IPC channel, meaning it's fully initialized.  (Or until an
71
  // error occurs.)
72
  bool SyncLaunch(StringVector aExtraOpts=StringVector(),
73
                  int32_t timeoutMs=0);
74
75
  virtual void OnProcessHandleReady(ProcessHandle aProcessHandle);
76
  virtual void OnProcessLaunchError();
77
  virtual void OnChannelConnected(int32_t peer_pid) override;
78
  virtual void OnMessageReceived(IPC::Message&& aMsg) override;
79
  virtual void OnChannelError() override;
80
  virtual void GetQueuedMessages(std::queue<IPC::Message>& queue) override;
81
82
  virtual void InitializeChannel();
83
84
  virtual bool CanShutdown() override { return true; }
85
86
  IPC::Channel* GetChannel() {
87
    return channelp();
88
  }
89
90
  // Returns a "borrowed" handle to the child process - the handle returned
91
  // by this function must not be closed by the caller.
92
0
  ProcessHandle GetChildProcessHandle() {
93
0
    return mChildProcessHandle;
94
0
  }
95
96
0
  GeckoProcessType GetProcessType() {
97
0
    return mProcessType;
98
0
  }
99
100
#ifdef XP_MACOSX
101
  task_t GetChildTask() {
102
    return mChildTask;
103
  }
104
#endif
105
106
#ifdef XP_WIN
107
  void AddHandleToShare(HANDLE aHandle) {
108
    mLaunchOptions->handles_to_inherit.push_back(aHandle);
109
  }
110
#else
111
0
  void AddFdToRemap(int aSrcFd, int aDstFd) {
112
0
    mLaunchOptions->fds_to_remap.push_back(std::make_pair(aSrcFd, aDstFd));
113
0
  }
114
#endif
115
116
  /**
117
   * Must run on the IO thread.  Cause the OS process to exit and
118
   * ensure its OS resources are cleaned up.
119
   */
120
  void Join();
121
122
  // For bug 943174: Skip the EnsureProcessTerminated call in the destructor.
123
  void SetAlreadyDead();
124
125
3
  static void EnableSameExecutableForContentProc() { sRunSelfAsContentProc = true; }
126
127
protected:
128
  GeckoProcessType mProcessType;
129
  bool mIsFileContent;
130
  Monitor mMonitor;
131
  FilePath mProcessPath;
132
  // GeckoChildProcessHost holds the launch options so they can be set
133
  // up on the main thread using main-thread-only APIs like prefs, and
134
  // then used for the actual launch on another thread.  This pointer
135
  // is set to null to free the options after the child is launched.
136
  UniquePtr<base::LaunchOptions> mLaunchOptions;
137
138
  // This value must be accessed while holding mMonitor.
139
  enum {
140
    // This object has been constructed, but the OS process has not
141
    // yet.
142
    CREATING_CHANNEL = 0,
143
    // The IPC channel for our subprocess has been created, but the OS
144
    // process has still not been created.
145
    CHANNEL_INITIALIZED,
146
    // The OS process has been created, but it hasn't yet connected to
147
    // our IPC channel.
148
    PROCESS_CREATED,
149
    // The process is launched and connected to our IPC channel.  All
150
    // is well.
151
    PROCESS_CONNECTED,
152
    PROCESS_ERROR
153
  } mProcessState;
154
155
  static int32_t mChildCounter;
156
157
  void PrepareLaunch();
158
159
#ifdef XP_WIN
160
  void InitWindowsGroupID();
161
  nsString mGroupId;
162
163
#ifdef MOZ_SANDBOX
164
  SandboxBroker mSandboxBroker;
165
  std::vector<std::wstring> mAllowedFilesRead;
166
  bool mEnableSandboxLogging;
167
  int32_t mSandboxLevel;
168
#endif
169
#endif // XP_WIN
170
171
  ProcessHandle mChildProcessHandle;
172
#if defined(OS_MACOSX)
173
  task_t mChildTask;
174
#endif
175
176
  bool OpenPrivilegedHandle(base::ProcessId aPid);
177
178
private:
179
  DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
180
181
  // Does the actual work for AsyncLaunch, on the IO thread.
182
  // (TODO, bug 1487287: move this to its own thread(s).)
183
  bool PerformAsyncLaunch(StringVector aExtraOpts);
184
185
  // Also called on the I/O thread; creates channel, launches, and
186
  // consolidates error handling.
187
  bool RunPerformAsyncLaunch(StringVector aExtraOpts);
188
189
  enum class BinaryPathType {
190
    Self,
191
    PluginContainer
192
  };
193
194
  static BinaryPathType GetPathToBinary(FilePath& exePath, GeckoProcessType processType);
195
196
  // The buffer is passed to preserve its lifetime until we are done
197
  // with launching the sub-process.
198
  void GetChildLogName(const char* origLogName, nsACString &buffer);
199
200
  // In between launching the subprocess and handing off its IPC
201
  // channel, there's a small window of time in which *we* might still
202
  // be the channel listener, and receive messages.  That's bad
203
  // because we have no idea what to do with those messages.  So queue
204
  // them here until we hand off the eventual listener.
205
  //
206
  // FIXME/cjones: this strongly indicates bad design.  Shame on us.
207
  std::queue<IPC::Message> mQueue;
208
209
  // Set this up before we're called from a different thread.
210
#if defined(OS_LINUX)
211
  nsCString mTmpDirName;
212
#endif
213
214
  static uint32_t sNextUniqueID;
215
216
  static bool sRunSelfAsContentProc;
217
218
#if defined(MOZ_WIDGET_ANDROID)
219
  void LaunchAndroidService(const char* type,
220
                            const std::vector<std::string>& argv,
221
                            const base::file_handle_mapping_vector& fds_to_remap,
222
                            ProcessHandle* process_handle);
223
#endif // defined(MOZ_WIDGET_ANDROID)
224
225
};
226
227
} /* namespace ipc */
228
} /* namespace mozilla */
229
230
#endif /* __IPC_GLUE_GECKOCHILDPROCESSHOST_H__ */