Bug Summary

File:root/firefox-clang/browser/app/nsBrowserApp.cpp
Warning:line 219, column 15
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nsBrowserApp.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/browser/app -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/browser/app -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D XPCOM_GLUE -D MOZ_HAS_MOZGLUE -D MOZ_GECKODRIVER -D FIREFOX_ICO="/root/firefox-clang/browser/branding/unofficial/firefox.ico" -D DOCUMENT_ICO="/root/firefox-clang/browser/branding/unofficial/document.ico" -D NEWWINDOW_ICO="/root/firefox-clang/browser/branding/unofficial/newwindow.ico" -D NEWTAB_ICO="/root/firefox-clang/browser/branding/unofficial/newtab.ico" -D PBMODE_ICO="/root/firefox-clang/browser/branding/unofficial/pbmode.ico" -D DOCUMENT_PDF_ICO="/root/firefox-clang/browser/branding/unofficial/document_pdf.ico" -D CUSTOM_RETRO2004_ICO="/root/firefox-clang/browser/components/shell/icons/retro2004.ico" -D CUSTOM_RETRO2017_ICO="/root/firefox-clang/browser/components/shell/icons/retro2017.ico" -D CUSTOM_PRIDE_ICO="/root/firefox-clang/browser/components/shell/icons/pride.ico" -D CUSTOM_MINIMAL_DARK_ICO="/root/firefox-clang/browser/components/shell/icons/minimal-dark.ico" -D CUSTOM_MINIMAL_LIGHT_ICO="/root/firefox-clang/browser/components/shell/icons/minimal-light.ico" -D CUSTOM_PIXELATED_ICO="/root/firefox-clang/browser/components/shell/icons/pixelated.ico" -D CUSTOM_MOMO_ICO="/root/firefox-clang/browser/components/shell/icons/momo.ico" -D CUSTOM_KIT_ICO="/root/firefox-clang/browser/components/shell/icons/kit.ico" -I /root/firefox-clang/browser/app -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/browser/app -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/build -I /root/firefox-clang/toolkit/xre -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ /root/firefox-clang/browser/app/nsBrowserApp.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsXULAppAPI.h"
6#include "mozilla/XREAppData.h"
7#include "XREChildData.h"
8#include "XREShellData.h"
9#include "ApplicationData.h"
10#include "mozilla/Bootstrap.h"
11#include "mozilla/ProcessType.h"
12#include "mozilla/RuntimeExceptionModule.h"
13#include "mozilla/ScopeExit.h"
14#include "BrowserDefines.h"
15#if defined(XP_WIN)
16# include <windows.h>
17# include <stdlib.h>
18#elif defined(XP_UNIX1)
19# include <sys/resource.h>
20# include <unistd.h>
21# include <fcntl.h>
22#endif
23
24#include <stdio.h>
25#include <stdarg.h>
26#include <time.h>
27
28#include "nsCOMPtr.h"
29
30#ifdef XP_WIN
31# include "mozilla/PreXULSkeletonUI.h"
32# include "freestanding/SharedSection.h"
33# include "LauncherProcessWin.h"
34# include "mozilla/GeckoArgs.h"
35# include "mozilla/mscom/ProcessRuntime.h"
36# include "mozilla/WindowsDllBlocklist.h"
37# include "mozilla/WindowsDpiInitialization.h"
38# include "mozilla/WindowsProcessMitigations.h"
39
40# define XRE_WANT_ENVIRON
41# include "nsWindowsWMain.cpp"
42
43# define strcasecmp _stricmp
44# ifdef MOZ_SANDBOX1
45# include "mozilla/sandboxing/SandboxInitialization.h"
46# include "mozilla/sandboxing/TargetGeckoServices.h"
47# endif
48#endif
49#include "BinaryPath.h"
50
51#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
52
53#include "mozilla/BaseProfiler.h"
54#include "mozilla/Sprintf.h"
55#include "mozilla/StartupTimeline.h"
56
57#ifdef LIBFUZZER
58# include "FuzzerDefs.h"
59#endif
60
61#ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
62# include <cpuid.h>
63
64static bool IsSSE2Available() {
65 // The rest of the app has been compiled to assume that SSE2 is present
66 // unconditionally, so we can't use the normal copy of SSE.cpp here.
67 // Since SSE.cpp caches the results and we need them only transiently,
68 // instead of #including SSE.cpp here, let's just inline the specific check
69 // that's needed.
70 unsigned int level = 1u;
71 unsigned int eax, ebx, ecx, edx;
72 unsigned int bits = (1u << 26);
73 unsigned int max = __get_cpuid_max(0, nullptr);
74 if (level > max) {
75 return false;
76 }
77 __cpuid_count(level, 0, eax, ebx, ecx, edx);
78 return (edx & bits) == bits;
79}
80
81static const char sSSE2Message[] =
82 "This browser version requires a processor with the SSE2 instruction "
83 "set extension.\nYou may be able to obtain a version that does not "
84 "require SSE2 from your Linux distribution.\n";
85
86__attribute__((constructor)) static void SSE2Check() {
87 if (IsSSE2Available()) {
88 return;
89 }
90 // Using write() in order to avoid jemalloc-based buffering. Ignoring return
91 // values, since there isn't much we could do on failure and there is no
92 // point in trying to recover from errors.
93 (void)write(STDERR_FILENO2, sSSE2Message, std::size(sSSE2Message) - 1);
94 // _exit() instead of exit() to avoid running the usual "at exit" code.
95 _exit(255);
96}
97#endif
98
99#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
100# define MOZ_BROWSER_CAN_BE_CONTENTPROC
101#endif
102
103using namespace mozilla;
104
105#define kDesktopFolder"browser" "browser"
106
107// Only `Output` below cares about this, and only on Windows, where it decides
108// whether to pop up a message box.
109#if defined(MOZ_BACKGROUNDTASKS1) && defined(XP_WIN)
110static bool gIsBackgroundTask = false;
111#endif
112
113static MOZ_FORMAT_PRINTF(1, 2)__attribute__((format(printf, 1, 2))) void Output(const char* fmt, ...) {
114 va_list ap;
115 va_start(ap, fmt)__builtin_va_start(ap, fmt);
116
117#ifndef XP_WIN
118 vfprintf(stderrstderr, fmt, ap);
119#else
120 bool showMessageBox = true;
121
122 char msg[2048];
123 vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
124
125 wchar_t wide_msg[2048];
126 MultiByteToWideChar(CP_UTF8, 0, msg, -1, wide_msg, _countof(wide_msg));
127
128# if MOZ_WINCONSOLE
129 showMessageBox = false;
130# elif defined(MOZ_BACKGROUNDTASKS1)
131 // Only show a UI if this isn't a background tasks.
132 showMessageBox = !gIsBackgroundTask;
133# endif
134
135 if (showMessageBox) {
136 // Linking user32 at load-time interferes with the DLL blocklist (bug
137 // 932100). This is a rare codepath, so we can load user32 at run-time
138 // instead.
139
140 // If we fail to display the message box, we set showMessageBox to false to
141 // fall back to printing to stderr below.
142 HMODULE user32 = LoadLibraryW(L"user32.dll");
143 if (user32) {
144 decltype(MessageBoxW)* messageBoxW =
145 (decltype(MessageBoxW)*)GetProcAddress(user32, "MessageBoxW");
146 if (messageBoxW) {
147 messageBoxW(nullptr, wide_msg, L"Firefox",
148 MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
149 } else {
150 showMessageBox = false;
151 }
152 FreeLibrary(user32);
153 } else {
154 showMessageBox = false;
155 }
156 }
157
158 if (!showMessageBox) {
159 fwprintf_s(stderrstderr, wide_msg);
160 }
161#endif
162
163 va_end(ap)__builtin_va_end(ap);
164}
165
166/**
167 * Return true if |arg| is a flag with the given string.
168 *
169 * A flag starts with one or two `-` characters, or a `/` character on windows.
170 */
171static bool IsFlag(const char* arg, const char* s) {
172 if (*arg == '-') {
173 if (*++arg == '-') ++arg;
174 return !strcasecmp(arg, s);
175 }
176
177#if defined(XP_WIN)
178 if (*arg == '/') return !strcasecmp(++arg, s);
179#endif
180
181 return false;
182}
183
184#if defined(MOZ_BACKGROUNDTASKS1) && defined(XP_WIN)
185/**
186 * Return true if any arguments are flags with the given string.
187 *
188 * A flag is defined per `IsFlag`.
189 */
190static bool HasFlag(int argc, char* argv[], const char* s) {
191 for (int i = 1; i < argc; i++) {
192 if (IsFlag(argv[i], s)) {
193 return true;
194 }
195 }
196 return false;
197}
198#endif
199
200constinit Bootstrap::UniquePtr gBootstrap;
201
202static int do_main(int argc, char* argv[], char* envp[]) {
203 // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
204 // Note that -app must be the *first* argument.
205 const char* appDataFile = getenv("XUL_APP_FILE");
206 if ((!appDataFile
6.1
'appDataFile' is null
|| !*appDataFile) && (argc
6.2
'argc' is > 1
> 1 && IsFlag(argv[1], "app"))) {
7
Taking true branch
207 if (argc == 2) {
8
Assuming 'argc' is not equal to 2
9
Taking false branch
208 Output("Incorrect number of arguments passed to -app");
209 return 255;
210 }
211 appDataFile = argv[2];
212
213 char appEnv[MAXPATHLEN4096];
214 SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
215 if (putenv(strdup(appEnv))) {
10
Memory is allocated
11
Assuming the condition is false
12
Taking false branch
216 Output("Couldn't set %s.\n", appEnv);
217 return 255;
218 }
219 argv[2] = argv[0];
13
Potential memory leak
220 argv += 2;
221 argc -= 2;
222 } else if (argc > 1 && IsFlag(argv[1], "xpcshell")) {
223 for (int i = 1; i < argc; i++) {
224 argv[i] = argv[i + 1];
225 }
226
227 XREShellData shellData;
228#if defined(XP_WIN) && defined(MOZ_SANDBOX1)
229 shellData.sandboxBrokerServices =
230 sandboxing::GetInitializedBrokerServices();
231#endif
232
233#ifdef LIBFUZZER
234 shellData.fuzzerDriver = fuzzer::FuzzerDriver;
235#endif
236#ifdef AFLFUZZ
237 shellData.fuzzerDriver = afl_interface_raw;
238#endif
239
240 return gBootstrap->XRE_XPCShellMain(--argc, argv, envp, &shellData);
241 }
242
243 BootstrapConfig config;
244
245 if (appDataFile && *appDataFile) {
246 config.appData = nullptr;
247 config.appDataPath = appDataFile;
248 } else {
249 // no -app flag so we use the compiled-in app data
250 config.appData = kStaticAppData;
251 config.appDataPath = kDesktopFolder"browser";
252 }
253
254#if defined(XP_WIN) && defined(MOZ_SANDBOX1)
255 sandbox::BrokerServices* brokerServices =
256 sandboxing::GetInitializedBrokerServices();
257 if (!brokerServices) {
258 Output("Couldn't initialize the broker services.\n");
259 return 255;
260 }
261 config.sandboxBrokerServices = brokerServices;
262#endif
263
264#ifdef LIBFUZZER
265 if (getenv("FUZZER"))
266 gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
267#endif
268
269 EnsureBrowserCommandlineSafe(argc, argv);
270
271 return gBootstrap->XRE_main(argc, argv, config);
272}
273
274static nsresult InitXPCOMGlue(LibLoadingStrategy aLibLoadingStrategy) {
275 if (gBootstrap) {
276 return NS_OK;
277 }
278
279 UniqueFreePtr<char> exePath = BinaryPath::Get();
280 if (!exePath) {
281 Output("Couldn't find the application directory.\n");
282 return NS_ERROR_FAILURE;
283 }
284
285 auto bootstrapResult =
286 mozilla::GetBootstrap(exePath.get(), aLibLoadingStrategy);
287 if (bootstrapResult.isErr()) {
288 Output("Couldn't load XPCOM.\n");
289 return NS_ERROR_FAILURE;
290 }
291
292 gBootstrap = bootstrapResult.unwrap();
293
294 // This will set this thread as the main thread.
295 gBootstrap->NS_LogInit();
296
297 return NS_OK;
298}
299
300#ifdef HAS_DLL_BLOCKLIST
301// NB: This must be extern, as this value is checked elsewhere
302uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault;
303#endif
304
305#if defined(XP_UNIX1)
306static void ReserveDefaultFileDescriptors() {
307 // Reserve the lower positions of the file descriptors to make sure
308 // we don't reuse stdin/stdout/stderr in case they were closed
309 // before launch.
310 // Otherwise code explicitly writing to fd 1 or 2 might accidentally
311 // write to something else, like in bug 1820896 where FD 1 is
312 // reused for the X server display connection.
313 int fd = open("/dev/null", O_RDONLY00);
314 for (int i = 0; i < 2; i++) {
315 [[maybe_unused]] int r = dup(fd);
316 }
317}
318#endif
319
320#ifdef XP_LINUX1
321// Linux performance hack: when the fd table expands to the next power
322// of two, in a multithreaded process it blocks for 30-50ms due to
323// RCU, and this applies separately to each process, so it can add up.
324// But, for a single-threaded process it's basically free, so we can
325// pre-expand early in startup to a value that will usually be enough.
326// The table takes one machine word per entry, so it's cheap in memory.
327//
328// Idea from https://chromium-review.googlesource.com/c/chromium/src/+/6845921
329static void ExpandFileDescriptorTable() {
330 // Expand the table to size 512 by creating a fd with the first
331 // unused number greater than 255 (unlike dup2, this won't overwrite
332 // an existing fd). Empirically, 512 seems to be enough for our
333 // content processes in most cases.
334 mozilla::UniqueFileHandle fdTableExpander(fcntl(0, F_DUPFD0, 256));
335 // The fd is immediately closed (if it was created; we ignore errors
336 // because this is just an optimization).
337}
338#endif
339
340int main(int argc, char* argv[], char* envp[]) {
341#if defined(XP_UNIX1)
342 ReserveDefaultFileDescriptors();
343#endif
344
345#if defined(MOZ_BACKGROUNDTASKS1) && defined(XP_WIN)
346 // Check whether this is a background task very early, as the `Output`
347 // function uses this information.
348 gIsBackgroundTask = HasFlag(argc, argv, "backgroundtask");
349#endif
350
351#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
352 if (argc > 1 && IsFlag(argv[1], "contentproc")) {
1
Assuming 'argc' is > 1
2
Taking false branch
353 // Set the process type and gecko child id.
354 SetGeckoProcessType(argv[--argc]);
355 SetGeckoChildID(argv[--argc]);
356
357# if defined(MOZ_ENABLE_FORKSERVER1)
358 if (GetGeckoProcessType() == GeckoProcessType_ForkServer) {
359 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
360 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
361 return 255;
362 }
363
364 // Run a fork server in this process, single thread. When it returns, it
365 // means the fork server have been stopped or a new child process is
366 // created.
367 //
368 // For the latter case, XRE_ForkServer() will return false, running in a
369 // child process just forked from the fork server process. argc & argv
370 // will be updated with the values passing from the chrome process, as
371 // will GeckoProcessType and GeckoChildID. With the new values, this
372 // function continues the reset of the code acting as a child process.
373 if (gBootstrap->XRE_ForkServer(&argc, &argv)) {
374 // Return from the fork server in the fork server process.
375 // Stop the fork server.
376 // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
377 gBootstrap->NS_LogTerm();
378 return 0;
379 }
380 }
381# endif
382 }
383#endif
384
385#ifdef XP_LINUX1
386 // Do this as early as possible but after the fork server hook,
387 // because forking resets the fd table size.
388 ExpandFileDescriptorTable();
389#endif
390
391 mozilla::TimeStamp start = mozilla::TimeStamp::Now();
392
393 AUTO_BASE_PROFILER_INIT::mozilla::baseprofiler::AutoProfilerInit raiiObject393;
394 AUTO_BASE_PROFILER_LABEL("nsBrowserApp main", OTHER)::mozilla::baseprofiler::AutoProfilerLabel raiiObject394( "nsBrowserApp main"
, nullptr, ::mozilla::baseprofiler::ProfilingCategoryPair::OTHER
)
;
395
396 // Register an external module to report on otherwise uncatchable exceptions.
397 // Note that in child processes this must be called after Gecko process type
398 // has been set.
399 CrashReporter::RegisterRuntimeExceptionModule();
400
401 // Make sure we unregister the runtime exception module before returning.
402 auto unregisterRuntimeExceptionModule =
403 MakeScopeExit([] { CrashReporter::UnregisterRuntimeExceptionModule(); });
404
405#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
406 // We are launching as a content process, delegate to the appropriate
407 // main
408 if (GetGeckoProcessType() != GeckoProcessType_Default) {
3
Assuming the condition is false
4
Taking false branch
409# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
410 // We need to set whether our process is supposed to have win32k locked down
411 // from the command line setting before DllBlocklist_Initialize,
412 // GetInitializedTargetServices and WindowsDpiInitialization.
413 Maybe<bool> win32kLockedDown =
414 mozilla::geckoargs::sWin32kLockedDown.Get(argc, argv);
415 if (win32kLockedDown.isSome() && *win32kLockedDown) {
416 mozilla::SetWin32kLockedDownInPolicy();
417 }
418# endif
419
420# ifdef HAS_DLL_BLOCKLIST
421 uint32_t initFlags =
422 gBlocklistInitFlags | eDllBlocklistInitFlagIsChildProcess;
423 SetDllBlocklistProcessTypeFlags(initFlags, GetGeckoProcessType());
424 DllBlocklist_Initialize(initFlags);
425# endif // HAS_DLL_BLOCKLIST
426
427# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
428 // We need to initialize the sandbox TargetServices before InitXPCOMGlue
429 // because we might need the sandbox broker to give access to some files.
430 if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
431 Output("Failed to initialize the sandbox target services.");
432 return 255;
433 }
434# endif
435# if defined(XP_WIN)
436 // Ideally, we would be able to set our DPI awareness in
437 // firefox.exe.manifest Unfortunately, that would cause Win32k calls when
438 // user32.dll gets loaded, which would be incompatible with Win32k Lockdown
439 //
440 // MSDN says that it's allowed-but-not-recommended to initialize DPI
441 // programatically, as long as it's done before any HWNDs are created.
442 // Thus, we do it almost as soon as we possibly can
443 {
444 auto result = mozilla::WindowsDpiInitialization();
445 (void)result; // Ignore errors since some tools block DPI calls
446 }
447# endif
448
449 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
450 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
451 return 255;
452 }
453
454 XREChildData childData;
455
456# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
457 if (IsSandboxedProcess()) {
458 childData.sandboxTargetServices =
459 mozilla::sandboxing::GetInitializedTargetServices();
460 if (!childData.sandboxTargetServices) {
461 return 1;
462 }
463
464 childData.setTargetGeckoServices =
465 mozilla::sandboxing::SetTargetGeckoServices;
466 }
467# endif
468
469 rv = gBootstrap->XRE_InitChildProcess(argc, argv, &childData);
470
471# if defined(DEBUG1) && defined(HAS_DLL_BLOCKLIST)
472 DllBlocklist_Shutdown();
473# endif
474
475 // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
476 gBootstrap->NS_LogTerm();
477
478 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) ? 1 : 0;
479 }
480#endif
481
482#ifdef HAS_DLL_BLOCKLIST
483 DllBlocklist_Initialize(gBlocklistInitFlags);
484#endif
485
486// We will likely only ever support this as a command line argument on Windows
487// and OSX, so we're ifdefing here just to not create any expectations.
488#if defined(XP_WIN) || defined(XP_MACOSX)
489 if (argc > 1 && IsFlag(argv[1], "silentmode")) {
490 ::putenv(const_cast<char*>("MOZ_APP_SILENT_START=1"));
491# if defined(XP_WIN)
492 // On windows We also want to set a separate variable, which we want to
493 // persist across restarts, which will let us keep the process alive
494 // even if the last window is closed.
495 ::putenv(const_cast<char*>("MOZ_APP_ALLOW_WINDOWLESS=1"));
496# endif
497# if defined(XP_MACOSX)
498 ::putenv(const_cast<char*>("MOZ_APP_NO_DOCK=1"));
499# endif
500 }
501#endif
502
503#if defined(XP_WIN)
504
505 // Ideally, we would be able to set our DPI awareness in firefox.exe.manifest
506 // Unfortunately, that would cause Win32k calls when user32.dll gets loaded,
507 // which would be incompatible with Win32k Lockdown
508 //
509 // MSDN says that it's allowed-but-not-recommended to initialize DPI
510 // programatically, as long as it's done before any HWNDs are created.
511 // Thus, we do it almost as soon as we possibly can
512 {
513 auto result = mozilla::WindowsDpiInitialization();
514 (void)result; // Ignore errors since some tools block DPI calls
515 }
516
517 // Once the browser process hits the main function, we no longer need
518 // a writable section handle because all dependent modules have been
519 // loaded.
520 mozilla::freestanding::gSharedSection.ConvertToReadOnly();
521
522 mozilla::CreateAndStorePreXULSkeletonUI(GetModuleHandle(nullptr), argc, argv);
523
524 // Preload cryptbase.dll from the system directory to avoid loading a
525 // planted one. This used to be done unconditionally in mozglue's DllMain;
526 // it's now parent-only, as child processes either don't need it, or by
527 // the time they do the sandbox already guarantees PreferSystem32Images.
528 ::LoadLibraryExW(L"cryptbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
529#endif
530
531 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::ReadAhead);
532 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5
Taking false branch
533 return 255;
534 }
535
536 gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
537
538#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
539 gBootstrap->XRE_EnableSameExecutableForContentProc();
540#endif
541
542 int result = do_main(argc, argv, envp);
6
Calling 'do_main'
543
544#if defined(XP_WIN)
545 CleanupProcessRuntime();
546#endif
547
548 gBootstrap->NS_LogTerm();
549
550#if defined(DEBUG1) && defined(HAS_DLL_BLOCKLIST)
551 DllBlocklist_Shutdown();
552#endif
553
554#ifdef XP_MACOSX
555 // Allow writes again. While we would like to catch writes from static
556 // destructors to allow early exits to use _exit, we know that there is
557 // at least one such write that we don't control (see bug 826029). For
558 // now we enable writes again and early exits will have to use exit instead
559 // of _exit.
560 gBootstrap->XRE_StopLateWriteChecks();
561#endif
562
563 gBootstrap.reset();
564
565 return result;
566}