From 60d35bbaf4b52287c37b09e4f343fd8959998afb Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Thu, 5 Feb 2026 14:37:24 -0800 Subject: [PATCH] feat: add support for disclaiming utility processes (#49128) * feat: add support for disclaiming utility processes * chore: update patches --------- Co-authored-by: Keeley Hammond --- docs/api/utility-process.md | 6 + ...e_launch_options_for_service_process.patch | 104 +++++++++++++++--- ...g_exit_code_on_service_process_crash.patch | 6 +- ..._avoid_private_macos_api_usage.patch.patch | 17 ++- .../api/electron_api_utility_process.cc | 15 ++- .../api/electron_api_utility_process.h | 3 +- spec/api-utility-process-spec.ts | 19 ++++ 7 files changed, 141 insertions(+), 29 deletions(-) diff --git a/docs/api/utility-process.md b/docs/api/utility-process.md index e6cf1b79ba..bac030bbfa 100644 --- a/docs/api/utility-process.md +++ b/docs/api/utility-process.md @@ -36,6 +36,12 @@ Process: [Main](../glossary.md#main-process)
`com.apple.security.cs.allow-unsigned-executable-memory` entitlements. This will allow the utility process to load unsigned libraries. Unless you specifically need this capability, it is best to leave this disabled. Default is `false`. + * `disclaim` boolean (optional) _macOS_ - With this flag, the utility process will disclaim + responsibility for the child process. This causes the operating system to consider the child + process as a separate entity for purposes of security policies like Transparency, Consent, and + Control (TCC). When responsibility is disclaimed, the parent process will not be attributed + for any TCC requests initiated by the child process. This is useful when launching processes + that run third-party or otherwise untrusted code. Default is `false`. * `respondToAuthRequestsFromMainProcess` boolean (optional) - With this flag, all HTTP 401 and 407 network requests created via the [net module](net.md) will allow responding to them via the [`app#login`](app.md#event-login) event in the main process instead of the default diff --git a/patches/chromium/feat_configure_launch_options_for_service_process.patch b/patches/chromium/feat_configure_launch_options_for_service_process.patch index 36f15c90c7..5147528057 100644 --- a/patches/chromium/feat_configure_launch_options_for_service_process.patch +++ b/patches/chromium/feat_configure_launch_options_for_service_process.patch @@ -9,6 +9,8 @@ Subject: feat: configure launch options for service process Allows configuring base::LaunchOptions::handles_to_inherit, base::LaunchOptions::stdout_handle, base::LaunchOptions::stderr_handle and base::LaunchOptions::feedback_cursor_off when launching the child process. +- Mac: + Allows configuring base::LaunchOptions::disclaim_responsibility when launching the child process. - All: Allows configuring base::LauncOptions::current_directory, base::LaunchOptions::enviroment and base::LaunchOptions::clear_environment. @@ -165,10 +167,10 @@ index 0791b5317fc6846389f65f93734ae5e816d04623..71df2459fd759a75be573449accd3a4d FinishStartSandboxedProcessOnLauncherThread, this)); diff --git a/content/browser/service_host/service_process_host_impl.cc b/content/browser/service_host/service_process_host_impl.cc -index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c1bf6acbe 100644 +index d9c14f91747bde0e76056d7f2f2ada166e67f994..09335acac17f526fb8d8e42e4b2d993b11045786 100644 --- a/content/browser/service_host/service_process_host_impl.cc +++ b/content/browser/service_host/service_process_host_impl.cc -@@ -69,6 +69,17 @@ void LaunchServiceProcess(mojo::GenericPendingReceiver receiver, +@@ -69,6 +69,21 @@ void LaunchServiceProcess(mojo::GenericPendingReceiver receiver, utility_options.WithGpuClientAllowed(); } @@ -179,6 +181,10 @@ index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c +#elif BUILDFLAG(IS_POSIX) + utility_options.WithAdditionalFds(std::move(service_options.fds_to_remap)); +#endif ++#if BUILDFLAG(IS_MAC) ++ utility_options.WithDisclaimResponsibility( ++ service_options.disclaim_responsibility); ++#endif + utility_options.WithCurrentDirectory(service_options.current_directory); + utility_options.WithEnvironment(service_options.environment, + service_options.clear_environment); @@ -187,7 +193,7 @@ index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c UtilityProcessHost::Start(std::move(utility_options), diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc -index 1f848cd121b2ecef4892bb2563c593124337e7cf..5fa25d07cddca53177e82e5cba1cc834a40994d0 100644 +index 1f848cd121b2ecef4892bb2563c593124337e7cf..8ad0b2ebbe0e4e2a1a60efec7c4d7b9f8277b82c 100644 --- a/content/browser/service_host/utility_process_host.cc +++ b/content/browser/service_host/utility_process_host.cc @@ -241,13 +241,13 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithFileToPreload( @@ -207,7 +213,7 @@ index 1f848cd121b2ecef4892bb2563c593124337e7cf..5fa25d07cddca53177e82e5cba1cc834 #if BUILDFLAG(USE_ZYGOTE) UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting( -@@ -257,6 +257,36 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting( +@@ -257,6 +257,45 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting( } #endif // BUILDFLAG(USE_ZYGOTE) @@ -240,11 +246,20 @@ index 1f848cd121b2ecef4892bb2563c593124337e7cf..5fa25d07cddca53177e82e5cba1cc834 + return *this; +} +#endif // BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++UtilityProcessHost::Options& ++UtilityProcessHost::Options::WithDisclaimResponsibility( ++ bool disclaim_responsibility) { ++ disclaim_responsibility_ = disclaim_responsibility; ++ return *this; ++} ++#endif // BUILDFLAG(IS_MAC) + UtilityProcessHost::Options& UtilityProcessHost::Options::WithBoundReceiverOnChildProcessForTesting( mojo::GenericPendingReceiver receiver) { -@@ -531,9 +561,26 @@ bool UtilityProcessHost::StartProcess() { +@@ -531,9 +570,30 @@ bool UtilityProcessHost::StartProcess() { } #endif // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE) && !BUILDFLAG(IS_WIN) @@ -269,11 +284,15 @@ index 1f848cd121b2ecef4892bb2563c593124337e7cf..5fa25d07cddca53177e82e5cba1cc834 +#if BUILDFLAG(IS_WIN) + delegate->SetFeedbackCursorOff(options_.feedback_cursor_off_); +#endif // BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++ delegate->SetDisclaimResponsibility(options_.disclaim_responsibility_); ++#endif // BUILDFLAG(IS_MAC) #if BUILDFLAG(IS_WIN) if (!options_.preload_libraries_.empty()) { diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h -index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f339263712d 100644 +index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..96c0cadf5caf5bf27f2a767c43f0f1da04298800 100644 --- a/content/browser/service_host/utility_process_host.h +++ b/content/browser/service_host/utility_process_host.h @@ -30,6 +30,7 @@ @@ -284,7 +303,7 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33 #endif // BUILDFLAG(IS_WIN) namespace base { -@@ -133,14 +134,31 @@ class CONTENT_EXPORT UtilityProcessHost final +@@ -133,14 +134,36 @@ class CONTENT_EXPORT UtilityProcessHost final std::variant file); #endif @@ -315,11 +334,16 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33 + // Specifies if the process should trigger mouse cursor feedback. + Options& WithFeedbackCursorOff(bool feedback_cursor_off); +#endif // BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++ // Specifies if the process should disclaim TCC responsibility. ++ Options& WithDisclaimResponsibility(bool disclaim_responsibility); ++#endif // BUILDFLAG(IS_MAC) + // Requests that the process bind a receiving pipe targeting the interface // named by `receiver`. Calls to this method generally end up in // `ChildThreadImpl::OnBindReceiver()` and the option is used for testing -@@ -184,6 +202,27 @@ class CONTENT_EXPORT UtilityProcessHost final +@@ -184,6 +207,32 @@ class CONTENT_EXPORT UtilityProcessHost final std::optional> zygote_for_testing_; #endif // BUILDFLAG(USE_ZYGOTE) @@ -343,12 +367,17 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33 + // Specifies if the process should trigger mouse cursor feedback. + bool feedback_cursor_off_ = false; +#endif // BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++ // Specifies if the process should disclaim TCC responsibility. ++ bool disclaim_responsibility_ = false; ++#endif // BUILDFLAG(IS_MAC) + #if BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE) // Whether or not to bind viz::mojom::Gpu to the utility process. bool allowed_gpu_; diff --git a/content/browser/service_host/utility_sandbox_delegate.cc b/content/browser/service_host/utility_sandbox_delegate.cc -index ada7034c8926c276ea1c7ebf8242c61b0a993c39..b852d40936f1e876681a00f2eb57c9077a086a1d 100644 +index ada7034c8926c276ea1c7ebf8242c61b0a993c39..aec3de8bd0c18666b33147779cad68c6b41fe1fe 100644 --- a/content/browser/service_host/utility_sandbox_delegate.cc +++ b/content/browser/service_host/utility_sandbox_delegate.cc @@ -39,17 +39,19 @@ UtilitySandboxedProcessLauncherDelegate:: @@ -406,8 +435,24 @@ index ada7034c8926c276ea1c7ebf8242c61b0a993c39..b852d40936f1e876681a00f2eb57c907 #if BUILDFLAG(USE_ZYGOTE) ZygoteCommunication* UtilitySandboxedProcessLauncherDelegate::GetZygote() { +@@ -189,6 +208,15 @@ UtilitySandboxedProcessLauncherDelegate::GetProcessRequirement() { + + return std::nullopt; + } ++ ++void UtilitySandboxedProcessLauncherDelegate::SetDisclaimResponsibility( ++ bool disclaim_responsibility) { ++ disclaim_responsibility_ = disclaim_responsibility; ++} ++ ++bool UtilitySandboxedProcessLauncherDelegate::DisclaimResponsibility() { ++ return disclaim_responsibility_; ++} + #endif // BUILDFLAG(IS_MAC) + + } // namespace content diff --git a/content/browser/service_host/utility_sandbox_delegate.h b/content/browser/service_host/utility_sandbox_delegate.h -index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb3e7a18d0 100644 +index f2e8c1d62c1cb1677f618b584ed401685b03034b..00a20885092bd299e817685dd18c3971b25f721b 100644 --- a/content/browser/service_host/utility_sandbox_delegate.h +++ b/content/browser/service_host/utility_sandbox_delegate.h @@ -36,7 +36,9 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate @@ -438,7 +483,12 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb #if BUILDFLAG(USE_ZYGOTE) void SetZygote(ZygoteCommunication* handle); -@@ -77,9 +84,7 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate +@@ -74,12 +81,12 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate + + #if BUILDFLAG(IS_MAC) + std::optional GetProcessRequirement() override; ++ void SetDisclaimResponsibility(bool disclaim_responsibility); ++ bool DisclaimResponsibility() override; #endif // BUILDFLAG(IS_MAC) private: @@ -448,7 +498,7 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb #if BUILDFLAG(IS_WIN) // Adds preload-libraries to the delegate blob for utility_main() to access -@@ -95,12 +100,17 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate +@@ -95,12 +102,20 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate std::optional> zygote_; #endif // BUILDFLAG(USE_ZYGOTE) @@ -463,6 +513,9 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb +#if BUILDFLAG(IS_WIN) + bool feedback_cursor_off_ = false; +#endif // BUILDFLAG(IS_WIN) ++#if BUILDFLAG(IS_MAC) ++ bool disclaim_responsibility_ = false; ++#endif // BUILDFLAG(IS_MAC) }; } // namespace content @@ -489,10 +542,10 @@ index 39c96d4423b24695eee86353057cfeed19318b57..31b343d97b7672294644041c9bb1a4cd } diff --git a/content/public/browser/service_process_host.cc b/content/public/browser/service_process_host.cc -index d1bc550a891979e2d41d8d5b18a2f9287468e460..5fcac7a8493e5065f80303067a04f59e7c4509ef 100644 +index d1bc550a891979e2d41d8d5b18a2f9287468e460..5d255f628788bc8b40d8df0039b08c06ffec8730 100644 --- a/content/public/browser/service_process_host.cc +++ b/content/public/browser/service_process_host.cc -@@ -53,12 +53,53 @@ ServiceProcessHost::Options::WithExtraCommandLineSwitches( +@@ -53,12 +53,62 @@ ServiceProcessHost::Options::WithExtraCommandLineSwitches( return *this; } @@ -542,12 +595,21 @@ index d1bc550a891979e2d41d8d5b18a2f9287468e460..5fcac7a8493e5065f80303067a04f59e + return *this; +} +#endif // #if BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++ServiceProcessHost::Options& ++ServiceProcessHost::Options::WithDisclaimResponsibility( ++ bool should_disclaim_responsibility) { ++ disclaim_responsibility = should_disclaim_responsibility; ++ return *this; ++} ++#endif // BUILDFLAG(IS_MAC) + #if BUILDFLAG(IS_WIN) ServiceProcessHost::Options& ServiceProcessHost::Options::WithPreloadedLibraries( diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h -index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e45320b70 100644 +index 0062d2cb6634b8b29977a0312516b1b13936b40a..888ff36d70c83010f1f45e9eeb2dd6b573158db5 100644 --- a/content/public/browser/service_process_host.h +++ b/content/public/browser/service_process_host.h @@ -14,6 +14,7 @@ @@ -569,7 +631,7 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e namespace base { class Process; } // namespace base -@@ -94,11 +99,35 @@ class CONTENT_EXPORT ServiceProcessHost { +@@ -94,11 +99,40 @@ class CONTENT_EXPORT ServiceProcessHost { // Specifies extra command line switches to append before launch. Options& WithExtraCommandLineSwitches(std::vector switches); @@ -601,11 +663,16 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e + // Specifies if the process should trigger mouse cursor feedback. + Options& WithFeedbackCursorOff(bool feedback_cursor_off); +#endif // #if BUILDFLAG(IS_WIN) ++ ++#if BUILDFLAG(IS_MAC) ++ // Specifies if the process should disclaim TCC responsibility. ++ Options& WithDisclaimResponsibility(bool disclaim_responsibility); ++#endif // BUILDFLAG(IS_MAC) + #if BUILDFLAG(IS_WIN) // Specifies libraries to preload before the sandbox is locked down. Paths // should be absolute paths. Libraries will be preloaded before sandbox -@@ -127,11 +156,23 @@ class CONTENT_EXPORT ServiceProcessHost { +@@ -127,11 +161,26 @@ class CONTENT_EXPORT ServiceProcessHost { std::optional site; std::optional child_flags; std::vector extra_switches; @@ -626,6 +693,9 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e +#if BUILDFLAG(IS_WIN) + bool feedback_cursor_off = false; +#endif // BUILDFLAG(IS_WIN) ++#if BUILDFLAG(IS_MAC) ++ bool disclaim_responsibility = false; ++#endif // BUILDFLAG(IS_MAC) }; // An interface which can be implemented and registered/unregistered with diff --git a/patches/chromium/feat_enable_passing_exit_code_on_service_process_crash.patch b/patches/chromium/feat_enable_passing_exit_code_on_service_process_crash.patch index ed99acaafe..df0a50b4fb 100644 --- a/patches/chromium/feat_enable_passing_exit_code_on_service_process_crash.patch +++ b/patches/chromium/feat_enable_passing_exit_code_on_service_process_crash.patch @@ -84,10 +84,10 @@ index 2648adb1cf38ab557b66ffd0e3034b26b04d76d6..98eab587f343f6ca472efc3d4e7b31b2 private: const std::string service_interface_name_; diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc -index 5fa25d07cddca53177e82e5cba1cc834a40994d0..75f43420e80752be98af3f35f5a4b82aa8f3e8a8 100644 +index 8ad0b2ebbe0e4e2a1a60efec7c4d7b9f8277b82c..ac1a3d303aa8dbcdb47e6cbddbfd10b9035ef885 100644 --- a/content/browser/service_host/utility_process_host.cc +++ b/content/browser/service_host/utility_process_host.cc -@@ -635,7 +635,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) { +@@ -648,7 +648,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) { : Client::CrashType::kPreIpcInitialization; } #endif // BUILDFLAG(IS_WIN) @@ -97,7 +97,7 @@ index 5fa25d07cddca53177e82e5cba1cc834a40994d0..75f43420e80752be98af3f35f5a4b82a std::optional UtilityProcessHost::GetServiceName() { diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h -index d731211d727f6e96533a058106c13f339263712d..19e35a0684746d6f5703ac4237de4d8aeddbaa4e 100644 +index 96c0cadf5caf5bf27f2a767c43f0f1da04298800..5a16fe5c01ae7777064168e8883ec8ec0b82a873 100644 --- a/content/browser/service_host/utility_process_host.h +++ b/content/browser/service_host/utility_process_host.h @@ -87,7 +87,7 @@ class CONTENT_EXPORT UtilityProcessHost final diff --git a/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch b/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch index 106a23ca00..f7826baa4a 100644 --- a/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch +++ b/patches/chromium/mas_avoid_private_macos_api_usage.patch.patch @@ -130,7 +130,7 @@ index 419a051968c58ae5a761708e4d942e8975c70852..a77032dd43f5fcbe29c54b622b34607f } // namespace base::mac diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc -index b63d58da9837ba4d1e4aff8f24f2cd977c5ed02d..8387fd7d2bcf8951b6cc024829c16d970799190c 100644 +index b63d58da9837ba4d1e4aff8f24f2cd977c5ed02d..49b4c0b69731386ef5a4b7dfb782aa8f4ae09cdd 100644 --- a/base/process/launch_mac.cc +++ b/base/process/launch_mac.cc @@ -84,6 +84,10 @@ int posix_spawnattr_set_csm_np(const posix_spawnattr_t*, uint32_t) @@ -184,15 +184,26 @@ index b63d58da9837ba4d1e4aff8f24f2cd977c5ed02d..8387fd7d2bcf8951b6cc024829c16d97 } #endif -@@ -301,7 +321,7 @@ Process LaunchProcess(const std::vector& argv, +@@ -301,16 +321,16 @@ Process LaunchProcess(const std::vector& argv, file_actions.Inherit(STDERR_FILENO); } -#if BUILDFLAG(IS_MAC) -+#if 0 ++#if !IS_MAS_BUILD() if (options.disclaim_responsibility) { DPSXCHECK(responsibility_spawnattrs_setdisclaim(attr.get(), 1)); } ++#endif + + EnvironmentMap new_environment_map = options.environment; ++#if !IS_MAS_BUILD() + MachPortRendezvousServerMac::AddFeatureStateToEnvironment( + new_environment_map); +-#else +- const EnvironmentMap& new_environment_map = options.environment; + #endif + + std::vector argv_cstr; diff --git a/base/process/process_info_mac.mm b/base/process/process_info_mac.mm index e12c1d078147d956a1d9b1bc498c1b1d6fe7b974..233362259dc4e728ed37435e650417647b45a6af 100644 --- a/base/process/process_info_mac.mm diff --git a/shell/browser/api/electron_api_utility_process.cc b/shell/browser/api/electron_api_utility_process.cc index 2fa5bb1750..474ee3f3b6 100644 --- a/shell/browser/api/electron_api_utility_process.cc +++ b/shell/browser/api/electron_api_utility_process.cc @@ -70,7 +70,8 @@ UtilityProcessWrapper::UtilityProcessWrapper( base::EnvironmentMap env_map, base::FilePath current_working_directory, bool use_plugin_helper, - bool create_network_observer) { + bool create_network_observer, + bool disclaim_responsibility) { #if BUILDFLAG(IS_WIN) base::win::ScopedHandle stdout_write(nullptr); base::win::ScopedHandle stderr_write(nullptr); @@ -184,6 +185,7 @@ UtilityProcessWrapper::UtilityProcessWrapper( .WithChildFlags(use_plugin_helper ? content::ChildProcessHost::CHILD_PLUGIN : content::ChildProcessHost::CHILD_NORMAL) + .WithDisclaimResponsibility(disclaim_responsibility) #endif .WithProcessCallback( base::BindOnce(&UtilityProcessWrapper::OnServiceProcessLaunch, @@ -451,6 +453,7 @@ gin_helper::Handle UtilityProcessWrapper::Create( std::u16string display_name; bool use_plugin_helper = false; bool create_network_observer = false; + bool disclaim_responsibility = false; std::map stdio; base::FilePath current_working_directory; base::EnvironmentMap env_map; @@ -494,13 +497,15 @@ gin_helper::Handle UtilityProcessWrapper::Create( #if BUILDFLAG(IS_MAC) opts.Get("allowLoadingUnsignedLibraries", &use_plugin_helper); + opts.Get("disclaim", &disclaim_responsibility); #endif } auto handle = gin_helper::CreateHandle( - args->isolate(), new UtilityProcessWrapper( - std::move(params), display_name, std::move(stdio), - env_map, current_working_directory, - use_plugin_helper, create_network_observer)); + args->isolate(), + new UtilityProcessWrapper( + std::move(params), display_name, std::move(stdio), env_map, + current_working_directory, use_plugin_helper, create_network_observer, + disclaim_responsibility)); handle->Pin(args->isolate()); return handle; } diff --git a/shell/browser/api/electron_api_utility_process.h b/shell/browser/api/electron_api_utility_process.h index c62fb96795..2dcd6fc71c 100644 --- a/shell/browser/api/electron_api_utility_process.h +++ b/shell/browser/api/electron_api_utility_process.h @@ -72,7 +72,8 @@ class UtilityProcessWrapper final base::EnvironmentMap env_map, base::FilePath current_working_directory, bool use_plugin_helper, - bool create_network_observer); + bool create_network_observer, + bool disclaim_responsibility); void OnServiceProcessLaunch(const base::Process& process); void CloseConnectorPort(); diff --git a/spec/api-utility-process-spec.ts b/spec/api-utility-process-spec.ts index 37d0897f3d..484190200a 100644 --- a/spec/api-utility-process-spec.ts +++ b/spec/api-utility-process-spec.ts @@ -863,5 +863,24 @@ describe('utilityProcess module', () => { await exit; } }); + + // Note: This doesn't test that disclaiming works (that requires stubbing / mocking TCC which is + // just straight up not possible generically). This just tests that utility processes still launch + // when disclaimed. + ifit(process.platform === 'darwin')('supports disclaim option on macOS', async () => { + const child = utilityProcess.fork(path.join(fixturesPath, 'post-message.js'), [], { + disclaim: true + }); + await once(child, 'spawn'); + expect(child.pid).to.be.a('number'); + // Verify the process can communicate normally + const testMessage = 'test-disclaim'; + child.postMessage(testMessage); + const [data] = await once(child, 'message'); + expect(data).to.equal(testMessage); + const exit = once(child, 'exit'); + expect(child.kill()).to.be.true(); + await exit; + }); }); });