diff options
Diffstat (limited to 'www/chromium-uc/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_h')
| -rw-r--r-- | www/chromium-uc/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_h | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/www/chromium-uc/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_h b/www/chromium-uc/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_h new file mode 100644 index 0000000..78278b1 --- /dev/null +++ b/www/chromium-uc/patches/patch-sandbox_policy_openbsd_sandbox_openbsd_h | |||
| @@ -0,0 +1,284 @@ | |||
| 1 | $OpenBSD: patch-sandbox_policy_openbsd_sandbox_openbsd_h,v 1.4 2021/09/01 16:54:40 robert Exp $ | ||
| 2 | |||
| 3 | Index: sandbox/policy/openbsd/sandbox_openbsd.h | ||
| 4 | --- sandbox/policy/openbsd/sandbox_openbsd.h.orig | ||
| 5 | +++ sandbox/policy/openbsd/sandbox_openbsd.h | ||
| 6 | @@ -0,0 +1,278 @@ | ||
| 7 | +// Copyright (c) 2012 The Chromium Authors. All rights reserved. | ||
| 8 | +// Use of this source code is governed by a BSD-style license that can be | ||
| 9 | +// found in the LICENSE file. | ||
| 10 | +#ifndef SANDBOX_POLICY_LINUX_SANDBOX_OPENBSD_H_ | ||
| 11 | +#define SANDBOX_POLICY_LINUX_SANDBOX_OPENBSD_H_ | ||
| 12 | + | ||
| 13 | +#include <memory> | ||
| 14 | +#include <string> | ||
| 15 | +#include <vector> | ||
| 16 | + | ||
| 17 | +#include "base/logging.h" | ||
| 18 | +#include "base/macros.h" | ||
| 19 | +#include "base/posix/global_descriptors.h" | ||
| 20 | +#include "sandbox/policy/export.h" | ||
| 21 | +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" | ||
| 22 | +#include "sandbox/policy/sandbox_type.h" | ||
| 23 | +#include "sandbox/policy/sanitizer_buildflags.h" | ||
| 24 | + | ||
| 25 | +#if BUILDFLAG(USING_SANITIZER) | ||
| 26 | +#include <sanitizer/common_interface_defs.h> | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | +namespace base { | ||
| 30 | +template <typename T> | ||
| 31 | +struct DefaultSingletonTraits; | ||
| 32 | +class Thread; | ||
| 33 | +} // namespace base | ||
| 34 | + | ||
| 35 | +namespace sandbox { | ||
| 36 | +namespace syscall_broker { | ||
| 37 | +class BrokerProcess; | ||
| 38 | +} // namespace syscall_broker | ||
| 39 | +} // namespace sandbox | ||
| 40 | + | ||
| 41 | +namespace sandbox { | ||
| 42 | +namespace policy { | ||
| 43 | + | ||
| 44 | +// A singleton class to represent and change our sandboxing state for the | ||
| 45 | +// three main Linux sandboxes. | ||
| 46 | +// The sandboxing model allows using two layers of sandboxing. The first layer | ||
| 47 | +// can be implemented either with unprivileged namespaces or with the setuid | ||
| 48 | +// sandbox. This class provides a way to engage the namespace sandbox, but does | ||
| 49 | +// not deal with the legacy setuid sandbox directly. | ||
| 50 | +// The second layer is mainly based on seccomp-bpf and is engaged with | ||
| 51 | +// InitializeSandbox(). InitializeSandbox() is also responsible for "sealing" | ||
| 52 | +// the first layer of sandboxing. That is, InitializeSandbox must always be | ||
| 53 | +// called to have any meaningful sandboxing at all. | ||
| 54 | +class SANDBOX_POLICY_EXPORT SandboxLinux { | ||
| 55 | + public: | ||
| 56 | + // This is a list of sandbox IPC methods which the renderer may send to the | ||
| 57 | + // sandbox host. See | ||
| 58 | + // https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md | ||
| 59 | + // This isn't the full list, values < 32 are reserved for methods called from | ||
| 60 | + // Skia, and values < 64 are reserved for libc_interceptor.cc. | ||
| 61 | + enum LinuxSandboxIPCMethods { | ||
| 62 | + DEPRECATED_METHOD_GET_FALLBACK_FONT_FOR_CHAR = 64, | ||
| 63 | + DEPRECATED_METHOD_GET_CHILD_WITH_INODE, | ||
| 64 | + DEPRECATED_METHOD_GET_STYLE_FOR_STRIKE, | ||
| 65 | + METHOD_MAKE_SHARED_MEMORY_SEGMENT, | ||
| 66 | + DEPRECATED_METHOD_MATCH_WITH_FALLBACK, | ||
| 67 | + }; | ||
| 68 | + | ||
| 69 | + // These form a bitmask which describes the conditions of the Linux sandbox. | ||
| 70 | + // Note: this doesn't strictly give you the current status, it states | ||
| 71 | + // what will be enabled when the relevant processes are initialized. | ||
| 72 | + enum Status { | ||
| 73 | + // SUID sandbox active. | ||
| 74 | + kSUID = 1 << 0, | ||
| 75 | + | ||
| 76 | + // Sandbox is using a new PID namespace. | ||
| 77 | + kPIDNS = 1 << 1, | ||
| 78 | + | ||
| 79 | + // Sandbox is using a new network namespace. | ||
| 80 | + kNetNS = 1 << 2, | ||
| 81 | + | ||
| 82 | + // seccomp-bpf sandbox active. | ||
| 83 | + kSeccompBPF = 1 << 3, | ||
| 84 | + | ||
| 85 | + // The Yama LSM module is present and enforcing. | ||
| 86 | + kYama = 1 << 4, | ||
| 87 | + | ||
| 88 | + // seccomp-bpf sandbox is active and the kernel supports TSYNC. | ||
| 89 | + kSeccompTSYNC = 1 << 5, | ||
| 90 | + | ||
| 91 | + // User namespace sandbox active. | ||
| 92 | + kUserNS = 1 << 6, | ||
| 93 | + | ||
| 94 | + // A flag that denotes an invalid sandbox status. | ||
| 95 | + kInvalid = 1 << 31, | ||
| 96 | + }; | ||
| 97 | + | ||
| 98 | + // SandboxLinux Options are a superset of SandboxSecompBPF Options. | ||
| 99 | + struct Options : public SandboxSeccompBPF::Options { | ||
| 100 | + // When running with a zygote, the namespace sandbox will have already | ||
| 101 | + // been engaged prior to initializing SandboxLinux itself, and need not | ||
| 102 | + // be done so again. Set to true to indicate that there isn't a zygote | ||
| 103 | + // for this process and the step is to be performed here explicitly. | ||
| 104 | + bool engage_namespace_sandbox = false; | ||
| 105 | + | ||
| 106 | + // Allow starting the sandbox with multiple threads already running. This | ||
| 107 | + // will enable TSYNC for seccomp-BPF, which syncs the seccomp-BPF policy | ||
| 108 | + // across all running threads. | ||
| 109 | + bool allow_threads_during_sandbox_init = false; | ||
| 110 | + | ||
| 111 | + // Enables the CHECK for open directories. The open directory check is only | ||
| 112 | + // useful for the chroot jail (from the semantic layer of the sandbox), and | ||
| 113 | + // can safely be disabled if we are only enabling the seccomp-BPF layer. | ||
| 114 | + bool check_for_open_directories = true; | ||
| 115 | + }; | ||
| 116 | + | ||
| 117 | + // Callers can provide this hook to run code right before the policy | ||
| 118 | + // is passed to the BPF compiler and the sandbox is engaged. If | ||
| 119 | + // pre_sandbox_hook() returns true, the sandbox will be engaged | ||
| 120 | + // afterwards, otherwise the process is terminated. | ||
| 121 | + using PreSandboxHook = base::OnceCallback<bool(Options)>; | ||
| 122 | + | ||
| 123 | + // Get our singleton instance. | ||
| 124 | + static SandboxLinux* GetInstance(); | ||
| 125 | + | ||
| 126 | + bool SetPledge(const char *pstring, const char *ppath); | ||
| 127 | + bool SetUnveil(const std::string process_type, SandboxType sandbox_type); | ||
| 128 | + | ||
| 129 | + // Do some initialization that can only be done before any of the sandboxes | ||
| 130 | + // are enabled. If using the setuid sandbox, this should be called manually | ||
| 131 | + // before the setuid sandbox is engaged. | ||
| 132 | + // Security: When this runs, it is imperative that either InitializeSandbox() | ||
| 133 | + // runs as well or that all file descriptors returned in | ||
| 134 | + // GetFileDescriptorsToClose() get closed. | ||
| 135 | + // Otherwise file descriptors that bypass the security of the setuid sandbox | ||
| 136 | + // would be kept open. One must be particularly careful if a process performs | ||
| 137 | + // a fork(). | ||
| 138 | + void PreinitializeSandbox(SandboxType sandbox_type); | ||
| 139 | + | ||
| 140 | + // Check that the current process is the init process of a new PID | ||
| 141 | + // namespace and then proceed to drop access to the file system by using | ||
| 142 | + // a new unprivileged namespace. This is a layer-1 sandbox. | ||
| 143 | + // In order for this sandbox to be effective, it must be "sealed" by calling | ||
| 144 | + // InitializeSandbox(). | ||
| 145 | + void EngageNamespaceSandbox(bool from_zygote); | ||
| 146 | + | ||
| 147 | + // Return a list of file descriptors to close if PreinitializeSandbox() ran | ||
| 148 | + // but InitializeSandbox() won't. Avoid using. | ||
| 149 | + // TODO(jln): get rid of this hack. | ||
| 150 | + std::vector<int> GetFileDescriptorsToClose(); | ||
| 151 | + | ||
| 152 | + // Seal an eventual layer-1 sandbox and initialize the layer-2 sandbox with | ||
| 153 | + // an adequate policy depending on the process type and command line | ||
| 154 | + // arguments. | ||
| 155 | + // Currently the layer-2 sandbox is composed of seccomp-bpf and address space | ||
| 156 | + // limitations. | ||
| 157 | + // This function should only be called without any thread running. | ||
| 158 | + bool InitializeSandbox(SandboxType sandbox_type, | ||
| 159 | + PreSandboxHook hook, | ||
| 160 | + const Options& options); | ||
| 161 | + | ||
| 162 | + // Stop |thread| in a way that can be trusted by the sandbox. | ||
| 163 | + void StopThread(base::Thread* thread); | ||
| 164 | + | ||
| 165 | + // Returns the status of the renderer, worker and ppapi sandbox. Can only | ||
| 166 | + // be queried after going through PreinitializeSandbox(). This is a bitmask | ||
| 167 | + // and uses the constants defined in "enum Status" above. Since the | ||
| 168 | + // status needs to be provided before the sandboxes are actually started, | ||
| 169 | + // this returns what will actually happen once InitializeSandbox() | ||
| 170 | + // is called from inside these processes. | ||
| 171 | + int GetStatus(); | ||
| 172 | + | ||
| 173 | + static std::string GetSandboxTypeInEnglish(SandboxType sandbox_type); | ||
| 174 | + | ||
| 175 | + // Returns true if the current process is single-threaded or if the number | ||
| 176 | + // of threads cannot be determined. | ||
| 177 | + bool IsSingleThreaded() const; | ||
| 178 | + | ||
| 179 | + // Returns true if we started Seccomp BPF. | ||
| 180 | + bool seccomp_bpf_started() const; | ||
| 181 | + | ||
| 182 | + // Check the policy and eventually start the seccomp-bpf sandbox. This should | ||
| 183 | + // never be called with threads started. If we detect that threads have | ||
| 184 | + // started we will crash. | ||
| 185 | + bool StartSeccompBPF(SandboxType sandbox_type, | ||
| 186 | + PreSandboxHook hook, | ||
| 187 | + const Options& options); | ||
| 188 | + | ||
| 189 | + // Limit the address space of the current process (and its children) to make | ||
| 190 | + // some vulnerabilities harder to exploit. Writes the errno due to setrlimit | ||
| 191 | + // (including 0 if no error) into |error|. | ||
| 192 | + bool LimitAddressSpace(int* error); | ||
| 193 | + | ||
| 194 | + // Returns a file descriptor to proc. The file descriptor is no longer valid | ||
| 195 | + // after the sandbox has been sealed. | ||
| 196 | + int proc_fd() const { | ||
| 197 | + DCHECK_NE(-1, proc_fd_); | ||
| 198 | + return proc_fd_; | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | +#if BUILDFLAG(USING_SANITIZER) | ||
| 202 | + __sanitizer_sandbox_arguments* sanitizer_args() const { | ||
| 203 | + return sanitizer_args_.get(); | ||
| 204 | + }; | ||
| 205 | +#endif | ||
| 206 | + | ||
| 207 | + // A BrokerProcess is a helper that is started before the sandbox is engaged, | ||
| 208 | + // typically from a pre-sandbox hook, that will serve requests to access | ||
| 209 | + // files over an IPC channel. The client of this runs from a SIGSYS handler | ||
| 210 | + // triggered by the seccomp-bpf sandbox. | ||
| 211 | + // |client_sandbox_policy| is the policy being run by the client, and is | ||
| 212 | + // used to derive the equivalent broker-side policy. | ||
| 213 | + // |broker_side_hook| is an alternate pre-sandbox hook to be run before the | ||
| 214 | + // broker itself gets sandboxed, to which the broker side policy and | ||
| 215 | + // |options| are passed. | ||
| 216 | + // Crashes the process if the broker can not be started since continuation | ||
| 217 | + // is impossible (and presumably unsafe). | ||
| 218 | + // This should never be destroyed, as after the sandbox is started it is | ||
| 219 | + // vital to the process. | ||
| 220 | +#if 0 | ||
| 221 | + void StartBrokerProcess( | ||
| 222 | + const sandbox::syscall_broker::BrokerCommandSet& allowed_command_set, | ||
| 223 | + std::vector<sandbox::syscall_broker::BrokerFilePermission> permissions, | ||
| 224 | + PreSandboxHook broker_side_hook, | ||
| 225 | + const Options& options); | ||
| 226 | + | ||
| 227 | + sandbox::syscall_broker::BrokerProcess* broker_process() const { | ||
| 228 | + return broker_process_; | ||
| 229 | + } | ||
| 230 | +#endif | ||
| 231 | + | ||
| 232 | + private: | ||
| 233 | + friend struct base::DefaultSingletonTraits<SandboxLinux>; | ||
| 234 | + | ||
| 235 | + SandboxLinux(); | ||
| 236 | + ~SandboxLinux(); | ||
| 237 | + | ||
| 238 | + // We must have been pre_initialized_ before using these. | ||
| 239 | + bool seccomp_bpf_supported() const; | ||
| 240 | + bool seccomp_bpf_with_tsync_supported() const; | ||
| 241 | + | ||
| 242 | + // Returns true if it can be determined that the current process has open | ||
| 243 | + // directories that are not managed by the SandboxLinux class. This would | ||
| 244 | + // be a vulnerability as it would allow to bypass the setuid sandbox. | ||
| 245 | + bool HasOpenDirectories() const; | ||
| 246 | + | ||
| 247 | + // The last part of the initialization is to make sure any temporary "hole" | ||
| 248 | + // in the sandbox is closed. For now, this consists of closing proc_fd_. | ||
| 249 | + void SealSandbox(); | ||
| 250 | + | ||
| 251 | + // GetStatus() makes promises as to how the sandbox will behave. This | ||
| 252 | + // checks that no promises have been broken. | ||
| 253 | + void CheckForBrokenPromises(SandboxType sandbox_type); | ||
| 254 | + | ||
| 255 | + // Stop |thread| and make sure it does not appear in /proc/self/tasks/ | ||
| 256 | + // anymore. | ||
| 257 | + void StopThreadAndEnsureNotCounted(base::Thread* thread) const; | ||
| 258 | + | ||
| 259 | + // A file descriptor to /proc. It's dangerous to have it around as it could | ||
| 260 | + // allow for sandbox bypasses. It needs to be closed before we consider | ||
| 261 | + // ourselves sandboxed. | ||
| 262 | + int proc_fd_; | ||
| 263 | + | ||
| 264 | + bool seccomp_bpf_started_; | ||
| 265 | + // The value returned by GetStatus(). Gets computed once and then cached. | ||
| 266 | + int sandbox_status_flags_; | ||
| 267 | + // Did PreinitializeSandbox() run? | ||
| 268 | + bool pre_initialized_; | ||
| 269 | + bool seccomp_bpf_supported_; // Accurate if pre_initialized_. | ||
| 270 | + bool seccomp_bpf_with_tsync_supported_; // Accurate if pre_initialized_. | ||
| 271 | + bool yama_is_enforcing_; // Accurate if pre_initialized_. | ||
| 272 | + bool initialize_sandbox_ran_; // InitializeSandbox() was called. | ||
| 273 | +#if BUILDFLAG(USING_SANITIZER) | ||
| 274 | + std::unique_ptr<__sanitizer_sandbox_arguments> sanitizer_args_; | ||
| 275 | +#endif | ||
| 276 | + sandbox::syscall_broker::BrokerProcess* broker_process_; // Leaked as global. | ||
| 277 | + | ||
| 278 | + DISALLOW_COPY_AND_ASSIGN(SandboxLinux); | ||
| 279 | +}; | ||
| 280 | + | ||
| 281 | +} // namespace policy | ||
| 282 | +} // namespace sandbox | ||
| 283 | + | ||
| 284 | +#endif // SANDBOX_POLICY_LINUX_SANDBOX_OPENBSD_H_ | ||
