blob: f732687feee92de038243d496f18c60c9ec03bc2 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2017 The Chromium Authors
kerrnel0f7a1922017-06-26 23:40:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/sandbox_parameters_mac.h"
6
7#include <unistd.h>
8
Arthur Sonzognic686e8f2024-01-11 08:36:379#include <optional>
10
Avi Drissmand4f07082023-05-12 18:05:4411#include "base/apple/bundle_locations.h"
Avi Drissmaneac566b02023-08-18 02:56:2112#include "base/apple/foundation_util.h"
Hans Wennborgda08b7362020-05-14 17:30:5013#include "base/check.h"
kerrnel0f7a1922017-06-26 23:40:5814#include "base/command_line.h"
Greg Kerrf46f31872019-08-08 20:22:4415#include "base/feature_list.h"
kerrnel0f7a1922017-06-26 23:40:5816#include "base/files/file_util.h"
kerrnel0f7a1922017-06-26 23:40:5817#include "base/mac/mac_util.h"
Robert Sesek6a9e65f2019-08-14 20:02:3418#include "base/no_destructor.h"
Peter Boströmb41d6ee2024-11-20 15:49:3919#include "base/notreached.h"
Greg Kerr4fa6e522017-07-10 19:00:4520#include "base/numerics/checked_math.h"
Robert Sesek34f68f312019-01-14 20:25:1121#include "base/strings/string_number_conversions.h"
Greg Kerr51462da2018-01-31 23:14:2522#include "base/strings/stringprintf.h"
kerrnel0f7a1922017-06-26 23:40:5823#include "base/strings/sys_string_conversions.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0324#include "base/system/sys_info.h"
Mark Rowee5ada492023-06-23 14:48:4925#include "content/browser/mac_helpers.h"
kerrnel0f7a1922017-06-26 23:40:5826#include "content/public/browser/content_browser_client.h"
27#include "content/public/common/content_client.h"
Greg Kerrf46f31872019-08-08 20:22:4428#include "content/public/common/content_features.h"
kerrnel0f7a1922017-06-26 23:40:5829#include "content/public/common/content_switches.h"
Evan Stade526e35a62025-02-01 00:09:3730#include "sandbox/mac/sandbox_serializer.h"
Robert Sesek7838cee12021-04-14 18:39:2231#include "sandbox/policy/mac/params.h"
Robert Sesek7d0b49b2020-07-08 18:31:2732#include "sandbox/policy/mac/sandbox_mac.h"
Alex Gougheb6a38f2021-10-22 01:55:1333#include "sandbox/policy/mojom/sandbox.mojom.h"
Robert Sesek7d0b49b2020-07-08 18:31:2734#include "sandbox/policy/switches.h"
kerrnel0f7a1922017-06-26 23:40:5835
36namespace content {
37
Greg Kerr4fa6e522017-07-10 19:00:4538namespace {
39
Arthur Sonzognic686e8f2024-01-11 08:36:3740std::optional<base::FilePath>& GetNetworkTestCertsDirectory() {
Kenneth Russell1c9a9ab2021-02-10 23:19:5041 // Set by SetNetworkTestCertsDirectoryForTesting().
Arthur Sonzognic686e8f2024-01-11 08:36:3742 static base::NoDestructor<std::optional<base::FilePath>>
Kenneth Russell1c9a9ab2021-02-10 23:19:5043 network_test_certs_dir;
44 return *network_test_certs_dir;
45}
Robert Sesek6a9e65f2019-08-14 20:02:3446
Greg Kerr4fa6e522017-07-10 19:00:4547// Produce the OS version as an integer "1010", etc. and pass that to the
48// profile. The profile converts the string back to a number and can do
49// comparison operations on OS version.
50std::string GetOSVersion() {
51 int32_t major_version, minor_version, bugfix_version;
52 base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
53 &bugfix_version);
54 base::CheckedNumeric<int32_t> os_version(major_version);
55 os_version *= 100;
56 os_version += minor_version;
57
58 int32_t final_os_version = os_version.ValueOrDie();
Helmut Januschkaa965cc12024-05-07 07:11:0959 return base::NumberToString(final_os_version);
Greg Kerr4fa6e522017-07-10 19:00:4560}
61
Greg Kerr19c405e92019-10-04 21:23:3862// Retrieves the users shared darwin dirs and adds it to the profile.
Evan Stade526e35a62025-02-01 00:09:3763void AddDarwinDirs(sandbox::SandboxSerializer* serializer) {
Greg Kerr5bff9882019-07-01 22:43:1464 char dir_path[PATH_MAX + 1];
65
66 size_t rv = confstr(_CS_DARWIN_USER_CACHE_DIR, dir_path, sizeof(dir_path));
67 PCHECK(rv != 0);
Evan Stade526e35a62025-02-01 00:09:3768 CHECK(serializer->SetParameter(
Robert Sesek7838cee12021-04-14 18:39:2269 sandbox::policy::kParamDarwinUserCacheDir,
Robert Sesek5aef3522021-04-14 22:48:2370 sandbox::policy::GetCanonicalPath(base::FilePath(dir_path)).value()));
Greg Kerr19c405e92019-10-04 21:23:3871
72 rv = confstr(_CS_DARWIN_USER_DIR, dir_path, sizeof(dir_path));
73 PCHECK(rv != 0);
Evan Stade526e35a62025-02-01 00:09:3774 CHECK(serializer->SetParameter(
Robert Sesek7838cee12021-04-14 18:39:2275 sandbox::policy::kParamDarwinUserDir,
Robert Sesek5aef3522021-04-14 22:48:2376 sandbox::policy::GetCanonicalPath(base::FilePath(dir_path)).value()));
Greg Kerr19c405e92019-10-04 21:23:3877
78 rv = confstr(_CS_DARWIN_USER_TEMP_DIR, dir_path, sizeof(dir_path));
79 PCHECK(rv != 0);
Evan Stade526e35a62025-02-01 00:09:3780 CHECK(serializer->SetParameter(
Robert Sesek7838cee12021-04-14 18:39:2281 sandbox::policy::kParamDarwinUserTempDir,
Robert Sesek5aef3522021-04-14 22:48:2382 sandbox::policy::GetCanonicalPath(base::FilePath(dir_path)).value()));
Greg Kerr5bff9882019-07-01 22:43:1483}
84
Evan Stade526e35a62025-02-01 00:09:3785// All of the below functions populate the `serializer` with the parameters that
Robert Sesek794b0822022-12-05 15:22:2786// the sandbox needs to resolve information that cannot be known at build time,
87// such as the user's home directory.
Robert Sesek8c9018642022-12-03 01:55:4688void SetupCommonSandboxParameters(
Evan Stade526e35a62025-02-01 00:09:3789 sandbox::SandboxSerializer* serializer,
Robert Sesek8c9018642022-12-03 01:55:4690 const base::CommandLine& target_command_line) {
91 const base::CommandLine* browser_command_line =
kerrnel0f7a1922017-06-26 23:40:5892 base::CommandLine::ForCurrentProcess();
Robert Sesek8c9018642022-12-03 01:55:4693 bool enable_logging = browser_command_line->HasSwitch(
94 sandbox::policy::switches::kEnableSandboxLogging);
95
Evan Stade526e35a62025-02-01 00:09:3796 CHECK(serializer->SetParameter(
Robert Sesek8c9018642022-12-03 01:55:4697 sandbox::policy::kParamExecutablePath,
98 sandbox::policy::GetCanonicalPath(target_command_line.GetProgram())
99 .value()));
kerrnel0f7a1922017-06-26 23:40:58100
Evan Stade526e35a62025-02-01 00:09:37101 CHECK(serializer->SetBooleanParameter(sandbox::policy::kParamEnableLogging,
102 enable_logging));
103 CHECK(serializer->SetBooleanParameter(
Robert Sesek7838cee12021-04-14 18:39:22104 sandbox::policy::kParamDisableSandboxDenialLogging, !enable_logging));
kerrnel0f7a1922017-06-26 23:40:58105
Tom Sepez305e0d0d2017-10-19 20:48:52106 std::string bundle_path =
Avi Drissmand4f07082023-05-12 18:05:44107 sandbox::policy::GetCanonicalPath(base::apple::MainBundlePath()).value();
Evan Stade526e35a62025-02-01 00:09:37108 CHECK(
109 serializer->SetParameter(sandbox::policy::kParamBundlePath, bundle_path));
kerrnel0f7a1922017-06-26 23:40:58110
Avi Drissman370a58102025-05-06 15:54:54111 std::string bundle_id(base::apple::BaseBundleID());
Avi Drissmand4f07082023-05-12 18:05:44112 DCHECK(!bundle_id.empty()) << "base::apple::OuterBundle is unset";
Evan Stade526e35a62025-02-01 00:09:37113 CHECK(serializer->SetParameter(sandbox::policy::kParamBundleId, bundle_id));
kerrnel0f7a1922017-06-26 23:40:58114
Evan Stade526e35a62025-02-01 00:09:37115 CHECK(serializer->SetParameter(sandbox::policy::kParamBrowserPid,
116 base::NumberToString(getpid())));
kerrnel0f7a1922017-06-26 23:40:58117
Robert Sesek8c9018642022-12-03 01:55:46118 std::string logging_path = GetContentClient()
119 ->browser()
120 ->GetLoggingFileName(*browser_command_line)
121 .value();
Evan Stade526e35a62025-02-01 00:09:37122 CHECK(serializer->SetParameter(sandbox::policy::kParamLogFilePath,
123 logging_path));
kerrnel0f7a1922017-06-26 23:40:58124
125#if defined(COMPONENT_BUILD)
126 // For component builds, allow access to one directory level higher, where
127 // the dylibs live.
Avi Drissmand4f07082023-05-12 18:05:44128 base::FilePath component_path = base::apple::MainBundlePath().Append("..");
kerrnel0f7a1922017-06-26 23:40:58129 std::string component_path_canonical =
Robert Sesek5aef3522021-04-14 22:48:23130 sandbox::policy::GetCanonicalPath(component_path).value();
Evan Stade526e35a62025-02-01 00:09:37131 CHECK(serializer->SetParameter(sandbox::policy::kParamComponentPath,
132 component_path_canonical));
kerrnel0f7a1922017-06-26 23:40:58133#endif
Greg Kerrc382e2ae2017-12-14 23:43:34134
Evan Stade526e35a62025-02-01 00:09:37135 CHECK(serializer->SetParameter(sandbox::policy::kParamOsVersion,
136 GetOSVersion()));
Greg Kerrc382e2ae2017-12-14 23:43:34137
138 std::string homedir =
Robert Sesek5aef3522021-04-14 22:48:23139 sandbox::policy::GetCanonicalPath(base::GetHomeDir()).value();
Evan Stade526e35a62025-02-01 00:09:37140 CHECK(serializer->SetParameter(sandbox::policy::kParamHomedirAsLiteral,
141 homedir));
Greg Kerrc382e2ae2017-12-14 23:43:34142}
143
Evan Stade526e35a62025-02-01 00:09:37144void SetupNetworkSandboxParameters(sandbox::SandboxSerializer* serializer,
Robert Sesek8c9018642022-12-03 01:55:46145 const base::CommandLine& command_line) {
Evan Stade526e35a62025-02-01 00:09:37146 SetupCommonSandboxParameters(serializer, command_line);
Robert Sesek34f68f312019-01-14 20:25:11147
Robert Sesek34f68f312019-01-14 20:25:11148 std::vector<base::FilePath> storage_paths =
149 GetContentClient()->browser()->GetNetworkContextsParentDirectory();
150
Evan Stade526e35a62025-02-01 00:09:37151 AddDarwinDirs(serializer);
Greg Kerr5bff9882019-07-01 22:43:14152
Evan Stade526e35a62025-02-01 00:09:37153 CHECK(serializer->SetParameter(
Robert Sesek7838cee12021-04-14 18:39:22154 sandbox::policy::kParamNetworkServiceStoragePathsCount,
155 base::NumberToString(storage_paths.size())));
Robert Sesek34f68f312019-01-14 20:25:11156 for (size_t i = 0; i < storage_paths.size(); ++i) {
Robert Sesek5aef3522021-04-14 22:48:23157 base::FilePath path = sandbox::policy::GetCanonicalPath(storage_paths[i]);
Robert Sesek7838cee12021-04-14 18:39:22158 std::string param_name = base::StringPrintf(
159 "%s%zu", sandbox::policy::kParamNetworkServiceStoragePathN, i);
Evan Stade526e35a62025-02-01 00:09:37160 CHECK(serializer->SetParameter(param_name, path.value())) << param_name;
Robert Sesek34f68f312019-01-14 20:25:11161 }
Robert Sesek6a9e65f2019-08-14 20:02:34162
Kenneth Russell1c9a9ab2021-02-10 23:19:50163 if (GetNetworkTestCertsDirectory().has_value()) {
Evan Stade526e35a62025-02-01 00:09:37164 CHECK(serializer->SetParameter(
Robert Sesek5aef3522021-04-14 22:48:23165 sandbox::policy::kParamNetworkServiceTestCertsDir,
166 sandbox::policy::GetCanonicalPath(*GetNetworkTestCertsDirectory())
167 .value()));
Robert Sesek6a9e65f2019-08-14 20:02:34168 }
Robert Sesek34f68f312019-01-14 20:25:11169}
170
Evan Stade526e35a62025-02-01 00:09:37171bool SetupGpuSandboxParameters(sandbox::SandboxSerializer* serializer,
Kenneth Russell1c9a9ab2021-02-10 23:19:50172 const base::CommandLine& command_line) {
Evan Stade526e35a62025-02-01 00:09:37173 SetupCommonSandboxParameters(serializer, command_line);
174 AddDarwinDirs(serializer);
175 CHECK(serializer->SetBooleanParameter(
Robert Sesek7838cee12021-04-14 18:39:22176 sandbox::policy::kParamDisableMetalShaderCache,
Kenneth Russell1c9a9ab2021-02-10 23:19:50177 command_line.HasSwitch(
178 sandbox::policy::switches::kDisableMetalShaderCache)));
Mark Rowee5ada492023-06-23 14:48:49179
180 base::FilePath helper_bundle_path =
Avi Drissmaneac566b02023-08-18 02:56:21181 base::apple::GetInnermostAppBundlePath(command_line.GetProgram());
Mark Rowee5ada492023-06-23 14:48:49182
183 // The helper may not be contained in an app bundle for unit tests.
184 // In that case `kParamHelperBundleId` will remain unset.
185 if (!helper_bundle_path.empty()) {
186 @autoreleasepool {
187 NSBundle* helper_bundle = [NSBundle
188 bundleWithPath:base::SysUTF8ToNSString(helper_bundle_path.value())];
Ken Rockotaf264582024-05-23 01:03:27189 if (!helper_bundle) {
190 return false;
191 }
Mark Rowee5ada492023-06-23 14:48:49192
Evan Stade526e35a62025-02-01 00:09:37193 return serializer->SetParameter(
Mark Rowee5ada492023-06-23 14:48:49194 sandbox::policy::kParamHelperBundleId,
Ken Rockotaf264582024-05-23 01:03:27195 base::SysNSStringToUTF8(helper_bundle.bundleIdentifier));
Mark Rowee5ada492023-06-23 14:48:49196 }
197 }
Ken Rockotaf264582024-05-23 01:03:27198
199 return true;
Kenneth Russell1c9a9ab2021-02-10 23:19:50200}
201
Greg Kerrb7fdb792019-04-24 23:05:46202} // namespace
203
Ken Rockotaf264582024-05-23 01:03:27204bool SetupSandboxParameters(sandbox::mojom::Sandbox sandbox_type,
Greg Kerrb7fdb792019-04-24 23:05:46205 const base::CommandLine& command_line,
Evan Stade526e35a62025-02-01 00:09:37206 sandbox::SandboxSerializer* serializer) {
Greg Kerrb7fdb792019-04-24 23:05:46207 switch (sandbox_type) {
Alex Gougheb6a38f2021-10-22 01:55:13208 case sandbox::mojom::Sandbox::kAudio:
209 case sandbox::mojom::Sandbox::kCdm:
210 case sandbox::mojom::Sandbox::kMirroring:
Alex Gougheb6a38f2021-10-22 01:55:13211 case sandbox::mojom::Sandbox::kPrintBackend:
Alex Gougheb6a38f2021-10-22 01:55:13212 case sandbox::mojom::Sandbox::kPrintCompositor:
213 case sandbox::mojom::Sandbox::kRenderer:
214 case sandbox::mojom::Sandbox::kService:
Alex Gough72421352021-12-21 11:08:31215 case sandbox::mojom::Sandbox::kServiceWithJit:
Alex Gougheb6a38f2021-10-22 01:55:13216 case sandbox::mojom::Sandbox::kUtility:
Evan Stade526e35a62025-02-01 00:09:37217 SetupCommonSandboxParameters(serializer, command_line);
Greg Kerrb7fdb792019-04-24 23:05:46218 break;
Ken Rockot624ae3272023-11-10 00:43:23219 case sandbox::mojom::Sandbox::kOnDeviceModelExecution:
Ken Rockotaf264582024-05-23 01:03:27220 case sandbox::mojom::Sandbox::kGpu:
Evan Stade526e35a62025-02-01 00:09:37221 return SetupGpuSandboxParameters(serializer, command_line);
Alex Gougheb6a38f2021-10-22 01:55:13222 case sandbox::mojom::Sandbox::kNetwork:
Evan Stade526e35a62025-02-01 00:09:37223 SetupNetworkSandboxParameters(serializer, command_line);
Greg Kerrb7fdb792019-04-24 23:05:46224 break;
Alex Gougheb6a38f2021-10-22 01:55:13225 case sandbox::mojom::Sandbox::kNoSandbox:
Peter Boströmb41d6ee2024-11-20 15:49:39226 NOTREACHED() << "Unhandled parameters for sandbox_type "
Alex Gough9ab468a6c32019-12-10 19:10:22227 << static_cast<int>(sandbox_type);
Alex Gough53fc1472024-11-22 19:31:13228 // Setup parameters for sandbox types handled by embedders below.
David Tseng24e69a2f2022-05-13 19:09:43229 case sandbox::mojom::Sandbox::kScreenAI:
Alex Gougheb6a38f2021-10-22 01:55:13230 case sandbox::mojom::Sandbox::kSpeechRecognition:
Tsuyoshi Horo85ca5f902024-09-25 04:28:50231 case sandbox::mojom::Sandbox::kOnDeviceTranslation:
Evan Stade526e35a62025-02-01 00:09:37232 SetupCommonSandboxParameters(serializer, command_line);
Evan Liu054dc082020-09-30 14:09:42233 CHECK(GetContentClient()->browser()->SetupEmbedderSandboxParameters(
Evan Stade526e35a62025-02-01 00:09:37234 sandbox_type, serializer));
mark a. foltza3128182024-09-06 05:43:53235 break;
Greg Kerrb7fdb792019-04-24 23:05:46236 }
Ken Rockotaf264582024-05-23 01:03:27237 return true;
Greg Kerrb7fdb792019-04-24 23:05:46238}
239
Robert Sesek6a9e65f2019-08-14 20:02:34240void SetNetworkTestCertsDirectoryForTesting(const base::FilePath& path) {
Kenneth Russell1c9a9ab2021-02-10 23:19:50241 GetNetworkTestCertsDirectory().emplace(path);
Robert Sesek6a9e65f2019-08-14 20:02:34242}
243
kerrnel0f7a1922017-06-26 23:40:58244} // namespace content