GeckoChildProcessHost.h (11622B)
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/ipc_message.h" 14 #include "mojo/core/ports/port_ref.h" 15 16 #include "mozilla/GeckoArgs.h" 17 #include "mozilla/ipc/Endpoint.h" 18 #include "mozilla/ipc/FileDescriptor.h" 19 #include "mozilla/ipc/NodeChannel.h" 20 #include "mozilla/ipc/LaunchError.h" 21 #include "mozilla/ipc/ScopedPort.h" 22 #include "mozilla/Atomics.h" 23 #include "mozilla/LinkedList.h" 24 #include "mozilla/Monitor.h" 25 #include "mozilla/MozPromise.h" 26 #include "mozilla/RWLock.h" 27 #include "mozilla/StaticMutex.h" 28 #include "mozilla/StaticPtr.h" 29 #include "mozilla/UniquePtr.h" 30 31 #include "nsCOMPtr.h" 32 #include "nsExceptionHandler.h" 33 #include "nsXULAppAPI.h" // for GeckoProcessType 34 #include "nsString.h" 35 36 #if defined(XP_IOS) 37 # include "mozilla/ipc/ExtensionKitUtils.h" 38 #endif 39 40 #if defined(XP_WIN) && defined(MOZ_SANDBOX) 41 # include "sandboxBroker.h" 42 #endif 43 44 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) 45 # include "mozilla/Sandbox.h" 46 #endif 47 48 #if defined(MOZ_SANDBOX) 49 # include "mozilla/ipc/UtilityProcessSandboxing.h" 50 #endif 51 52 #if (defined(XP_WIN) && defined(_ARM64_)) || \ 53 (defined(XP_MACOSX) && defined(__aarch64__)) 54 # define ALLOW_GECKO_CHILD_PROCESS_ARCH 55 #endif 56 57 struct _MacSandboxInfo; 58 typedef _MacSandboxInfo MacSandboxInfo; 59 60 namespace mozilla { 61 namespace ipc { 62 63 typedef mozilla::MozPromise<base::ProcessHandle, LaunchError, false> 64 ProcessHandlePromise; 65 66 class GeckoChildProcessHost : public SupportsWeakPtr, 67 public LinkedListElement<GeckoChildProcessHost> { 68 protected: 69 typedef mozilla::Monitor Monitor; 70 typedef std::vector<std::string> StringVector; 71 72 public: 73 using ProcessId = base::ProcessId; 74 using ProcessHandle = base::ProcessHandle; 75 76 explicit GeckoChildProcessHost(GeckoProcessType aProcessType, 77 bool aIsFileContent = false); 78 79 // Causes the object to be deleted, on the I/O thread, after any 80 // pending asynchronous work (like launching) is complete. This 81 // method can be called from any thread. If called from the I/O 82 // thread itself, deletion won't happen until the event loop spins; 83 // otherwise, it could happen immediately. 84 // 85 // GeckoChildProcessHost instances must not be deleted except 86 // through this method. 87 void Destroy(); 88 89 static uint32_t GetUniqueID(); 90 91 // Call this before launching to set an environment variable for the 92 // child process. The arguments must be UTF-8. 93 void SetEnv(const char* aKey, const char* aValue); 94 95 // Does not block. The IPC channel may not be initialized yet, and 96 // the child process may or may not have been created when this 97 // method returns. 98 bool AsyncLaunch( 99 geckoargs::ChildProcessArgs aExtraOpts = geckoargs::ChildProcessArgs{}); 100 101 virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0); 102 103 // Block until the IPC channel for our subprocess is initialized and 104 // the OS process is created. The subprocess may or may not have 105 // connected back to us when this method returns. 106 // 107 // NB: on POSIX, this method is relatively cheap, and doesn't 108 // require disk IO. On win32 however, it requires at least the 109 // analogue of stat(). This difference induces a semantic 110 // difference in this method: on POSIX, when we return, we know the 111 // subprocess has been created, but we don't know whether its 112 // executable image can be loaded. On win32, we do know that when 113 // we return. But we don't know if dynamic linking succeeded on 114 // either platform. 115 bool LaunchAndWaitForProcessHandle( 116 geckoargs::ChildProcessArgs aExtraOpts = geckoargs::ChildProcessArgs()); 117 bool WaitForProcessHandle(); 118 119 // Block until the child process has been created and it connects to 120 // the IPC channel, meaning it's fully initialized. (Or until an 121 // error occurs.) 122 bool SyncLaunch( 123 geckoargs::ChildProcessArgs aExtraOpts = geckoargs::ChildProcessArgs(), 124 int32_t timeoutMs = 0); 125 126 virtual void OnChannelConnected(base::ProcessId peer_pid); 127 128 // Resolves to the process handle when it's available (see 129 // LaunchAndWaitForProcessHandle); use with AsyncLaunch. 130 RefPtr<ProcessHandlePromise> WhenProcessHandleReady(); 131 132 bool InitializeChannel(IPC::Channel::ChannelHandle* aClientHandle); 133 134 virtual bool CanShutdown() { return true; } 135 136 UntypedEndpoint TakeInitialEndpoint() { 137 return UntypedEndpoint{PrivateIPDLInterface{}, std::move(mInitialPort), 138 mInitialChannelId, EndpointProcInfo::Current(), 139 EndpointProcInfo{.mPid = GetChildProcessId(), 140 .mChildID = GetChildID()}}; 141 } 142 143 // Returns a "borrowed" handle to the child process - the handle returned 144 // by this function must not be closed by the caller. The handle is also 145 // not guaranteed to remain valid; if the caller is using it for anything 146 // more than logging or asserting non-null, it will need to deal with 147 // synchronization. 148 // 149 // Warning: the null value here is 0, not kInvalidProcessHandle. 150 ProcessHandle GetChildProcessHandle(); 151 152 // Returns the child's process ID; as for GetChildProcessHandle, there is 153 // no inherent guarantee that it will remain valid or continue to 154 // reference the same process. 155 // 156 // The null value here is also 0; this matches the result of 157 // GetProcId on a zero or (on Windows) invalid handle. 158 ProcessId GetChildProcessId(); 159 160 // Return the child's GeckoChildID. This is a unique identifier given out to 161 // each process started with `GeckoChildProcessHost` which will only ever 162 // identify this process. 163 GeckoChildID GetChildID() const { return mChildID; } 164 165 GeckoProcessType GetProcessType() { return mProcessType; } 166 167 #ifdef XP_MACOSX 168 task_t GetChildTask(); 169 #endif 170 171 #ifdef ALLOW_GECKO_CHILD_PROCESS_ARCH 172 void SetLaunchArchitecture(uint32_t aArch) { mLaunchArch = aArch; } 173 #endif 174 175 // For bug 943174: Skip the EnsureProcessTerminated call in the destructor. 176 void SetAlreadyDead(); 177 178 #if defined(MOZ_SANDBOX) && defined(XP_MACOSX) 179 // Start the sandbox from the child process. 180 static bool StartMacSandbox(int aArgc, char** aArgv, 181 std::string& aErrorMessage); 182 183 // The sandbox type that will be use when sandboxing is 184 // enabled in the derived class and FillMacSandboxInfo 185 // has not been overridden. 186 static MacSandboxType GetDefaultMacSandboxType() { 187 return MacSandboxType_Utility; 188 }; 189 190 // Must be called before the process is launched. Determines if 191 // child processes will be launched with OS_ACTIVITY_MODE set to 192 // "disabled" or not. When |mDisableOSActivityMode| is set to true, 193 // child processes will be launched with OS_ACTIVITY_MODE 194 // disabled to avoid connection attempts to diagnosticd(8) which are 195 // blocked in child processes due to sandboxing. 196 void DisableOSActivityMode(); 197 #endif // defined(MOZ_SANDBOX) && defined(XP_MACOSX) 198 typedef std::function<void(GeckoChildProcessHost*)> GeckoProcessCallback; 199 200 // Iterates over all instances and calls aCallback with each one of them. 201 // This method will lock any addition/removal of new processes 202 // so you need to make sure the callback is as fast as possible. 203 // 204 // To reiterate: the callbacks are executed synchronously. 205 static void GetAll(const GeckoProcessCallback& aCallback); 206 207 friend class BaseProcessLauncher; 208 friend class PosixProcessLauncher; 209 friend class WindowsProcessLauncher; 210 211 protected: 212 virtual ~GeckoChildProcessHost(); 213 GeckoProcessType mProcessType; 214 GeckoChildID mChildID; 215 bool mIsFileContent; 216 Monitor mMonitor; 217 FilePath mProcessPath; 218 #ifdef ALLOW_GECKO_CHILD_PROCESS_ARCH 219 // Used on platforms where we may launch a child process with a different 220 // architecture than the parent process. 221 uint32_t mLaunchArch = base::PROCESS_ARCH_INVALID; 222 #endif 223 // GeckoChildProcessHost holds the launch options so they can be set 224 // up on the main thread using main-thread-only APIs like prefs, and 225 // then used for the actual launch on another thread. This pointer 226 // is set to null to free the options after the child is launched. 227 UniquePtr<base::LaunchOptions> mLaunchOptions; 228 ScopedPort mInitialPort; 229 nsID mInitialChannelId; 230 RefPtr<NodeController> mNodeController; 231 RefPtr<NodeChannel> mNodeChannel; 232 233 // This value must be accessed while holding mMonitor. 234 enum { 235 // This object has been constructed, but the OS process has not 236 // yet. 237 CREATING_CHANNEL = 0, 238 // The IPC channel for our subprocess has been created, but the OS 239 // process has still not been created. 240 CHANNEL_INITIALIZED, 241 // The OS process has been created, but it hasn't yet connected to 242 // our IPC channel. 243 PROCESS_CREATED, 244 // The process is launched and connected to our IPC channel. All 245 // is well. 246 PROCESS_CONNECTED, 247 PROCESS_ERROR 248 } mProcessState MOZ_GUARDED_BY(mMonitor); 249 250 bool PrepareLaunch(geckoargs::ChildProcessArgs& aExtraOpts); 251 252 #ifdef XP_WIN 253 void InitWindowsGroupID(); 254 nsString mGroupId; 255 # ifdef MOZ_SANDBOX 256 UniquePtr<SandboxBroker> mSandboxBroker; 257 std::vector<std::wstring> mAllowedFilesRead; 258 bool mEnableSandboxLogging; 259 int32_t mSandboxLevel; 260 # endif 261 #endif // XP_WIN 262 263 #if defined(MOZ_SANDBOX) 264 SandboxingKind mSandbox; 265 #endif 266 267 mozilla::RWLock mHandleLock; 268 ProcessHandle mChildProcessHandle MOZ_GUARDED_BY(mHandleLock); 269 #if defined(XP_MACOSX) 270 task_t mChildTask MOZ_GUARDED_BY(mHandleLock); 271 #endif 272 #if defined(MOZ_WIDGET_UIKIT) 273 Maybe<ExtensionKitProcess> mExtensionKitProcess MOZ_GUARDED_BY(mHandleLock); 274 DarwinObjectPtr<xpc_connection_t> mXPCConnection MOZ_GUARDED_BY(mHandleLock); 275 UniqueBEProcessCapabilityGrant mForegroundCapabilityGrant 276 MOZ_GUARDED_BY(mHandleLock); 277 #endif 278 RefPtr<ProcessHandlePromise> mHandlePromise; 279 280 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) 281 bool mDisableOSActivityMode; 282 #endif 283 284 bool OpenPrivilegedHandle(base::ProcessId aPid) MOZ_REQUIRES(mHandleLock); 285 286 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) 287 // Override this method to return true to launch the child process 288 // using the Mac utility (by default) sandbox. Override 289 // FillMacSandboxInfo() to change the sandbox type and settings. 290 virtual bool IsMacSandboxLaunchEnabled() { return false; } 291 292 // Fill a MacSandboxInfo to configure the sandbox 293 virtual bool FillMacSandboxInfo(MacSandboxInfo& aInfo); 294 295 // Adds the command line arguments needed to enable 296 // sandboxing of the child process at startup before 297 // the child event loop is up. 298 virtual bool AppendMacSandboxParams(StringVector& aArgs); 299 #endif 300 301 private: 302 DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost); 303 304 // Removes the instance from sGeckoChildProcessHosts 305 void RemoveFromProcessList(); 306 307 // Mac and Windows. Set this up before we're called from a different thread. 308 nsCOMPtr<nsIFile> mProfileDir; 309 310 mozilla::Atomic<bool> mDestroying; 311 312 static uint32_t sNextUniqueID; 313 static StaticAutoPtr<LinkedList<GeckoChildProcessHost>> 314 sGeckoChildProcessHosts MOZ_GUARDED_BY(sMutex); 315 static StaticMutex sMutex; 316 }; 317 318 nsCOMPtr<nsISerialEventTarget> GetIPCLauncher(); 319 320 } /* namespace ipc */ 321 } /* namespace mozilla */ 322 323 #endif /* __IPC_GLUE_GECKOCHILDPROCESSHOST_H__ */