9999999-port1908725-suite-bustage.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. # HG changeset patch
  2. # User Bill Gianopoulos <wgianopoulos@gmail.com>
  3. # Date 1723715420 0
  4. # Parent f6007cc0d04ad3163c7786931f0a1af583e02adb
  5. Bug 9999999 - Port bug 1908725 to suite.
  6. Bug 1908725 - Provide a never-reused PID alternative for all Gecko processes.
  7. diff --git a/suite/app/moz.build b/suite/app/moz.build
  8. --- a/suite/app/moz.build
  9. +++ b/suite/app/moz.build
  10. @@ -13,17 +13,16 @@ if CONFIG['MOZ_NO_PIE_COMPAT']:
  11. DIRS += ['no-pie']
  12. else:
  13. GeckoProgram(CONFIG['MOZ_APP_NAME'])
  14. SOURCES += ["nsSuiteApp.cpp"]
  15. LOCAL_INCLUDES += [
  16. "!/build",
  17. - "/ipc/contentproc/",
  18. "/toolkit/xre",
  19. "/xpcom/base",
  20. "/xpcom/build",
  21. ]
  22. if CONFIG["OS_ARCH"] == "WINNT":
  23. RCINCLUDE = "splash.rc"
  24. DEFINES["MOZ_SUITE"] = True
  25. diff --git a/suite/app/nsSuiteApp.cpp b/suite/app/nsSuiteApp.cpp
  26. --- a/suite/app/nsSuiteApp.cpp
  27. +++ b/suite/app/nsSuiteApp.cpp
  28. @@ -1,212 +1,193 @@
  29. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  30. /* This Source Code Form is subject to the terms of the Mozilla Public
  31. * License, v. 2.0. If a copy of the MPL was not distributed with this
  32. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  33. #include "nsXULAppAPI.h"
  34. -#include "nsXPCOM.h"
  35. -#include "nsISupports.h"
  36. +#include "mozilla/CmdLineAndEnvUtils.h"
  37. #include "mozilla/Logging.h"
  38. -#include "mozilla/XREAppData.h"
  39. -#include "mozilla/ArrayUtils.h"
  40. -#include "mozilla/Assertions.h"
  41. -#include "mozilla/Vector.h"
  42. #include "mozilla/TimeStamp.h"
  43. #include "XREChildData.h"
  44. #include "XREShellData.h"
  45. +
  46. #include "application.ini.h"
  47. #include "mozilla/Bootstrap.h"
  48. +#include "mozilla/ProcessType.h"
  49. +#include "mozilla/RuntimeExceptionModule.h"
  50. +#include "mozilla/ScopeExit.h"
  51. #if defined(XP_WIN)
  52. -#include <windows.h>
  53. -#include <stdlib.h>
  54. +# include <windows.h>
  55. +# include <stdlib.h>
  56. #elif defined(XP_UNIX)
  57. -#include <sys/resource.h>
  58. -#include <unistd.h>
  59. +# include <sys/resource.h>
  60. +# include <unistd.h>
  61. #endif
  62. #include <stdio.h>
  63. #include <stdarg.h>
  64. #include <time.h>
  65. -#include "nsCOMPtr.h"
  66. -#include "nsIFile.h"
  67. +#ifdef XP_WIN
  68. +# include "mozilla/mscom/ProcessRuntime.h"
  69. +# include "mozilla/WindowsDllBlocklist.h"
  70. +# include "mozilla/WindowsDpiInitialization.h"
  71. -#ifdef XP_WIN
  72. -#include "mozilla/WindowsDllBlocklist.h"
  73. -#define XRE_WANT_ENVIRON
  74. -#define strcasecmp _stricmp
  75. -#ifdef MOZ_SANDBOX
  76. -#include "mozilla/sandboxing/SandboxInitialization.h"
  77. -#endif
  78. +# define XRE_WANT_ENVIRON
  79. +# include "nsWindowsWMain.cpp"
  80. +
  81. +# define strcasecmp _stricmp
  82. +# ifdef MOZ_SANDBOX
  83. +# include "mozilla/sandboxing/SandboxInitialization.h"
  84. +# include "mozilla/sandboxing/sandboxLogging.h"
  85. +# endif
  86. #endif
  87. #include "BinaryPath.h"
  88. -#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
  89. +#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
  90. #include "mozilla/Sprintf.h"
  91. #include "mozilla/StartupTimeline.h"
  92. #ifdef LIBFUZZER
  93. -#include "FuzzerDefs.h"
  94. +# include "FuzzerDefs.h"
  95. #endif
  96. #ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
  97. -#include <cpuid.h>
  98. -#include "mozilla/Unused.h"
  99. +# include <cpuid.h>
  100. +# include "mozilla/Unused.h"
  101. -static bool
  102. -IsSSE2Available()
  103. -{
  104. +static bool IsSSE2Available() {
  105. // The rest of the app has been compiled to assume that SSE2 is present
  106. // unconditionally, so we can't use the normal copy of SSE.cpp here.
  107. // Since SSE.cpp caches the results and we need them only transiently,
  108. // instead of #including SSE.cpp here, let's just inline the specific check
  109. // that's needed.
  110. unsigned int level = 1u;
  111. unsigned int eax, ebx, ecx, edx;
  112. - unsigned int bits = (1u<<26);
  113. + unsigned int bits = (1u << 26);
  114. unsigned int max = __get_cpuid_max(0, nullptr);
  115. if (level > max) {
  116. return false;
  117. }
  118. __cpuid_count(level, 0, eax, ebx, ecx, edx);
  119. return (edx & bits) == bits;
  120. }
  121. static const char sSSE2Message[] =
  122. - "This SeaMonkey version requires a processor with the SSE2 instruction "
  123. + "This browser version requires a processor with the SSE2 instruction "
  124. "set extension.\nYou may be able to obtain a version that does not "
  125. "require SSE2 from your Linux distribution.\n";
  126. -__attribute__((constructor))
  127. -static void
  128. -SSE2Check()
  129. -{
  130. +__attribute__((constructor)) static void SSE2Check() {
  131. if (IsSSE2Available()) {
  132. return;
  133. }
  134. // Using write() in order to avoid jemalloc-based buffering. Ignoring return
  135. // values, since there isn't much we could do on failure and there is no
  136. // point in trying to recover from errors.
  137. - MOZ_UNUSED(write(STDERR_FILENO,
  138. - sSSE2Message,
  139. - MOZ_ARRAY_LENGTH(sSSE2Message) - 1));
  140. + MOZ_UNUSED(
  141. + write(STDERR_FILENO, sSSE2Message, MOZ_ARRAY_LENGTH(sSSE2Message) - 1));
  142. // _exit() instead of exit() to avoid running the usual "at exit" code.
  143. _exit(255);
  144. }
  145. #endif
  146. #if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
  147. -#define MOZ_BROWSER_CAN_BE_CONTENTPROC
  148. -#include "plugin-container.cpp"
  149. +# define MOZ_BROWSER_CAN_BE_CONTENTPROC
  150. #endif
  151. using namespace mozilla;
  152. #ifdef XP_MACOSX
  153. -#define kOSXResourcesFolder "Resources"
  154. +# define kOSXResourcesFolder "Resources"
  155. #endif
  156. #define kDesktopFolder ""
  157. -static MOZ_FORMAT_PRINTF(1, 2) void Output(const char *fmt, ... )
  158. -{
  159. +static MOZ_FORMAT_PRINTF(1, 2) void Output(const char* fmt, ...) {
  160. va_list ap;
  161. va_start(ap, fmt);
  162. #ifndef XP_WIN
  163. vfprintf(stderr, fmt, ap);
  164. #else
  165. char msg[2048];
  166. vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
  167. wchar_t wide_msg[2048];
  168. - MultiByteToWideChar(CP_UTF8,
  169. - 0,
  170. - msg,
  171. - -1,
  172. - wide_msg,
  173. - _countof(wide_msg));
  174. -#if MOZ_WINCONSOLE
  175. + MultiByteToWideChar(CP_UTF8, 0, msg, -1, wide_msg, _countof(wide_msg));
  176. +# if MOZ_WINCONSOLE
  177. fwprintf_s(stderr, wide_msg);
  178. -#else
  179. +# else
  180. // Linking user32 at load-time interferes with the DLL blocklist (bug 932100).
  181. // This is a rare codepath, so we can load user32 at run-time instead.
  182. HMODULE user32 = LoadLibraryW(L"user32.dll");
  183. if (user32) {
  184. decltype(MessageBoxW)* messageBoxW =
  185. - (decltype(MessageBoxW)*) GetProcAddress(user32, "MessageBoxW");
  186. + (decltype(MessageBoxW)*)GetProcAddress(user32, "MessageBoxW");
  187. if (messageBoxW) {
  188. - messageBoxW(nullptr, wide_msg, L"XULRunner", MB_OK
  189. - | MB_ICONERROR
  190. - | MB_SETFOREGROUND);
  191. + messageBoxW(nullptr, wide_msg, L"SeaMonkey",
  192. + MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
  193. }
  194. FreeLibrary(user32);
  195. }
  196. -#endif
  197. +# endif
  198. #endif
  199. va_end(ap);
  200. }
  201. /**
  202. * Return true if |arg| matches the given argument name.
  203. */
  204. -static bool IsArg(const char* arg, const char* s)
  205. -{
  206. - if (*arg == '-')
  207. - {
  208. - if (*++arg == '-')
  209. - ++arg;
  210. +static bool IsArg(const char* arg, const char* s) {
  211. + if (*arg == '-') {
  212. + if (*++arg == '-') ++arg;
  213. return !strcasecmp(arg, s);
  214. }
  215. #if defined(XP_WIN)
  216. - if (*arg == '/')
  217. - return !strcasecmp(++arg, s);
  218. + if (*arg == '/') return !strcasecmp(++arg, s);
  219. #endif
  220. return false;
  221. }
  222. Bootstrap::UniquePtr gBootstrap;
  223. -static int do_main(int argc, char* argv[], char* envp[])
  224. -{
  225. +static int do_main(int argc, char* argv[], char* envp[]) {
  226. // Allow seamonkey.exe to launch XULRunner apps via -app <application.ini>
  227. // Note that -app must be the *first* argument.
  228. - const char *appDataFile = getenv("XUL_APP_FILE");
  229. - if ((!appDataFile || !*appDataFile) &&
  230. - (argc > 1 && IsArg(argv[1], "app"))) {
  231. + const char* appDataFile = getenv("XUL_APP_FILE");
  232. + if ((!appDataFile || !*appDataFile) && (argc > 1 && IsArg(argv[1], "app"))) {
  233. if (argc == 2) {
  234. Output("Incorrect number of arguments passed to -app");
  235. return 255;
  236. }
  237. appDataFile = argv[2];
  238. char appEnv[MAXPATHLEN];
  239. SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
  240. - // Bug 1271574 Purposefully leak the XUL_APP_FILE string passed to putenv.
  241. if (putenv(strdup(appEnv))) {
  242. Output("Couldn't set %s.\n", appEnv);
  243. return 255;
  244. }
  245. argv[2] = argv[0];
  246. argv += 2;
  247. argc -= 2;
  248. } else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
  249. for (int i = 1; i < argc; i++) {
  250. argv[i] = argv[i + 1];
  251. }
  252. XREShellData shellData;
  253. #if defined(XP_WIN) && defined(MOZ_SANDBOX)
  254. shellData.sandboxBrokerServices =
  255. - sandboxing::GetInitializedBrokerServices();
  256. + sandboxing::GetInitializedBrokerServices();
  257. #endif
  258. return gBootstrap->XRE_XPCShellMain(--argc, argv, envp, &shellData);
  259. }
  260. BootstrapConfig config;
  261. if (appDataFile && *appDataFile) {
  262. @@ -215,37 +196,42 @@ static int do_main(int argc, char* argv[
  263. } else {
  264. // no -app flag so we use the compiled-in app data
  265. config.appData = &sAppData;
  266. config.appDataPath = kDesktopFolder;
  267. }
  268. #if defined(XP_WIN) && defined(MOZ_SANDBOX)
  269. sandbox::BrokerServices* brokerServices =
  270. - sandboxing::GetInitializedBrokerServices();
  271. -#if defined(MOZ_CONTENT_SANDBOX)
  272. + sandboxing::GetInitializedBrokerServices();
  273. if (!brokerServices) {
  274. Output("Couldn't initialize the broker services.\n");
  275. return 255;
  276. }
  277. -#endif
  278. config.sandboxBrokerServices = brokerServices;
  279. #endif
  280. #ifdef LIBFUZZER
  281. if (getenv("FUZZER"))
  282. gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
  283. #endif
  284. + // Note: FF needs to keep in sync with LauncherProcessWin,
  285. + // TB doesn't have that file.
  286. + const char* acceptableParams[] = {"compose", "mail", nullptr};
  287. + EnsureCommandlineSafe(argc, argv, acceptableParams);
  288. +
  289. return gBootstrap->XRE_main(argc, argv, config);
  290. }
  291. -static nsresult
  292. -InitXPCOMGlue(LibLoadingStrategy aLibLoadingStrategy)
  293. -{
  294. +static nsresult InitXPCOMGlue(LibLoadingStrategy aLibLoadingStrategy) {
  295. + if (gBootstrap) {
  296. + return NS_OK;
  297. + }
  298. +
  299. UniqueFreePtr<char> exePath = BinaryPath::Get();
  300. if (!exePath) {
  301. Output("Couldn't find the application directory.\n");
  302. return NS_ERROR_FAILURE;
  303. }
  304. auto bootstrapResult =
  305. mozilla::GetBootstrap(exePath.get(), aLibLoadingStrategy);
  306. @@ -262,55 +248,147 @@ InitXPCOMGlue(LibLoadingStrategy aLibLoa
  307. return NS_OK;
  308. }
  309. #ifdef HAS_DLL_BLOCKLIST
  310. // NB: This must be extern, as this value is checked elsewhere
  311. uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault;
  312. #endif
  313. -int main(int argc, char* argv[], char* envp[])
  314. -{
  315. +int main(int argc, char* argv[], char* envp[]) {
  316. +#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
  317. + if (argc > 1 && IsArg(argv[1], "contentproc")) {
  318. + // Set the process type and gecko child id.
  319. + SetGeckoProcessType(argv[--argc]);
  320. + SetGeckoChildID(argv[--argc]);
  321. +
  322. +# if defined(MOZ_ENABLE_FORKSERVER)
  323. + if (GetGeckoProcessType() == GeckoProcessType_ForkServer) {
  324. + nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
  325. + if (NS_FAILED(rv)) {
  326. + return 255;
  327. + }
  328. +
  329. + // Run a fork server in this process, single thread. When it returns, it
  330. + // means the fork server have been stopped or a new child process is
  331. + // created.
  332. + //
  333. + // For the latter case, XRE_ForkServer() will return false, running in a
  334. + // child process just forked from the fork server process. argc & argv
  335. + // will be updated with the values passing from the chrome process, as
  336. + // will GeckoProcessType and GeckoChildID. With the new values, this
  337. + // function continues the reset of the code acting as a child process.
  338. + if (gBootstrap->XRE_ForkServer(&argc, &argv)) {
  339. + // Return from the fork server in the fork server process.
  340. + // Stop the fork server.
  341. + // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
  342. + gBootstrap->NS_LogTerm();
  343. + return 0;
  344. + }
  345. + }
  346. +# endif
  347. + }
  348. +#endif
  349. +
  350. mozilla::TimeStamp start = mozilla::TimeStamp::Now();
  351. + // Register an external module to report on otherwise uncatchable
  352. + // exceptions. Note that in child processes this must be called after Gecko
  353. + // process type has been set.
  354. + CrashReporter::RegisterRuntimeExceptionModule();
  355. +
  356. + // Make sure we unregister the runtime exception module before returning.
  357. + auto unregisterRuntimeExceptionModule =
  358. + MakeScopeExit([] { CrashReporter::UnregisterRuntimeExceptionModule(); });
  359. +
  360. #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
  361. // We are launching as a content process, delegate to the appropriate
  362. // main
  363. - if (argc > 1 && IsArg(argv[1], "contentproc")) {
  364. -#ifdef HAS_DLL_BLOCKLIST
  365. - DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
  366. -#endif
  367. -#if defined(XP_WIN) && defined(MOZ_SANDBOX)
  368. + if (GetGeckoProcessType() != GeckoProcessType_Default) {
  369. +# ifdef HAS_DLL_BLOCKLIST
  370. + DllBlocklist_Initialize(gBlocklistInitFlags |
  371. + eDllBlocklistInitFlagIsChildProcess);
  372. +# endif
  373. +# if defined(XP_WIN) && defined(MOZ_SANDBOX)
  374. // We need to initialize the sandbox TargetServices before InitXPCOMGlue
  375. // because we might need the sandbox broker to give access to some files.
  376. if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
  377. Output("Failed to initialize the sandbox target services.");
  378. return 255;
  379. }
  380. -#endif
  381. +# endif
  382. +# if defined(XP_WIN)
  383. + // Ideally, we would be able to set our DPI awareness in
  384. + // seamonkey.exe.manifest Unfortunately, that would cause Win32k calls
  385. + // when user32.dll gets loaded, which would be incompatible with Win32k
  386. + // Lockdown. We need to call this after GetInitializedTargetServices
  387. + // because it can affect the detection of the win32k lockdown status.
  388. + //
  389. + // MSDN says that it's allowed-but-not-recommended to initialize DPI
  390. + // programmatically, as long as it's done before any HWNDs are created.
  391. + // Thus, we do it almost as soon as we possibly can
  392. + {
  393. + auto result = mozilla::WindowsDpiInitialization();
  394. + (void)result; // Ignore errors since some tools block DPI calls
  395. + }
  396. +# endif
  397. nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
  398. if (NS_FAILED(rv)) {
  399. return 255;
  400. }
  401. - int result = content_process_main(gBootstrap.get(), argc, argv);
  402. + XREChildData childData;
  403. +
  404. +# if defined(XP_WIN) && defined(MOZ_SANDBOX)
  405. + if (IsSandboxedProcess()) {
  406. + childData.sandboxTargetServices =
  407. + mozilla::sandboxing::GetInitializedTargetServices();
  408. + if (!childData.sandboxTargetServices) {
  409. + return 1;
  410. + }
  411. +
  412. + childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction;
  413. + }
  414. +
  415. + if (GetGeckoProcessType() == GeckoProcessType_RemoteSandboxBroker) {
  416. + childData.sandboxBrokerServices =
  417. + mozilla::sandboxing::GetInitializedBrokerServices();
  418. + }
  419. +# endif
  420. +
  421. + rv = gBootstrap->XRE_InitChildProcess(argc, argv, &childData);
  422. // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
  423. gBootstrap->NS_LogTerm();
  424. - return result;
  425. + return NS_FAILED(rv) ? 1 : 0;
  426. }
  427. #endif
  428. #ifdef HAS_DLL_BLOCKLIST
  429. DllBlocklist_Initialize(gBlocklistInitFlags);
  430. #endif
  431. - nsresult rv = InitXPCOMGlue(LibLoadingStrategy::ReadAhead);
  432. +#if defined(XP_WIN)
  433. +
  434. + // Ideally, we would be able to set our DPI awareness in
  435. + // seamonkey.exe.manifest Unfortunately, that would cause Win32k calls when
  436. + // user32.dll gets loaded, which would be incompatible with Win32k Lockdown
  437. + //
  438. + // MSDN says that it's allowed-but-not-recommended to initialize DPI
  439. + // programmatically, as long as it's done before any HWNDs are created.
  440. + // Thus, we do it almost as soon as we possibly can
  441. + {
  442. + auto result = mozilla::WindowsDpiInitialization();
  443. + (void)result; // Ignore errors since some tools block DPI calls
  444. + }
  445. +#endif
  446. +
  447. + nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
  448. if (NS_FAILED(rv)) {
  449. return 255;
  450. }
  451. gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
  452. #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
  453. gBootstrap->XRE_EnableSameExecutableForContentProc();
  454. diff --git a/suite/components/shell/moz.build b/suite/components/shell/moz.build
  455. --- a/suite/components/shell/moz.build
  456. +++ b/suite/components/shell/moz.build
  457. @@ -21,16 +21,19 @@ XPIDL_MODULE = "shellservice"
  458. if CONFIG["OS_ARCH"] == "WINNT":
  459. SOURCES += [
  460. "nsWindowsShellService.cpp",
  461. ]
  462. LOCAL_INCLUDES += [
  463. "/other-licenses/nsis/Contrib/CityHash/cityhash",
  464. ]
  465. + OS_LIBS += [
  466. + "propsys",
  467. + ]
  468. elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
  469. SOURCES += ["nsMacShellService.cpp"]
  470. elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
  471. SOURCES += ["nsGNOMEShellService.cpp"]
  472. if SOURCES:
  473. EXTRA_COMPONENTS += [
  474. "nsSetDefault.js",