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/. */
7 #include "mozilla/ipc/IOThreadChild.h"
9 #include "ContentProcess.h"
10 #include "base/shared_memory.h"
11 #include "mozilla/Preferences.h"
13 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
15 # include "mozilla/Sandbox.h"
18 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
19 # include "mozilla/WindowsProcessMitigations.h"
22 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
23 # include "mozilla/SandboxSettings.h"
24 # include "nsAppDirectoryServiceDefs.h"
25 # include "nsDirectoryService.h"
26 # include "nsDirectoryServiceDefs.h"
29 #include "nsAppRunner.h"
30 #include "mozilla/ipc/BackgroundChild.h"
31 #include "mozilla/ipc/ProcessUtils.h"
32 #include "mozilla/GeckoArgs.h"
34 using mozilla::ipc::IOThreadChild
;
36 namespace mozilla::dom
{
38 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
39 static void SetTmpEnvironmentVariable(nsIFile
* aValue
) {
40 // Save the TMP environment variable so that is is picked up by GetTempPath().
41 // Note that we specifically write to the TMP variable, as that is the first
42 // variable that is checked by GetTempPath() to determine its output.
43 nsAutoString fullTmpPath
;
44 nsresult rv
= aValue
->GetPath(fullTmpPath
);
45 if (NS_WARN_IF(NS_FAILED(rv
))) {
48 Unused
<< NS_WARN_IF(!SetEnvironmentVariableW(L
"TMP", fullTmpPath
.get()));
49 // We also set TEMP in case there is naughty third-party code that is
50 // referencing the environment variable directly.
51 Unused
<< NS_WARN_IF(!SetEnvironmentVariableW(L
"TEMP", fullTmpPath
.get()));
55 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
56 static void SetUpSandboxEnvironment() {
58 nsDirectoryService::gService
,
59 "SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
61 // On Windows, a sandbox-writable temp directory is used whenever the sandbox
62 // is enabled, except when win32k is locked down when we no longer require a
64 if (!IsContentSandboxEnabled() || IsWin32kLockedDown()) {
68 nsCOMPtr
<nsIFile
> sandboxedContentTemp
;
69 nsresult rv
= nsDirectoryService::gService
->Get(
70 NS_APP_CONTENT_PROCESS_TEMP_DIR
, NS_GET_IID(nsIFile
),
71 getter_AddRefs(sandboxedContentTemp
));
72 if (NS_WARN_IF(NS_FAILED(rv
))) {
76 // Change the gecko defined temp directory to our sandbox-writable one.
77 // Undefine returns a failure if the property is not already set.
78 Unused
<< nsDirectoryService::gService
->Undefine(NS_OS_TEMP_DIR
);
79 rv
= nsDirectoryService::gService
->Set(NS_OS_TEMP_DIR
, sandboxedContentTemp
);
80 if (NS_WARN_IF(NS_FAILED(rv
))) {
84 SetTmpEnvironmentVariable(sandboxedContentTemp
);
88 bool ContentProcess::Init(int aArgc
, char* aArgv
[]) {
89 Maybe
<uint64_t> childID
= geckoargs::sChildID
.Get(aArgc
, aArgv
);
90 Maybe
<bool> isForBrowser
= Nothing();
91 Maybe
<const char*> parentBuildID
=
92 geckoargs::sParentBuildID
.Get(aArgc
, aArgv
);
93 Maybe
<uint64_t> jsInitHandle
;
94 Maybe
<uint64_t> jsInitLen
= geckoargs::sJsInitLen
.Get(aArgc
, aArgv
);
95 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
96 nsCOMPtr
<nsIFile
> profileDir
;
99 Maybe
<const char*> appDir
= geckoargs::sAppDir
.Get(aArgc
, aArgv
);
100 if (appDir
.isSome()) {
101 mXREEmbed
.SetAppDir(nsDependentCString(*appDir
));
104 Maybe
<bool> safeMode
= geckoargs::sSafeMode
.Get(aArgc
, aArgv
);
105 if (safeMode
.isSome()) {
106 gSafeMode
= *safeMode
;
109 Maybe
<bool> isForBrowerParam
= geckoargs::sIsForBrowser
.Get(aArgc
, aArgv
);
110 Maybe
<bool> notForBrowserParam
= geckoargs::sNotForBrowser
.Get(aArgc
, aArgv
);
111 if (isForBrowerParam
.isSome()) {
112 isForBrowser
= Some(true);
114 if (notForBrowserParam
.isSome()) {
115 isForBrowser
= Some(false);
118 // command line: [-jsInitHandle handle] -jsInitLen length
120 jsInitHandle
= geckoargs::sJsInitHandle
.Get(aArgc
, aArgv
);
123 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
125 Maybe
<const char*> profile
= geckoargs::sProfile
.Get(aArgc
, aArgv
);
126 // xpcshell self-test on macOS will hit this, so check isSome() otherwise
127 // Maybe<> assertions will MOZ_CRASH() us.
128 if (profile
.isSome()) {
129 nsresult rv
= XRE_GetFileFromPath(*profile
, getter_AddRefs(profileDir
));
130 if (NS_FAILED(rv
) || NS_FAILED(profileDir
->Exists(&flag
)) || !flag
) {
131 NS_WARNING("Invalid profile directory passed to content process.");
132 profileDir
= nullptr;
135 NS_WARNING("No profile directory passed to content process.");
137 #endif /* XP_MACOSX && MOZ_SANDBOX */
139 // Did we find all the mandatory flags?
140 if (childID
.isNothing() || isForBrowser
.isNothing() ||
141 parentBuildID
.isNothing()) {
145 if (!ProcessChild::InitPrefs(aArgc
, aArgv
)) {
149 if (!::mozilla::ipc::ImportSharedJSInit(jsInitHandle
.valueOr(0),
150 jsInitLen
.valueOr(0))) {
154 mContent
.Init(TakeInitialEndpoint(), *parentBuildID
, *childID
, *isForBrowser
);
157 #if (defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
158 mContent
.SetProfileDir(profileDir
);
160 if (IsContentSandboxEnabled()) {
161 AssertMacSandboxEnabled();
164 #endif /* XP_MACOSX && MOZ_SANDBOX */
166 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
167 SetUpSandboxEnvironment();
170 // Do this as early as possible to get the parent process to initialize the
171 // background thread since we'll likely need database information very soon.
172 mozilla::ipc::BackgroundChild::Startup();
173 mozilla::ipc::BackgroundChild::InitContentStarter(&mContent
);
178 // Note: CleanUp() never gets called in non-debug builds because we exit early
179 // in ContentChild::ActorDestroy().
180 void ContentProcess::CleanUp() { mXREEmbed
.Stop(); }
182 } // namespace mozilla::dom