diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index e6eb20ba17d3..d0e1ff7a2225 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -33,6 +33,8 @@ #if defined(XP_WIN) && defined(ACCESSIBILITY) # include "mozilla/a11y/AccessibleWrap.h" # include "mozilla/a11y/Compatibility.h" +# include "mozilla/mscom/ActCtxResource.h" +# include "mozilla/StaticPrefs_accessibility.h" #endif #include #include @@ -2526,6 +2528,20 @@ bool ContentParent::BeginSubprocessLaunch(ProcessPriority aPriority) { // processes. ::mozilla::ipc::ExportSharedJSInit(*mSubprocess, extraArgs); +#if defined(XP_WIN) && defined(ACCESSIBILITY) + // Determining the accessibility resource ID causes problems with the sandbox, + // so we pass it on the command line as it is required very early in process + // start up. It is not required when the caching mechanism is being used. + if (!StaticPrefs::accessibility_cache_enabled_AtStartup()) { + // The accessibility resource ID may not be set in some cases, for example + // in xpcshell tests. + auto resourceId = mscom::ActCtxResource::GetAccessibilityResourceId(); + if (resourceId) { + geckoargs::sA11yResourceId.Put(resourceId, extraArgs); + } + } +#endif + // Register ContentParent as an observer for changes to any pref // whose prefix matches the empty string, i.e. all of them. The // observation starts here in order to capture pref updates that diff --git a/ipc/mscom/ProcessRuntime.cpp b/ipc/mscom/ProcessRuntime.cpp index bb957b1a5d50..2b4e613d7537 100644 --- a/ipc/mscom/ProcessRuntime.cpp +++ b/ipc/mscom/ProcessRuntime.cpp @@ -59,7 +59,9 @@ ProcessRuntime::ProcessRuntime(const ProcessCategory aProcessCategory) # if defined(MOZILLA_INTERNAL_API) // If we're inside XUL, and we're the parent process, then we trust that // this has already been initialized for us prior to XUL being loaded. - if (aProcessCategory != ProcessCategory::GeckoBrowserParent) { + // Only required in the child if the Resource ID has been passed down. + if (aProcessCategory != ProcessCategory::GeckoBrowserParent && + ActCtxResource::GetAccessibilityResourceId()) { mActCtxRgn.emplace(ActCtxResource::GetAccessibilityResource()); } # elif defined(MOZ_HAS_MOZGLUE) diff --git a/ipc/mscom/mozglue/ActCtxResource.cpp b/ipc/mscom/mozglue/ActCtxResource.cpp index a51c1089e82c..778e36c4bc4c 100644 --- a/ipc/mscom/mozglue/ActCtxResource.cpp +++ b/ipc/mscom/mozglue/ActCtxResource.cpp @@ -195,23 +195,43 @@ static HMODULE GetContainingModuleHandle() { return thisModule; } +static uint16_t sActCtxResourceId = 0; + +/* static */ +void ActCtxResource::SetAccessibilityResourceId(uint16_t aResourceId) { + sActCtxResourceId = aResourceId; +} + +/* static */ +uint16_t ActCtxResource::GetAccessibilityResourceId() { + return sActCtxResourceId; +} + +static void EnsureAccessibilityResourceId() { + if (!sActCtxResourceId) { +#if defined(HAVE_64BIT_BUILD) + // The manifest for 64-bit Windows is embedded with resource ID 64. + sActCtxResourceId = 64; +#else + // The manifest for 32-bit Windows is embedded with resource ID 32. + // Beginning with Windows 10 Creators Update, 32-bit builds always use the + // 64-bit manifest. Older builds of Windows may or may not require the + // 64-bit manifest: UseIAccessibleProxyStub() determines the course of + // action. + if (mozilla::IsWin10CreatorsUpdateOrLater() || UseIAccessibleProxyStub()) { + sActCtxResourceId = 64; + } else { + sActCtxResourceId = 32; + } +#endif // defined(HAVE_64BIT_BUILD) + } +} + ActCtxResource ActCtxResource::GetAccessibilityResource() { ActCtxResource result = {}; result.mModule = GetContainingModuleHandle(); -#if defined(HAVE_64BIT_BUILD) - // The manifest for 64-bit Windows is embedded with resource ID 64. - result.mId = 64; -#else - // The manifest for 32-bit Windows is embedded with resource ID 32. - // Beginning with Windows 10 Creators Update, 32-bit builds always use the - // 64-bit manifest. Older builds of Windows may or may not require the 64-bit - // manifest: UseIAccessibleProxyStub() determines the course of action. - if (mozilla::IsWin10CreatorsUpdateOrLater() || UseIAccessibleProxyStub()) { - result.mId = 64; - } else { - result.mId = 32; - } -#endif // defined(HAVE_64BIT_BUILD) + EnsureAccessibilityResourceId(); + result.mId = GetAccessibilityResourceId(); return result; } diff --git a/ipc/mscom/mozglue/ActCtxResource.h b/ipc/mscom/mozglue/ActCtxResource.h index 843c065bb6f4..4e9c16c8e091 100644 --- a/ipc/mscom/mozglue/ActCtxResource.h +++ b/ipc/mscom/mozglue/ActCtxResource.h @@ -16,6 +16,17 @@ struct ActCtxResource { uint16_t mId; HMODULE mModule; + /** + * Set the resource ID used by GetAccessibilityResource. This is so that + * sandboxed child processes can use a value passed down from the parent. + */ + static MFBT_API void SetAccessibilityResourceId(uint16_t aResourceId); + + /** + * Get the resource ID used by GetAccessibilityResource. + */ + static MFBT_API uint16_t GetAccessibilityResourceId(); + /** * @return ActCtxResource of a11y manifest resource to be passed to * mscom::ActivationContext diff --git a/toolkit/xre/GeckoArgs.h b/toolkit/xre/GeckoArgs.h index ae36227b5b66..705335cad9e1 100644 --- a/toolkit/xre/GeckoArgs.h +++ b/toolkit/xre/GeckoArgs.h @@ -129,6 +129,11 @@ static CommandLineArg sSafeMode{"-safeMode", "safemode"}; static CommandLineArg sIsForBrowser{"-isForBrowser", "isforbrowser"}; static CommandLineArg sNotForBrowser{"-notForBrowser", "notforbrowser"}; +#if defined(XP_WIN) && defined(ACCESSIBILITY) +static CommandLineArg sA11yResourceId{"-a11yResourceId", + "a11yresourceid"}; +#endif // defined(XP_WIN) && defined(ACCESSIBILITY) + #if defined(__GNUC__) # pragma GCC diagnostic pop #endif diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index 557226747e01..992eb85e99b9 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -27,6 +27,10 @@ # include "mozilla/ScopeExit.h" # include "mozilla/WinDllServices.h" # include "WinUtils.h" +# ifdef ACCESSIBILITY +# include "mozilla/GeckoArgs.h" +# include "mozilla/mscom/ActCtxResource.h" +# endif #endif #include "nsAppRunner.h" @@ -620,6 +624,16 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[], // Associate this thread with a UI MessageLoop MessageLoop uiMessageLoop(uiLoopType); { +#if defined(XP_WIN) && defined(ACCESSIBILITY) + // The accessibility resource ID is passed down on the command line + // because its retrieval causes issues with the sandbox. When it is set, + // it is required for ProcessRuntime construction within ProcessChild. + auto a11yResourceId = geckoargs::sA11yResourceId.Get(aArgc, aArgv); + if (a11yResourceId.isSome()) { + mscom::ActCtxResource::SetAccessibilityResourceId(*a11yResourceId); + } +#endif + UniquePtr process; switch (XRE_GetProcessType()) { case GeckoProcessType_Default: