diff options
Diffstat (limited to 'www/chromium/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_cc')
| -rw-r--r-- | www/chromium/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_cc | 411 |
1 files changed, 0 insertions, 411 deletions
diff --git a/www/chromium/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_cc b/www/chromium/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_cc deleted file mode 100644 index 62f2bd8..0000000 --- a/www/chromium/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_cc +++ /dev/null | |||
| @@ -1,411 +0,0 @@ | |||
| 1 | Index: sandbox/policy/openbsd/sandbox_openbsd.cc | ||
| 2 | --- sandbox/policy/openbsd/sandbox_openbsd.cc.orig | ||
| 3 | +++ sandbox/policy/openbsd/sandbox_openbsd.cc | ||
| 4 | @@ -0,0 +1,407 @@ | ||
| 5 | +// Copyright (c) 2012 The Chromium Authors. All rights reserved. | ||
| 6 | +// Use of this source code is governed by a BSD-style license that can be | ||
| 7 | +// found in the LICENSE file. | ||
| 8 | + | ||
| 9 | +#include "sandbox/policy/openbsd/sandbox_openbsd.h" | ||
| 10 | + | ||
| 11 | +#include <dirent.h> | ||
| 12 | +#include <fcntl.h> | ||
| 13 | +#include <stdint.h> | ||
| 14 | +#include <sys/resource.h> | ||
| 15 | +#include <sys/stat.h> | ||
| 16 | +#include <sys/time.h> | ||
| 17 | +#include <sys/types.h> | ||
| 18 | +#include <unistd.h> | ||
| 19 | +#include <util.h> | ||
| 20 | + | ||
| 21 | +#include <limits> | ||
| 22 | +#include <memory> | ||
| 23 | +#include <string> | ||
| 24 | +#include <vector> | ||
| 25 | + | ||
| 26 | +#include "base/bind.h" | ||
| 27 | +#include "base/callback_helpers.h" | ||
| 28 | +#include "base/command_line.h" | ||
| 29 | +#include "base/debug/stack_trace.h" | ||
| 30 | +#include "base/feature_list.h" | ||
| 31 | +#include "base/files/file_path.h" | ||
| 32 | +#include "base/files/file_util.h" | ||
| 33 | +#include "base/files/scoped_file.h" | ||
| 34 | +#include "base/logging.h" | ||
| 35 | +#include "base/memory/singleton.h" | ||
| 36 | +#include "base/path_service.h" | ||
| 37 | +#include "base/posix/eintr_wrapper.h" | ||
| 38 | +#include "base/strings/string_number_conversions.h" | ||
| 39 | +#include "base/system/sys_info.h" | ||
| 40 | +#include "base/time/time.h" | ||
| 41 | +#include "build/build_config.h" | ||
| 42 | +#include "sandbox/constants.h" | ||
| 43 | +#include "sandbox/linux/services/credentials.h" | ||
| 44 | +#include "sandbox/linux/services/namespace_sandbox.h" | ||
| 45 | +#include "sandbox/linux/services/proc_util.h" | ||
| 46 | +#include "sandbox/linux/services/resource_limits.h" | ||
| 47 | +#include "sandbox/linux/services/thread_helpers.h" | ||
| 48 | +#include "sandbox/linux/syscall_broker/broker_command.h" | ||
| 49 | +#include "sandbox/linux/syscall_broker/broker_process.h" | ||
| 50 | +#include "sandbox/policy/sandbox.h" | ||
| 51 | +#include "sandbox/policy/sandbox_type.h" | ||
| 52 | +#include "sandbox/policy/mojom/sandbox.mojom.h" | ||
| 53 | +#include "sandbox/policy/switches.h" | ||
| 54 | +#include "sandbox/sandbox_buildflags.h" | ||
| 55 | + | ||
| 56 | +#if BUILDFLAG(USING_SANITIZER) | ||
| 57 | +#include <sanitizer/common_interface_defs.h> | ||
| 58 | +#endif | ||
| 59 | + | ||
| 60 | +#if defined(USE_NSS_CERTS) | ||
| 61 | +#include "crypto/nss_util.h" | ||
| 62 | +#endif | ||
| 63 | + | ||
| 64 | +#include "third_party/boringssl/src/include/openssl/crypto.h" | ||
| 65 | + | ||
| 66 | +#include "ui/gfx/x/connection.h" | ||
| 67 | +#include "ui/gfx/font_util.h" | ||
| 68 | + | ||
| 69 | +#include <X11/Xlib.h> | ||
| 70 | + | ||
| 71 | +#define MAXTOKENS 3 | ||
| 72 | + | ||
| 73 | +#define _UNVEIL_MAIN "/etc/chromium/unveil.main"; | ||
| 74 | +#define _UNVEIL_RENDERER "/etc/chromium/unveil.renderer"; | ||
| 75 | +#define _UNVEIL_GPU "/etc/chromium/unveil.gpu"; | ||
| 76 | +#define _UNVEIL_PLUGIN "/etc/chromium/unveil.plugin"; | ||
| 77 | +#define _UNVEIL_UTILITY "/etc/chromium/unveil.utility"; | ||
| 78 | +#define _UNVEIL_UTILITY_NETWORK "/etc/chromium/unveil.utility_network"; | ||
| 79 | +#define _UNVEIL_UTILITY_AUDIO "/etc/chromium/unveil.utility_audio"; | ||
| 80 | +#define _UNVEIL_UTILITY_VIDEO "/etc/chromium/unveil.utility_video"; | ||
| 81 | + | ||
| 82 | +namespace sandbox { | ||
| 83 | +namespace policy { | ||
| 84 | + | ||
| 85 | +SandboxLinux::SandboxLinux() | ||
| 86 | + : unveil_initialized_(false), | ||
| 87 | + sandbox_status_flags_(kInvalid), | ||
| 88 | + pre_initialized_(false), | ||
| 89 | + initialize_sandbox_ran_(false), | ||
| 90 | + broker_process_(nullptr) { | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +SandboxLinux::~SandboxLinux() { | ||
| 94 | + if (pre_initialized_) { | ||
| 95 | + CHECK(initialize_sandbox_ran_); | ||
| 96 | + } | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +SandboxLinux* SandboxLinux::GetInstance() { | ||
| 100 | + SandboxLinux* instance = base::Singleton<SandboxLinux>::get(); | ||
| 101 | + CHECK(instance); | ||
| 102 | + return instance; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +void SandboxLinux::PreinitializeSandbox(sandbox::mojom::Sandbox sandbox_type) { | ||
| 106 | + CHECK(!pre_initialized_); | ||
| 107 | +#if BUILDFLAG(USING_SANITIZER) | ||
| 108 | + // Sanitizers need to open some resources before the sandbox is enabled. | ||
| 109 | + // This should not fork, not launch threads, not open a directory. | ||
| 110 | + __sanitizer_sandbox_on_notify(sanitizer_args()); | ||
| 111 | + sanitizer_args_.reset(); | ||
| 112 | +#endif | ||
| 113 | + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | ||
| 114 | + const std::string process_type = | ||
| 115 | + command_line->GetSwitchValueASCII(switches::kProcessType); | ||
| 116 | + | ||
| 117 | + base::SysInfo::AmountOfPhysicalMemory(); | ||
| 118 | + base::SysInfo::NumberOfProcessors(); | ||
| 119 | + base::SysInfo::CPUModelName(); | ||
| 120 | + | ||
| 121 | +#if defined(USE_NSS_CERTS) | ||
| 122 | + // The main process has to initialize the ~/.pki dir which won't work | ||
| 123 | + // after unveil(2). | ||
| 124 | + if (process_type.empty()) | ||
| 125 | + crypto::EnsureNSSInit(); | ||
| 126 | +#endif | ||
| 127 | + | ||
| 128 | + if (process_type.empty()) | ||
| 129 | + CRYPTO_pre_sandbox_init(); | ||
| 130 | + | ||
| 131 | + // cache the XErrorDB by forcing a read on it | ||
| 132 | + { | ||
| 133 | + auto* connection = x11::Connection::Get(); | ||
| 134 | + auto* display = connection->GetXlibDisplay().display(); | ||
| 135 | + | ||
| 136 | + char buf[1]; | ||
| 137 | + XGetErrorDatabaseText(display, "XProtoError", "0", "", buf, base::size(buf)); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + if (process_type.empty()) { | ||
| 141 | + base::FilePath cache_directory, local_directory; | ||
| 142 | + | ||
| 143 | + base::PathService::Get(base::DIR_CACHE, &cache_directory); | ||
| 144 | + base::PathService::Get(base::DIR_HOME, &local_directory); | ||
| 145 | + | ||
| 146 | + cache_directory = cache_directory.AppendASCII("chromium"); | ||
| 147 | + local_directory = local_directory.AppendASCII(".local").AppendASCII("share").AppendASCII("applications"); | ||
| 148 | + | ||
| 149 | + if (!base::CreateDirectory(cache_directory)) { | ||
| 150 | + LOG(ERROR) << "Failed to create " << cache_directory.value() << " directory."; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + if (!base::CreateDirectory(local_directory)) { | ||
| 154 | + LOG(ERROR) << "Failed to create " << local_directory.value() << " directory."; | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + if (process_type == switches::kRendererProcess) | ||
| 159 | + gfx::InitializeFonts(); | ||
| 160 | + | ||
| 161 | + if (!command_line->HasSwitch(switches::kDisableUnveil)) | ||
| 162 | + SetUnveil(process_type, sandbox_type); | ||
| 163 | + | ||
| 164 | + pre_initialized_ = true; | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +bool SandboxLinux::SetPledge(const char *pstring, const char *ppath) { | ||
| 168 | + FILE *fp; | ||
| 169 | + char *s = NULL; | ||
| 170 | + size_t len = 0; | ||
| 171 | + ssize_t read; | ||
| 172 | + | ||
| 173 | + if (pstring != NULL) { | ||
| 174 | + if (pledge(pstring, NULL) == -1) | ||
| 175 | + goto err; | ||
| 176 | + } else if (ppath != NULL) { | ||
| 177 | + fp = fopen(ppath, "r"); | ||
| 178 | + if (fp != NULL) { | ||
| 179 | + while ((read = getline(&s, &len, fp)) != -1 ) { | ||
| 180 | + if (s[strlen(s)-1] == '\n') | ||
| 181 | + s[strlen(s)-1] = '\0'; | ||
| 182 | + if (pledge(s, NULL) == -1) | ||
| 183 | + goto err; | ||
| 184 | + } | ||
| 185 | + fclose(fp); | ||
| 186 | + } else { | ||
| 187 | + LOG(ERROR) << "fopen() failed, errno: " << errno; | ||
| 188 | + return false; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + return true; | ||
| 192 | +err: | ||
| 193 | + LOG(ERROR) << "pledge() failed, errno: " << errno; | ||
| 194 | + return false; | ||
| 195 | +} | ||
| 196 | + | ||
| 197 | +bool SandboxLinux::SetUnveil(const std::string process_type, sandbox::mojom::Sandbox sandbox_type) { | ||
| 198 | + FILE *fp; | ||
| 199 | + char *s = NULL, *cp = NULL, *home = NULL, **ap, *tokens[MAXTOKENS]; | ||
| 200 | + char path[PATH_MAX]; | ||
| 201 | + const char *ufile; | ||
| 202 | + size_t len = 0, lineno = 0; | ||
| 203 | + | ||
| 204 | + if (process_type.empty()) { | ||
| 205 | + ufile = _UNVEIL_MAIN; | ||
| 206 | + } else if (process_type == switches::kRendererProcess) { | ||
| 207 | + ufile = _UNVEIL_RENDERER; | ||
| 208 | + } else if (process_type == switches::kGpuProcess) { | ||
| 209 | + ufile = _UNVEIL_GPU; | ||
| 210 | + } else if (process_type == switches::kPpapiPluginProcess) { | ||
| 211 | + ufile = _UNVEIL_PLUGIN; | ||
| 212 | + } else if (process_type == switches::kUtilityProcess) { | ||
| 213 | + if (sandbox_type == sandbox::mojom::Sandbox::kNetwork) { | ||
| 214 | + ufile = _UNVEIL_UTILITY_NETWORK; | ||
| 215 | + } else if (sandbox_type == sandbox::mojom::Sandbox::kAudio) { | ||
| 216 | + ufile = _UNVEIL_UTILITY_AUDIO; | ||
| 217 | + } else if (sandbox_type == sandbox::mojom::Sandbox::kVideoCapture) { | ||
| 218 | + ufile = _UNVEIL_UTILITY_VIDEO; | ||
| 219 | + } else { | ||
| 220 | + ufile = _UNVEIL_UTILITY; | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + fp = fopen(ufile, "r"); | ||
| 225 | + if (fp != NULL) { | ||
| 226 | + while (!feof(fp)) { | ||
| 227 | + if ((s = fparseln(fp, &len, &lineno, NULL, | ||
| 228 | + FPARSELN_UNESCCOMM | FPARSELN_UNESCCONT)) == NULL) { | ||
| 229 | + if (ferror(fp)) { | ||
| 230 | + LOG(ERROR) << "ferror(), errno: " << errno; | ||
| 231 | + _exit(1); | ||
| 232 | + } else { | ||
| 233 | + continue; | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + cp = s; | ||
| 237 | + cp += strspn(cp, " \t\n"); /* eat whitespace */ | ||
| 238 | + if (cp[0] == '\0') | ||
| 239 | + continue; | ||
| 240 | + | ||
| 241 | + for (ap = tokens; ap < &tokens[MAXTOKENS - 1] && | ||
| 242 | + (*ap = strsep(&cp, " \t")) != NULL;) { | ||
| 243 | + if (**ap != '\0') | ||
| 244 | + ap++; | ||
| 245 | + } | ||
| 246 | + *ap = NULL; | ||
| 247 | + | ||
| 248 | + if (tokens[1] == NULL) { | ||
| 249 | + LOG(ERROR) << ufile << ": line " << lineno << ": must supply value to " << s; | ||
| 250 | + _exit(1); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + if (tokens[0][0] == '~') { | ||
| 254 | + if ((home = getenv("HOME")) == NULL || *home == '\0') { | ||
| 255 | + LOG(ERROR) << "failed to get home"; | ||
| 256 | + _exit(1); | ||
| 257 | + } | ||
| 258 | + memmove(tokens[0], tokens[0] + 1, strlen(tokens[0])); | ||
| 259 | + strncpy(path, home, sizeof(path) - 1); | ||
| 260 | + path[sizeof(path) - 1] = '\0'; | ||
| 261 | + strncat(path, tokens[0], sizeof(path) - 1 - strlen(path)); | ||
| 262 | + } else { | ||
| 263 | + strncpy(path, tokens[0], sizeof(path) - 1); | ||
| 264 | + path[sizeof(path) - 1] = '\0'; | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + if (unveil(path, tokens[1]) == -1) { | ||
| 268 | + LOG(ERROR) << "failed unveiling " << path << " with permissions " << tokens[1]; | ||
| 269 | + _exit(1); | ||
| 270 | + } else { | ||
| 271 | + VLOG(1) << "unveiling " << path << " with permissions " << tokens[1]; | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + fclose(fp); | ||
| 275 | + } else { | ||
| 276 | + LOG(ERROR) << "failed to open " << ufile << " errno: " << errno; | ||
| 277 | + _exit(1); | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + unveil_initialized_ = true; | ||
| 281 | + | ||
| 282 | + return true; | ||
| 283 | +} | ||
| 284 | + | ||
| 285 | +bool SandboxLinux::unveil_initialized() const { | ||
| 286 | + return unveil_initialized_; | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +bool SandboxLinux::InitializeSandbox(sandbox::mojom::Sandbox sandbox_type, | ||
| 290 | + SandboxLinux::PreSandboxHook hook, | ||
| 291 | + const Options& options) { | ||
| 292 | + DCHECK(!initialize_sandbox_ran_); | ||
| 293 | + initialize_sandbox_ran_ = true; | ||
| 294 | + | ||
| 295 | + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | ||
| 296 | + const std::string process_type = | ||
| 297 | + command_line->GetSwitchValueASCII(switches::kProcessType); | ||
| 298 | + | ||
| 299 | + if (command_line->HasSwitch(switches::kNoSandbox)) | ||
| 300 | + return true; | ||
| 301 | + | ||
| 302 | + VLOG(1) << "SandboxLinux::InitializeSandbox: process_type=" | ||
| 303 | + << process_type << " sandbox_type=" << GetSandboxTypeInEnglish(sandbox_type); | ||
| 304 | + | ||
| 305 | + // Only one thread is running, pre-initialize if not already done. | ||
| 306 | + if (!pre_initialized_) | ||
| 307 | + PreinitializeSandbox(sandbox_type); | ||
| 308 | + | ||
| 309 | + // Attempt to limit the future size of the address space of the process. | ||
| 310 | + int error = 0; | ||
| 311 | + const bool limited_as = LimitAddressSpace(&error); | ||
| 312 | + if (error) { | ||
| 313 | + // Restore errno. Internally to |LimitAddressSpace|, the errno due to | ||
| 314 | + // setrlimit may be lost. | ||
| 315 | + errno = error; | ||
| 316 | + PCHECK(limited_as); | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + if (process_type.empty()) { | ||
| 320 | + // XXX use a file for listing pledges of the main process for now | ||
| 321 | + // XXX not having the file is not a fatal error | ||
| 322 | + SetPledge(NULL, "/etc/chromium/pledge.main"); | ||
| 323 | + } else if (process_type == switches::kRendererProcess) { | ||
| 324 | + // prot_exec needed by v8 | ||
| 325 | + // flock needed by sqlite3 locking | ||
| 326 | + SetPledge("stdio rpath flock prot_exec recvfd sendfd ps", NULL); | ||
| 327 | + } else if (process_type == switches::kGpuProcess) { | ||
| 328 | + SetPledge("stdio rpath cpath wpath getpw drm prot_exec recvfd sendfd tmppath", NULL); | ||
| 329 | + } else if (process_type == switches::kPpapiPluginProcess) { | ||
| 330 | + // prot_exec needed by v8 | ||
| 331 | + SetPledge("stdio rpath prot_exec recvfd sendfd", NULL); | ||
| 332 | + } else if (process_type == switches::kUtilityProcess) { | ||
| 333 | + if (sandbox_type == sandbox::mojom::Sandbox::kAudio) | ||
| 334 | + SetPledge(NULL, "/etc/chromium/pledge.utility_audio"); | ||
| 335 | + else if (sandbox_type == sandbox::mojom::Sandbox::kNetwork) | ||
| 336 | + SetPledge(NULL, "/etc/chromium/pledge.utility_network"); | ||
| 337 | + else if (sandbox_type == sandbox::mojom::Sandbox::kVideoCapture) | ||
| 338 | + SetPledge(NULL, "/etc/chromium/pledge.utility_video"); | ||
| 339 | + else | ||
| 340 | + SetPledge("stdio rpath cpath wpath fattr flock sendfd recvfd prot_exec", NULL); | ||
| 341 | + } else { | ||
| 342 | + LOG(ERROR) << "non-pledge()'d process: " << process_type; | ||
| 343 | + return false; | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + return true; | ||
| 347 | +} | ||
| 348 | + | ||
| 349 | +bool SandboxLinux::LimitAddressSpace(int* error) { | ||
| 350 | +#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \ | ||
| 351 | + !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER) | ||
| 352 | + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | ||
| 353 | + if (SandboxTypeFromCommandLine(*command_line) == sandbox::mojom::Sandbox::kNoSandbox) { | ||
| 354 | + return false; | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | + // Unfortunately, it does not appear possible to set RLIMIT_AS such that it | ||
| 358 | + // will both (a) be high enough to support V8's and WebAssembly's address | ||
| 359 | + // space requirements while also (b) being low enough to mitigate exploits | ||
| 360 | + // using integer overflows that require large allocations, heap spray, or | ||
| 361 | + // other memory-hungry attack modes. | ||
| 362 | + | ||
| 363 | + *error = sandbox::ResourceLimits::Lower( | ||
| 364 | + RLIMIT_DATA, static_cast<rlim_t>(sandbox::kDataSizeLimit)); | ||
| 365 | + | ||
| 366 | + // Cache the resource limit before turning on the sandbox. | ||
| 367 | + base::SysInfo::AmountOfVirtualMemory(); | ||
| 368 | + base::SysInfo::MaxSharedMemorySize(); | ||
| 369 | + | ||
| 370 | + return *error == 0; | ||
| 371 | +#else | ||
| 372 | + base::SysInfo::AmountOfVirtualMemory(); | ||
| 373 | + return false; | ||
| 374 | +#endif // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && | ||
| 375 | + // !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER) | ||
| 376 | +} | ||
| 377 | + | ||
| 378 | +// static | ||
| 379 | +std::string SandboxLinux::GetSandboxTypeInEnglish(sandbox::mojom::Sandbox sandbox_type) { | ||
| 380 | + switch (sandbox_type) { | ||
| 381 | + case sandbox::mojom::Sandbox::kNoSandbox: | ||
| 382 | + return "Unsandboxed"; | ||
| 383 | + case sandbox::mojom::Sandbox::kRenderer: | ||
| 384 | + return "Renderer"; | ||
| 385 | + case sandbox::mojom::Sandbox::kUtility: | ||
| 386 | + return "Utility"; | ||
| 387 | + case sandbox::mojom::Sandbox::kGpu: | ||
| 388 | + return "GPU"; | ||
| 389 | + case sandbox::mojom::Sandbox::kPpapi: | ||
| 390 | + return "PPAPI"; | ||
| 391 | + case sandbox::mojom::Sandbox::kNetwork: | ||
| 392 | + return "Network"; | ||
| 393 | + case sandbox::mojom::Sandbox::kCdm: | ||
| 394 | + return "CDM"; | ||
| 395 | + case sandbox::mojom::Sandbox::kPrintCompositor: | ||
| 396 | + return "Print Compositor"; | ||
| 397 | + case sandbox::mojom::Sandbox::kAudio: | ||
| 398 | + return "Audio"; | ||
| 399 | + case sandbox::mojom::Sandbox::kSpeechRecognition: | ||
| 400 | + return "Speech Recognition"; | ||
| 401 | + case sandbox::mojom::Sandbox::kService: | ||
| 402 | + return "Service"; | ||
| 403 | + case sandbox::mojom::Sandbox::kVideoCapture: | ||
| 404 | + return "Video Capture"; | ||
| 405 | + default: | ||
| 406 | + return "Unknown"; | ||
| 407 | + } | ||
| 408 | +} | ||
| 409 | + | ||
| 410 | +} // namespace policy | ||
| 411 | +} // namespace sandbox | ||
