diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-29 10:46:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-02 12:02:10 +0000 |
commit | 99677208ff3b216fdfec551fbe548da5520cd6fb (patch) | |
tree | 476a4865c10320249360e859d8fdd3e01833b03a /chromium/sandbox/policy/linux | |
parent | c30a6232df03e1efbd9f3b226777b07e087a1122 (diff) | |
download | qtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz |
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/sandbox/policy/linux')
39 files changed, 2992 insertions, 0 deletions
diff --git a/chromium/sandbox/policy/linux/OWNERS b/chromium/sandbox/policy/linux/OWNERS new file mode 100644 index 00000000000..57df6dc7ec4 --- /dev/null +++ b/chromium/sandbox/policy/linux/OWNERS @@ -0,0 +1,2 @@ +set noparent +file://sandbox/linux/OWNERS diff --git a/chromium/sandbox/policy/linux/bpf_audio_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_audio_policy_linux.cc new file mode 100644 index 00000000000..fba1b9eb089 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_audio_policy_linux.cc @@ -0,0 +1,140 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_audio_policy_linux.h" + +#include <sys/socket.h> + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/services/syscall_wrappers.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_futex.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Arg; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::If; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +AudioProcessPolicy::AudioProcessPolicy() = default; + +AudioProcessPolicy::~AudioProcessPolicy() = default; + +ResultExpr AudioProcessPolicy::EvaluateSyscall(int system_call_number) const { + switch (system_call_number) { +#if defined(__NR_connect) + case __NR_connect: +#endif +#if defined(__NR_ftruncate) + case __NR_ftruncate: +#endif +#if defined(__NR_ftruncate64) + case __NR_ftruncate64: +#endif +#if defined(__NR_fallocate) + case __NR_fallocate: +#endif +#if defined(__NR_getdents) + case __NR_getdents: +#endif +#if defined(__NR_getpeername) + case __NR_getpeername: +#endif +#if defined(__NR_getsockopt) + case __NR_getsockopt: +#endif +#if defined(__NR_getsockname) + case __NR_getsockname: +#endif +#if defined(__NR_ioctl) + case __NR_ioctl: +#endif +#if defined(__NR_memfd_create) + case __NR_memfd_create: +#endif +#if defined(__NR_pwrite) + case __NR_pwrite: +#endif +#if defined(__NR_pwrite64) + case __NR_pwrite64: +#endif +#if defined(__NR_sched_setscheduler) + case __NR_sched_setscheduler: +#endif +#if defined(__NR_setsockopt) + case __NR_setsockopt: +#endif +#if defined(__NR_uname) + case __NR_uname: +#endif + return Allow(); +#if defined(__NR_futex) + case __NR_futex: { + const Arg<int> op(1); +#if defined(USE_PULSEAUDIO) + return Switch(op & ~FUTEX_PRIVATE_FLAG) + .SANDBOX_BPF_DSL_CASES( + (FUTEX_CMP_REQUEUE, FUTEX_LOCK_PI, FUTEX_UNLOCK_PI, FUTEX_WAIT, + FUTEX_WAIT_BITSET, FUTEX_WAKE), + Allow()) + .Default(Error(EPERM)); +#else + return RestrictFutex(); +#endif + } +#endif +#if defined(__NR_kill) + case __NR_kill: { + // man kill says: + // "If sig is 0, then no signal is sent, but existence and permission + // checks are still performed; this can be used to check for the + // existence of a process ID or process group ID that the caller is + // permitted to signal." + // + // This seems to be tripping up at least ESET's NOD32 anti-virus, causing + // an unnecessary crash in the audio process. See: http://crbug.com/904787 + const Arg<pid_t> pid(0); + const Arg<int> sig(1); + return If(pid == sys_getpid(), Allow()) + .ElseIf(sig == 0, Error(EPERM)) + .Else(CrashSIGSYSKill()); + } +#endif +#if defined(__NR_socket) + case __NR_socket: { + const Arg<int> domain(0); + return If(domain == AF_UNIX, Allow()).Else(Error(EPERM)); + } +#endif + default: +#if defined(__x86_64__) + if (SyscallSets::IsSystemVSemaphores(system_call_number) || + SyscallSets::IsSystemVSharedMemory(system_call_number)) { + return Allow(); + } +#elif defined(__i386__) + if (SyscallSets::IsSystemVIpc(system_call_number)) + return Allow(); +#endif + + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(system_call_number)) + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + + return BPFBasePolicy::EvaluateSyscall(system_call_number); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_audio_policy_linux.h b/chromium/sandbox/policy/linux/bpf_audio_policy_linux.h new file mode 100644 index 00000000000..56067e8ea93 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_audio_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_AUDIO_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_AUDIO_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT AudioProcessPolicy : public BPFBasePolicy { + public: + AudioProcessPolicy(); + ~AudioProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(AudioProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_AUDIO_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_base_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_base_policy_linux.cc new file mode 100644 index 00000000000..90164eaecf3 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_base_policy_linux.cc @@ -0,0 +1,57 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +#include <errno.h> + +#include "base/check.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +namespace { + +// The errno used for denied file system access system calls, such as open(2). +static const int kFSDeniedErrno = EPERM; + +} // namespace. + +BPFBasePolicy::BPFBasePolicy() + : baseline_policy_(new BaselinePolicy(kFSDeniedErrno)) {} +BPFBasePolicy::~BPFBasePolicy() {} + +ResultExpr BPFBasePolicy::EvaluateSyscall(int system_call_number) const { + DCHECK(baseline_policy_); + + // set_robust_list(2) is part of the futex(2) infrastructure. + // Chrome on Linux/Chrome OS will call set_robust_list(2) frequently. + // The baseline policy will EPERM set_robust_list(2), but on systems with + // SECCOMP logs enabled in auditd this will cause a ton of logspam. + // If we're not blocking the entire futex(2) infrastructure, we should allow + // set_robust_list(2) and quiet the logspam. + if (system_call_number == __NR_set_robust_list) { + return Allow(); + } + + return baseline_policy_->EvaluateSyscall(system_call_number); +} + +ResultExpr BPFBasePolicy::InvalidSyscall() const { + DCHECK(baseline_policy_); + return baseline_policy_->InvalidSyscall(); +} + +int BPFBasePolicy::GetFSDeniedErrno() { + return kFSDeniedErrno; +} + +} // namespace policy +} // namespace sandbox. diff --git a/chromium/sandbox/policy/linux/bpf_base_policy_linux.h b/chromium/sandbox/policy/linux/bpf_base_policy_linux.h new file mode 100644 index 00000000000..57152a0aafb --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_base_policy_linux.h @@ -0,0 +1,46 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_BASE_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_BASE_POLICY_LINUX_H_ + +#include <memory> + +#include "base/macros.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h" +#include "sandbox/linux/bpf_dsl/policy.h" +#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" +#include "sandbox/policy/export.h" + +namespace sandbox { +namespace policy { + +// The "baseline" BPF policy. Any other seccomp-bpf policy should inherit +// from it. +// It implements the main Policy interface. Due to its nature +// as a "kernel attack surface reduction" layer, it's implementation-defined. +class SANDBOX_POLICY_EXPORT BPFBasePolicy : public bpf_dsl::Policy { + public: + BPFBasePolicy(); + ~BPFBasePolicy() override; + + // bpf_dsl::Policy: + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + bpf_dsl::ResultExpr InvalidSyscall() const override; + + // Get the errno(3) to return for filesystem errors. + static int GetFSDeniedErrno(); + + pid_t GetPolicyPid() const { return baseline_policy_->policy_pid(); } + + private: + // Compose the BaselinePolicy from sandbox/. + std::unique_ptr<BaselinePolicy> baseline_policy_; + DISALLOW_COPY_AND_ASSIGN(BPFBasePolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_BASE_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_broker_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_broker_policy_linux.cc new file mode 100644 index 00000000000..2963bb9ca86 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_broker_policy_linux.cc @@ -0,0 +1,151 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_broker_policy_linux.h" + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +BrokerProcessPolicy::BrokerProcessPolicy( + const syscall_broker::BrokerCommandSet& allowed_command_set) + : allowed_command_set_(allowed_command_set) {} + +BrokerProcessPolicy::~BrokerProcessPolicy() {} + +ResultExpr BrokerProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { +#if defined(__NR_access) + case __NR_access: + if (allowed_command_set_.test(syscall_broker::COMMAND_ACCESS)) + return Allow(); + break; +#endif +#if defined(__NR_faccessat) + case __NR_faccessat: + if (allowed_command_set_.test(syscall_broker::COMMAND_ACCESS)) + return Allow(); + break; +#endif +#if defined(__NR_mkdir) + case __NR_mkdir: + if (allowed_command_set_.test(syscall_broker::COMMAND_MKDIR)) + return Allow(); + break; +#endif +#if defined(__NR_mkdirat) + case __NR_mkdirat: + if (allowed_command_set_.test(syscall_broker::COMMAND_MKDIR)) + return Allow(); + break; +#endif +#if defined(__NR_open) + case __NR_open: + if (allowed_command_set_.test(syscall_broker::COMMAND_OPEN)) + return Allow(); + break; +#endif +#if defined(__NR_openat) + case __NR_openat: + if (allowed_command_set_.test(syscall_broker::COMMAND_OPEN)) + return Allow(); + break; +#endif +#if defined(__NR_rename) + case __NR_rename: + if (allowed_command_set_.test(syscall_broker::COMMAND_RENAME)) + return Allow(); + break; +#endif +#if defined(__NR_renameat) + case __NR_renameat: + if (allowed_command_set_.test(syscall_broker::COMMAND_RENAME)) + return Allow(); + break; +#endif +#if defined(__NR_stat) + case __NR_stat: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_stat64) + case __NR_stat64: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_lstat) + case __NR_lstat: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_lstat64) + case __NR_lstat64: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_fstatat) + case __NR_fstatat: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_newfstatat) + case __NR_newfstatat: + if (allowed_command_set_.test(syscall_broker::COMMAND_STAT)) + return Allow(); + break; +#endif +#if defined(__NR_readlink) + case __NR_readlink: + if (allowed_command_set_.test(syscall_broker::COMMAND_READLINK)) + return Allow(); + break; +#endif +#if defined(__NR_readlinkat) + case __NR_readlinkat: + if (allowed_command_set_.test(syscall_broker::COMMAND_READLINK)) + return Allow(); + break; +#endif +#if defined(__NR_rmdir) + case __NR_rmdir: + if (allowed_command_set_.test(syscall_broker::COMMAND_RMDIR)) + return Allow(); + break; +#endif +#if defined(__NR_unlink) + case __NR_unlink: + // NOTE: Open() uses unlink() to make "temporary" files. + if (allowed_command_set_.test(syscall_broker::COMMAND_OPEN) || + allowed_command_set_.test(syscall_broker::COMMAND_UNLINK)) { + return Allow(); + } + break; +#endif +#if defined(__NR_unlinkat) + case __NR_unlinkat: + // NOTE: Open() uses unlink() to make "temporary" files. + if (allowed_command_set_.test(syscall_broker::COMMAND_OPEN) || + allowed_command_set_.test(syscall_broker::COMMAND_UNLINK)) { + return Allow(); + } + break; +#endif + default: + break; + } + return BPFBasePolicy::EvaluateSyscall(sysno); +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_broker_policy_linux.h b/chromium/sandbox/policy/linux/bpf_broker_policy_linux.h new file mode 100644 index 00000000000..0fe3515a985 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_broker_policy_linux.h @@ -0,0 +1,35 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_BROKER_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_BROKER_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/syscall_broker/broker_command.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// A broker policy is one for a privileged syscall broker that allows +// access, open, openat, and (in the non-Chrome OS case) unlink. +class SANDBOX_POLICY_EXPORT BrokerProcessPolicy : public BPFBasePolicy { + public: + explicit BrokerProcessPolicy( + const syscall_broker::BrokerCommandSet& allowed_command_set); + ~BrokerProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + const syscall_broker::BrokerCommandSet allowed_command_set_; + + DISALLOW_COPY_AND_ASSIGN(BrokerProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_BROKER_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.cc new file mode 100644 index 00000000000..1181e7291d7 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.cc @@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_cdm_policy_linux.h" + +#include <errno.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +CdmProcessPolicy::CdmProcessPolicy() {} +CdmProcessPolicy::~CdmProcessPolicy() {} + +ResultExpr CdmProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + case __NR_ioctl: + return RestrictIoctl(); + // Allow the system calls below. + case __NR_fdatasync: + case __NR_fsync: + case __NR_ftruncate: + case __NR_fallocate: +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ + defined(__aarch64__) + case __NR_getrlimit: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // https://crbug.com/546204 + case __NR_pwrite64: + case __NR_sysinfo: + case __NR_times: + case __NR_uname: + return Allow(); + case __NR_sched_getaffinity: + return RestrictSchedTarget(GetPolicyPid(), sysno); + default: + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.h b/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.h new file mode 100644 index 00000000000..ebf7de5f583 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cdm_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_CDM_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_CDM_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy can be used by the process hosting a Content Decryption Module. +class CdmProcessPolicy : public BPFBasePolicy { + public: + CdmProcessPolicy(); + ~CdmProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(CdmProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_CDM_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc new file mode 100644 index 00000000000..0506ef37d6b --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h" + +#include <errno.h> +#include <fcntl.h> +#include <linux/kcmp.h> +#include <sys/socket.h> + +// Some arch's (arm64 for instance) unistd.h don't pull in symbols used here +// unless these are defined. +#define __ARCH_WANT_SYSCALL_NO_AT +#define __ARCH_WANT_SYSCALL_DEPRECATED +#include <unistd.h> + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" + +using sandbox::bpf_dsl::AllOf; +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Arg; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::If; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +CrosAmdGpuProcessPolicy::CrosAmdGpuProcessPolicy() {} + +CrosAmdGpuProcessPolicy::~CrosAmdGpuProcessPolicy() {} + +ResultExpr CrosAmdGpuProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + case __NR_fstatfs: + case __NR_sched_setscheduler: + case __NR_sysinfo: + case __NR_uname: +#if !defined(__aarch64__) + case __NR_readlink: + case __NR_stat: +#endif + return Allow(); +#if defined(__x86_64__) + // Allow only AF_UNIX for |domain|. + case __NR_socket: + case __NR_socketpair: { + const Arg<int> domain(0); + return If(domain == AF_UNIX, Allow()).Else(Error(EPERM)); + } +#endif + case __NR_kcmp: { + const Arg<int> pid1(0); + const Arg<int> pid2(1); + const Arg<int> type(2); + const int policy_pid = GetPolicyPid(); + // Only allowed when comparing file handles for the calling thread. + return If(AllOf(pid1 == policy_pid, pid2 == policy_pid, + type == KCMP_FILE), + Allow()) + .Else(Error(EPERM)); + } + default: + // Default to the generic GPU policy. + return GpuProcessPolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h b/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h new file mode 100644 index 00000000000..305128c1b95 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h @@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_gpu_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy is for AMD GPUs running on Chrome OS. +class SANDBOX_POLICY_EXPORT CrosAmdGpuProcessPolicy : public GpuProcessPolicy { + public: + CrosAmdGpuProcessPolicy(); + ~CrosAmdGpuProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(CrosAmdGpuProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_CROS_AMD_GPU_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc new file mode 100644 index 00000000000..819cd9dcbd2 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h" + +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Arg; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::If; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat) +#if defined(__arm__) || defined(__aarch64__) + : allow_shmat_(allow_shmat) +#endif +{ +} + +CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {} + +ResultExpr CrosArmGpuProcessPolicy::EvaluateSyscall(int sysno) const { +#if defined(__arm__) || defined(__aarch64__) + if (allow_shmat_ && sysno == __NR_shmat) + return Allow(); +#endif // defined(__arm__) || defined(__aarch64__) + + switch (sysno) { +#if defined(__arm__) || defined(__aarch64__) + // ARM GPU sandbox is started earlier so we need to allow networking + // in the sandbox. + case __NR_connect: + case __NR_getpeername: + case __NR_getsockname: + case __NR_sysinfo: + case __NR_uname: + return Allow(); + // Allow only AF_UNIX for |domain|. + case __NR_socket: + case __NR_socketpair: { + const Arg<int> domain(0); + return If(domain == AF_UNIX, Allow()).Else(Error(EPERM)); + } +#endif // defined(__arm__) || defined(__aarch64__) + default: + // Default to the generic GPU policy. + return GpuProcessPolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h b/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h new file mode 100644 index 00000000000..2b7ad4086f7 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h @@ -0,0 +1,33 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_gpu_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy is for Chrome OS ARM. +class SANDBOX_POLICY_EXPORT CrosArmGpuProcessPolicy : public GpuProcessPolicy { + public: + explicit CrosArmGpuProcessPolicy(bool allow_shmat); + ~CrosArmGpuProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: +#if defined(__arm__) || defined(__aarch64__) + const bool allow_shmat_; // Allow shmat(2). +#endif + DISALLOW_COPY_AND_ASSIGN(CrosArmGpuProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.cc new file mode 100644 index 00000000000..127989715b3 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.cc @@ -0,0 +1,113 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_gpu_policy_linux.h" + +#include <errno.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" +#include "sandbox/policy/linux/sandbox_linux.h" +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Arg; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +GpuProcessPolicy::GpuProcessPolicy() {} + +GpuProcessPolicy::~GpuProcessPolicy() {} + +// Main policy for x86_64/i386. Extended by CrosArmGpuProcessPolicy. +ResultExpr GpuProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + case __NR_kcmp: + return Error(ENOSYS); +#if !defined(OS_CHROMEOS) + case __NR_fallocate: + return Allow(); +#endif // defined(OS_CHROMEOS) + case __NR_fcntl: { + // The Nvidia driver uses flags not in the baseline policy + // fcntl(fd, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW) + // https://crbug.com/1128175 + const Arg<int> cmd(1); + const Arg<long> long_arg(2); + + const uint64_t kAllowedMask = F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW; + if (cmd == F_ADD_SEALS && (long_arg & ~kAllowedMask) == 0) + return Allow(); + + break; + } + case __NR_ftruncate: +#if defined(__i386__) || defined(__arm__) || \ + (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS)) + case __NR_ftruncate64: +#endif +#if !defined(__aarch64__) + case __NR_getdents: +#endif + case __NR_getdents64: + case __NR_ioctl: + case __NR_memfd_create: + return Allow(); +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) + // The Nvidia driver uses flags not in the baseline policy + // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) + case __NR_mmap: + return Allow(); +#endif + // We also hit this on the linux_chromeos bot but don't yet know what + // weird flags were involved. + case __NR_mprotect: + // TODO(jln): restrict prctl. + case __NR_prctl: + case __NR_sysinfo: + case __NR_uname: // https://crbug.com/1075934 + return Allow(); + case __NR_sched_getaffinity: + case __NR_sched_setaffinity: + return RestrictSchedTarget(GetPolicyPid(), sysno); + case __NR_prlimit64: + return RestrictPrlimit64(GetPolicyPid()); + default: + break; + } + if (SyscallSets::IsEventFd(sysno)) + return Allow(); + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11) + if (SyscallSets::IsSystemVSharedMemory(sysno)) + return Allow(); +#endif + + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) { + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + } + + // Default on the baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.h b/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.h new file mode 100644 index 00000000000..a76a6362524 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_gpu_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_GPU_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_GPU_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT GpuProcessPolicy : public BPFBasePolicy { + public: + GpuProcessPolicy(); + ~GpuProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_GPU_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_ime_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_ime_policy_linux.cc new file mode 100644 index 00000000000..4d6147a2ebd --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_ime_policy_linux.cc @@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_ime_policy_linux.h" + +#include <sys/socket.h> + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +ImeProcessPolicy::ImeProcessPolicy() {} + +ImeProcessPolicy::~ImeProcessPolicy() {} + +ResultExpr ImeProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { +#if defined(__NR_uname) + case __NR_uname: +#endif +#if defined(__NR_clock_gettime) + case __NR_clock_gettime: +#endif + return Allow(); +// https://crbug.com/991435 +#if defined(__NR_getrusage) + case __NR_getrusage: + return RestrictGetrusage(); +#endif + default: + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_ime_policy_linux.h b/chromium/sandbox/policy/linux/bpf_ime_policy_linux.h new file mode 100644 index 00000000000..2ecb90bf7f8 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_ime_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_IME_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_IME_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT ImeProcessPolicy : public BPFBasePolicy { + public: + ImeProcessPolicy(); + ~ImeProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int sysno) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(ImeProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_IME_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_network_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_network_policy_linux.cc new file mode 100644 index 00000000000..2cdcc797d8e --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_network_policy_linux.cc @@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_network_policy_linux.h" + +#include <fcntl.h> +#include <unistd.h> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/syscall_broker/broker_file_permission.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" +#include "sandbox/policy/linux/sandbox_linux.h" +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +NetworkProcessPolicy::NetworkProcessPolicy() {} + +NetworkProcessPolicy::~NetworkProcessPolicy() {} + +ResultExpr NetworkProcessPolicy::EvaluateSyscall(int sysno) const { + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) { + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + } + + // TODO(tsepez): FIX this. + return Allow(); +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_network_policy_linux.h b/chromium/sandbox/policy/linux/bpf_network_policy_linux.h new file mode 100644 index 00000000000..09d25c03c70 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_network_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_NETWORK_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_NETWORK_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT NetworkProcessPolicy : public BPFBasePolicy { + public: + NetworkProcessPolicy(); + ~NetworkProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_NETWORK_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.cc new file mode 100644 index 00000000000..1465de67d7a --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.cc @@ -0,0 +1,50 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_ppapi_policy_linux.h" + +#include <errno.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +PpapiProcessPolicy::PpapiProcessPolicy() {} +PpapiProcessPolicy::~PpapiProcessPolicy() {} + +ResultExpr PpapiProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + // TODO(jln): restrict prctl. + case __NR_prctl: + case __NR_pwrite64: + case __NR_sched_get_priority_max: + case __NR_sched_get_priority_min: + case __NR_sysinfo: + case __NR_times: + return Allow(); + case __NR_sched_getaffinity: + case __NR_sched_getparam: + case __NR_sched_getscheduler: + case __NR_sched_setscheduler: + return RestrictSchedTarget(GetPolicyPid(), sysno); + case __NR_ioctl: + return Error(ENOTTY); // Flash Access. + default: + // Default on the baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.h b/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.h new file mode 100644 index 00000000000..f90553471ad --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_ppapi_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_PPAPI_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_PPAPI_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// Policy for Pepper plugins such as Flash. +class PpapiProcessPolicy : public BPFBasePolicy { + public: + PpapiProcessPolicy(); + ~PpapiProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(PpapiProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_PPAPI_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.cc new file mode 100644 index 00000000000..4a234d79144 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.cc @@ -0,0 +1,55 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_print_compositor_policy_linux.h" + +#include <errno.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +PrintCompositorProcessPolicy::PrintCompositorProcessPolicy() {} +PrintCompositorProcessPolicy::~PrintCompositorProcessPolicy() {} + +ResultExpr PrintCompositorProcessPolicy::EvaluateSyscall(int sysno) const { + // TODO(weili): the current set of policy is exactly same as utility process + // policy. Check whether we can trim further. + switch (sysno) { + case __NR_ioctl: + return RestrictIoctl(); + // Allow the system calls below. + case __NR_fdatasync: + case __NR_fsync: +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ + defined(__aarch64__) + case __NR_getrlimit: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // https://crbug.com/546204 + case __NR_pwrite64: + case __NR_sysinfo: + case __NR_times: + case __NR_uname: + return Allow(); + default: + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.h b/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.h new file mode 100644 index 00000000000..4d082c37d55 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_print_compositor_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_PRINT_COMPOSITOR_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_PRINT_COMPOSITOR_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy can be used by print compositor utility processes. +class PrintCompositorProcessPolicy : public BPFBasePolicy { + public: + PrintCompositorProcessPolicy(); + ~PrintCompositorProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(PrintCompositorProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_PRINT_COMPOSITOR_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.cc new file mode 100644 index 00000000000..9fe9575eb63 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.cc @@ -0,0 +1,112 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_renderer_policy_linux.h" + +#include <errno.h> +#include <sys/ioctl.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +// TODO(vignatti): replace the local definitions below with #include +// <linux/dma-buf.h> once kernel version 4.6 becomes widely used. +#include <linux/types.h> + +struct local_dma_buf_sync { + __u64 flags; +}; +#define LOCAL_DMA_BUF_BASE 'b' +#define LOCAL_DMA_BUF_IOCTL_SYNC \ + _IOW(LOCAL_DMA_BUF_BASE, 0, struct local_dma_buf_sync) + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Arg; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +namespace { + +ResultExpr RestrictIoctl() { + const Arg<unsigned long> request(1); + return Switch(request) + .SANDBOX_BPF_DSL_CASES((static_cast<unsigned long>(TCGETS), FIONREAD), + Allow()) + .SANDBOX_BPF_DSL_CASES( + (static_cast<unsigned long>(LOCAL_DMA_BUF_IOCTL_SYNC)), Allow()) + .Default(CrashSIGSYSIoctl()); +} + +} // namespace + +RendererProcessPolicy::RendererProcessPolicy() {} +RendererProcessPolicy::~RendererProcessPolicy() {} + +ResultExpr RendererProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + // The baseline policy allows __NR_clock_gettime. Allow + // clock_getres() for V8. crbug.com/329053. + case __NR_clock_getres: + return RestrictClockID(); + case __NR_ioctl: + return RestrictIoctl(); + // Allow the system calls below. + case __NR_fdatasync: + case __NR_fsync: + case __NR_ftruncate: +#if defined(__i386__) || defined(__arm__) || \ + (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS)) + case __NR_ftruncate64: +#endif +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ + defined(__aarch64__) + case __NR_getrlimit: + case __NR_setrlimit: +// We allow setrlimit to dynamically adjust the address space limit as +// needed for WebAssembly memory objects (https://crbug.com/750378). Even +// with setrlimit being allowed, we cannot raise rlim_max once it's +// lowered. Thus we generally have the same protection because we normally +// set rlim_max and rlim_cur together. +// +// See SandboxLinux::LimitAddressSpace() in +// sandbox/policy/linux/sandbox_linux.cc and +// ArrayBufferContents::ReserveMemory, +// ArrayBufferContents::ReleaseReservedMemory in +// third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferContents.cpp. +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // See crbug.com/149834. + case __NR_pwrite64: + case __NR_sched_get_priority_max: + case __NR_sched_get_priority_min: + case __NR_sysinfo: + case __NR_times: + case __NR_uname: + return Allow(); + case __NR_sched_getaffinity: + case __NR_sched_getparam: + case __NR_sched_getscheduler: + case __NR_sched_setscheduler: + return RestrictSchedTarget(GetPolicyPid(), sysno); + case __NR_prlimit64: + // See crbug.com/662450 and setrlimit comment above. + return RestrictPrlimit(GetPolicyPid()); + default: + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.h b/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.h new file mode 100644 index 00000000000..01351e3694a --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_renderer_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_RENDERER_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_RENDERER_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy can be used by both renderer and worker processes. +class RendererProcessPolicy : public BPFBasePolicy { + public: + RendererProcessPolicy(); + ~RendererProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(RendererProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_RENDERER_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.cc new file mode 100644 index 00000000000..91c12ca9ce8 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.cc @@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_sharing_service_policy_linux.h" + +#include <errno.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +ResultExpr SharingServiceProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + case __NR_ioctl: + return RestrictIoctl(); + // Allow the system calls below. +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ + defined(__aarch64__) + case __NR_getrlimit: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // https://crbug.com/546204 + case __NR_pwrite64: + case __NR_times: + return Allow(); + default: + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.h b/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.h new file mode 100644 index 00000000000..bde3ffa2a38 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_sharing_service_policy_linux.h @@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_SHARING_SERVICE_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_SHARING_SERVICE_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy can be used by the Sharing service to host WebRTC. +class SharingServiceProcessPolicy : public BPFBasePolicy { + public: + SharingServiceProcessPolicy() = default; + ~SharingServiceProcessPolicy() override = default; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + SharingServiceProcessPolicy(const SharingServiceProcessPolicy&) = delete; + SharingServiceProcessPolicy& operator=(const SharingServiceProcessPolicy&) = + delete; +}; + +} // namespace policy +} // namespace sandbox + +#endif // SERVICES_SERVICE_MANAGER_SANDBOX_LINUX_BPF_UTILITY_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.cc new file mode 100644 index 00000000000..d02983ca53f --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.cc @@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_speech_recognition_policy_linux.h" + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +SpeechRecognitionProcessPolicy::SpeechRecognitionProcessPolicy() = default; +SpeechRecognitionProcessPolicy::~SpeechRecognitionProcessPolicy() = default; + +ResultExpr SpeechRecognitionProcessPolicy::EvaluateSyscall( + int system_call_number) const { + switch (system_call_number) { + default: + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(system_call_number)) + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(system_call_number); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.h b/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.h new file mode 100644 index 00000000000..f31e8529e65 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_speech_recognition_policy_linux.h @@ -0,0 +1,32 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_SPEECH_RECOGNITION_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_SPEECH_RECOGNITION_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// The process policy for the sandboxed utility process that loads the Speech +// On-Device API (SODA). This policy allows the syscalls used by the libsoda.so +// binary to transcribe audio into text. +class SANDBOX_POLICY_EXPORT SpeechRecognitionProcessPolicy + : public BPFBasePolicy { + public: + SpeechRecognitionProcessPolicy(); + ~SpeechRecognitionProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_SPEECH_RECOGNITION_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_tts_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_tts_policy_linux.cc new file mode 100644 index 00000000000..f39a05de9f3 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_tts_policy_linux.cc @@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_tts_policy_linux.h" + +#include <sys/socket.h> + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; +using sandbox::bpf_dsl::Trap; +using sandbox::syscall_broker::BrokerProcess; + +namespace sandbox { +namespace policy { + +TtsProcessPolicy::TtsProcessPolicy() {} + +TtsProcessPolicy::~TtsProcessPolicy() {} + +ResultExpr TtsProcessPolicy::EvaluateSyscall(int sysno) const { + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + + return BPFBasePolicy::EvaluateSyscall(sysno); +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_tts_policy_linux.h b/chromium/sandbox/policy/linux/bpf_tts_policy_linux.h new file mode 100644 index 00000000000..9e4dd92741d --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_tts_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_TTS_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_TTS_POLICY_LINUX_H_ + +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT TtsProcessPolicy : public BPFBasePolicy { + public: + TtsProcessPolicy(); + ~TtsProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int sysno) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(TtsProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_TTS_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/bpf_utility_policy_linux.cc b/chromium/sandbox/policy/linux/bpf_utility_policy_linux.cc new file mode 100644 index 00000000000..dfe9e9c55a7 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_utility_policy_linux.cc @@ -0,0 +1,56 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/bpf_utility_policy_linux.h" + +#include <errno.h> + +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/sandbox_linux.h" + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::Error; +using sandbox::bpf_dsl::ResultExpr; + +namespace sandbox { +namespace policy { + +UtilityProcessPolicy::UtilityProcessPolicy() {} +UtilityProcessPolicy::~UtilityProcessPolicy() {} + +ResultExpr UtilityProcessPolicy::EvaluateSyscall(int sysno) const { + switch (sysno) { + case __NR_ioctl: + return RestrictIoctl(); + case __NR_prlimit64: + // Restrict prlimit() to reference only the calling process. + return RestrictPrlimitToGetrlimit(GetPolicyPid()); + // Allow the system calls below. + case __NR_fdatasync: + case __NR_fsync: +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \ + defined(__aarch64__) + case __NR_getrlimit: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // https://crbug.com/546204 + case __NR_pwrite64: + case __NR_sysinfo: + case __NR_times: + case __NR_uname: + return Allow(); + default: + // Default on the content baseline policy. + return BPFBasePolicy::EvaluateSyscall(sysno); + } +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/bpf_utility_policy_linux.h b/chromium/sandbox/policy/linux/bpf_utility_policy_linux.h new file mode 100644 index 00000000000..fea3ea43ab1 --- /dev/null +++ b/chromium/sandbox/policy/linux/bpf_utility_policy_linux.h @@ -0,0 +1,29 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_BPF_UTILITY_POLICY_LINUX_H_ +#define SANDBOX_POLICY_LINUX_BPF_UTILITY_POLICY_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" + +namespace sandbox { +namespace policy { + +// This policy can be used by utility processes. +class UtilityProcessPolicy : public BPFBasePolicy { + public: + UtilityProcessPolicy(); + ~UtilityProcessPolicy() override; + + bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(UtilityProcessPolicy); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_BPF_UTILITY_POLICY_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.cc b/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.cc new file mode 100644 index 00000000000..705df32a26a --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.cc @@ -0,0 +1,81 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/sandbox_debug_handling_linux.h" + +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <sys/prctl.h> +#include <unistd.h> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/strings/safe_sprintf.h" +#include "sandbox/policy/switches.h" + +namespace sandbox { +namespace policy { + +namespace { + +void DoChrootSignalHandler(int) { + const int old_errno = errno; + const char kFirstMessage[] = "Chroot signal handler called.\n"; + ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1)); + + const int chroot_ret = chroot("/"); + + char kSecondMessage[100]; + const ssize_t printed = base::strings::SafeSPrintf( + kSecondMessage, "chroot() returned %d. Errno is %d.\n", chroot_ret, + errno); + if (printed > 0 && printed < static_cast<ssize_t>(sizeof(kSecondMessage))) { + ignore_result(write(STDERR_FILENO, kSecondMessage, printed)); + } + errno = old_errno; +} + +// This is a quick hack to allow testing sandbox crash reports in production +// binaries. +// This installs a signal handler for SIGUSR2 that performs a chroot(). +// In most of our BPF policies, it is a "watched" system call which will +// trigger a SIGSYS signal whose handler will crash. +// This has been added during the investigation of https://crbug.com/415842. +void InstallCrashTestHandler() { + struct sigaction act = {}; + act.sa_handler = DoChrootSignalHandler; + CHECK_EQ(0, sigemptyset(&act.sa_mask)); + act.sa_flags = 0; + + PCHECK(0 == sigaction(SIGUSR2, &act, NULL)); +} + +bool IsSandboxDebuggingEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAllowSandboxDebugging); +} + +} // namespace + +// static +bool SandboxDebugHandling::SetDumpableStatusAndHandlers() { + if (IsSandboxDebuggingEnabled()) { + // If sandbox debugging is allowed, install a handler for sandbox-related + // crash testing. + InstallCrashTestHandler(); + return true; + } + + if (prctl(PR_SET_DUMPABLE, 0) != 0) { + PLOG(ERROR) << "Failed to set non-dumpable flag"; + return false; + } + + return prctl(PR_GET_DUMPABLE) == 0; +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.h b/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.h new file mode 100644 index 00000000000..60ad0b21c28 --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_debug_handling_linux.h @@ -0,0 +1,28 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_ +#define SANDBOX_POLICY_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_ + +#include "base/macros.h" +#include "sandbox/policy/export.h" + +namespace sandbox { +namespace policy { + +class SANDBOX_POLICY_EXPORT SandboxDebugHandling { + public: + // Depending on the command line, set the current process as + // non dumpable. Also set any signal handlers for sandbox + // debugging. + static bool SetDumpableStatusAndHandlers(); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxDebugHandling); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_SANDBOX_DEBUG_HANDLING_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/sandbox_linux.cc b/chromium/sandbox/policy/linux/sandbox_linux.cc new file mode 100644 index 00000000000..a2f1150a0b6 --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_linux.cc @@ -0,0 +1,570 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/sandbox_linux.h" + +#include <dirent.h> +#include <fcntl.h> +#include <stdint.h> +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> + +#include <limits> +#include <memory> +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/files/scoped_file.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "base/posix/eintr_wrapper.h" +#include "base/strings/string_number_conversions.h" +#include "base/system/sys_info.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "sandbox/constants.h" +#include "sandbox/linux/services/credentials.h" +#include "sandbox/linux/services/libc_interceptor.h" +#include "sandbox/linux/services/namespace_sandbox.h" +#include "sandbox/linux/services/proc_util.h" +#include "sandbox/linux/services/resource_limits.h" +#include "sandbox/linux/services/thread_helpers.h" +#include "sandbox/linux/services/yama.h" +#include "sandbox/linux/suid/client/setuid_sandbox_client.h" +#include "sandbox/linux/syscall_broker/broker_command.h" +#include "sandbox/linux/syscall_broker/broker_process.h" +#include "sandbox/policy/linux/bpf_broker_policy_linux.h" +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" +#include "sandbox/policy/sandbox.h" +#include "sandbox/policy/sandbox_type.h" +#include "sandbox/policy/switches.h" +#include "sandbox/sandbox_buildflags.h" + +#if BUILDFLAG(USING_SANITIZER) +#include <sanitizer/common_interface_defs.h> +#endif + +namespace sandbox { +namespace policy { + +namespace { + +void LogSandboxStarted(const std::string& sandbox_name) { + const std::string process_type = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + service_manager::switches::kProcessType); + const std::string activated_sandbox = + "Activated " + sandbox_name + + " sandbox for process type: " + process_type + "."; + VLOG(1) << activated_sandbox; +} + +bool IsRunningTSAN() { +#if defined(THREAD_SANITIZER) + return true; +#else + return false; +#endif +} + +// Get a file descriptor to /proc. Either duplicate |proc_fd| or try to open +// it by using the filesystem directly. +// TODO(jln): get rid of this ugly interface. +base::ScopedFD OpenProc(int proc_fd) { + int ret_proc_fd = -1; + if (proc_fd >= 0) { + // If a handle to /proc is available, use it. This allows to bypass file + // system restrictions. + ret_proc_fd = + HANDLE_EINTR(openat(proc_fd, ".", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); + } else { + // Otherwise, make an attempt to access the file system directly. + ret_proc_fd = HANDLE_EINTR( + openat(AT_FDCWD, "/proc/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); + } + DCHECK_LE(0, ret_proc_fd); + return base::ScopedFD(ret_proc_fd); +} + +bool UpdateProcessTypeAndEnableSandbox( + SandboxLinux::PreSandboxHook broker_side_hook, + SandboxLinux::Options options, + syscall_broker::BrokerCommandSet allowed_command_set) { + base::CommandLine::StringVector exec = + base::CommandLine::ForCurrentProcess()->GetArgs(); + base::CommandLine::Reset(); + base::CommandLine::Init(0, nullptr); + base::CommandLine::ForCurrentProcess()->InitFromArgv(exec); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + std::string new_process_type = command_line->GetSwitchValueASCII( + service_manager::switches::kProcessType); + if (!new_process_type.empty()) { + new_process_type.append("-broker"); + } else { + new_process_type = "broker"; + } + + VLOG(3) << "UpdateProcessTypeAndEnableSandbox: Updating process type to " + << new_process_type; + command_line->AppendSwitchASCII(service_manager::switches::kProcessType, + new_process_type); + + if (broker_side_hook) + CHECK(std::move(broker_side_hook).Run(options)); + + return SandboxSeccompBPF::StartSandboxWithExternalPolicy( + std::make_unique<BrokerProcessPolicy>(allowed_command_set), + base::ScopedFD()); +} + +} // namespace + +SandboxLinux::SandboxLinux() + : proc_fd_(-1), + seccomp_bpf_started_(false), + sandbox_status_flags_(kInvalid), + pre_initialized_(false), + seccomp_bpf_supported_(false), + seccomp_bpf_with_tsync_supported_(false), + yama_is_enforcing_(false), + initialize_sandbox_ran_(false), + setuid_sandbox_client_(SetuidSandboxClient::Create()), + broker_process_(nullptr) { + if (!setuid_sandbox_client_) { + LOG(FATAL) << "Failed to instantiate the setuid sandbox client."; + } +#if BUILDFLAG(USING_SANITIZER) + sanitizer_args_ = std::make_unique<__sanitizer_sandbox_arguments>(); + *sanitizer_args_ = {0}; +#endif +} + +SandboxLinux::~SandboxLinux() { + if (pre_initialized_) { + CHECK(initialize_sandbox_ran_); + } +} + +SandboxLinux* SandboxLinux::GetInstance() { + SandboxLinux* instance = base::Singleton<SandboxLinux>::get(); + CHECK(instance); + return instance; +} + +void SandboxLinux::PreinitializeSandbox() { + CHECK(!pre_initialized_); + seccomp_bpf_supported_ = false; +#if BUILDFLAG(USING_SANITIZER) + // Sanitizers need to open some resources before the sandbox is enabled. + // This should not fork, not launch threads, not open a directory. + __sanitizer_sandbox_on_notify(sanitizer_args()); + sanitizer_args_.reset(); +#endif + + // Open proc_fd_. It would break the security of the setuid sandbox if it was + // not closed. + // If SandboxLinux::PreinitializeSandbox() runs, InitializeSandbox() must run + // as well. + proc_fd_ = HANDLE_EINTR(open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC)); + CHECK_GE(proc_fd_, 0); + // We "pre-warm" the code that detects supports for seccomp BPF. + if (SandboxSeccompBPF::IsSeccompBPFDesired()) { + if (!SandboxSeccompBPF::SupportsSandbox()) { + VLOG(1) << "Lacking support for seccomp-bpf sandbox."; + } else { + seccomp_bpf_supported_ = true; + } + + if (SandboxSeccompBPF::SupportsSandboxWithTsync()) { + seccomp_bpf_with_tsync_supported_ = true; + } + } + + // Yama is a "global", system-level status. We assume it will not regress + // after startup. + const int yama_status = Yama::GetStatus(); + yama_is_enforcing_ = (yama_status & Yama::STATUS_PRESENT) && + (yama_status & Yama::STATUS_ENFORCING); + pre_initialized_ = true; +} + +void SandboxLinux::EngageNamespaceSandbox(bool from_zygote) { + CHECK(EngageNamespaceSandboxInternal(from_zygote)); +} + +bool SandboxLinux::EngageNamespaceSandboxIfPossible() { + return EngageNamespaceSandboxInternal(false /* from_zygote */); +} + +std::vector<int> SandboxLinux::GetFileDescriptorsToClose() { + std::vector<int> fds; + if (proc_fd_ >= 0) { + fds.push_back(proc_fd_); + } + return fds; +} + +int SandboxLinux::GetStatus() { + if (!pre_initialized_) { + return 0; + } + if (sandbox_status_flags_ == kInvalid) { + // Initialize sandbox_status_flags_. + sandbox_status_flags_ = 0; + if (setuid_sandbox_client_->IsSandboxed()) { + sandbox_status_flags_ |= kSUID; + if (setuid_sandbox_client_->IsInNewPIDNamespace()) + sandbox_status_flags_ |= kPIDNS; + if (setuid_sandbox_client_->IsInNewNETNamespace()) + sandbox_status_flags_ |= kNetNS; + } else if (NamespaceSandbox::InNewUserNamespace()) { + sandbox_status_flags_ |= kUserNS; + if (NamespaceSandbox::InNewPidNamespace()) + sandbox_status_flags_ |= kPIDNS; + if (NamespaceSandbox::InNewNetNamespace()) + sandbox_status_flags_ |= kNetNS; + } + + // We report whether the sandbox will be activated when renderers, workers + // and PPAPI plugins go through sandbox initialization. + if (seccomp_bpf_supported()) { + sandbox_status_flags_ |= kSeccompBPF; + } + + if (seccomp_bpf_with_tsync_supported()) { + sandbox_status_flags_ |= kSeccompTSYNC; + } + + if (yama_is_enforcing_) { + sandbox_status_flags_ |= kYama; + } + } + + return sandbox_status_flags_; +} + +// Threads are counted via /proc/self/task. This is a little hairy because of +// PID namespaces and existing sandboxes, so "self" must really be used instead +// of using the pid. +bool SandboxLinux::IsSingleThreaded() const { + base::ScopedFD proc_fd(OpenProc(proc_fd_)); + + CHECK(proc_fd.is_valid()) << "Could not count threads, the sandbox was not " + << "pre-initialized properly."; + + const bool is_single_threaded = + ThreadHelpers::IsSingleThreaded(proc_fd.get()); + + return is_single_threaded; +} + +bool SandboxLinux::seccomp_bpf_started() const { + return seccomp_bpf_started_; +} + +SetuidSandboxClient* SandboxLinux::setuid_sandbox_client() const { + return setuid_sandbox_client_.get(); +} + +// For seccomp-bpf, we use the SandboxSeccompBPF class. +bool SandboxLinux::StartSeccompBPF(SandboxType sandbox_type, + PreSandboxHook hook, + const Options& options) { + CHECK(!seccomp_bpf_started_); + CHECK(pre_initialized_); +#if BUILDFLAG(USE_SECCOMP_BPF) + if (!seccomp_bpf_supported()) + return false; + + if (IsUnsandboxedSandboxType(sandbox_type) || + !SandboxSeccompBPF::IsSeccompBPFDesired() || + !SandboxSeccompBPF::SupportsSandbox()) { + return true; + } + + if (hook) + CHECK(std::move(hook).Run(options)); + + // If we allow threads *and* have multiple threads, try to use TSYNC. + SandboxBPF::SeccompLevel seccomp_level = + options.allow_threads_during_sandbox_init && !IsSingleThreaded() + ? SandboxBPF::SeccompLevel::MULTI_THREADED + : SandboxBPF::SeccompLevel::SINGLE_THREADED; + + // If the kernel supports the sandbox, and if the command line says we + // should enable it, enable it or die. + std::unique_ptr<BPFBasePolicy> policy = + SandboxSeccompBPF::PolicyForSandboxType(sandbox_type, options); + SandboxSeccompBPF::StartSandboxWithExternalPolicy( + std::move(policy), OpenProc(proc_fd_), seccomp_level); + SandboxSeccompBPF::RunSandboxSanityChecks(sandbox_type, options); + seccomp_bpf_started_ = true; + LogSandboxStarted("seccomp-bpf"); + return true; +#else + return false; +#endif +} + +bool SandboxLinux::InitializeSandbox(SandboxType sandbox_type, + SandboxLinux::PreSandboxHook hook, + const Options& options) { + DCHECK(!initialize_sandbox_ran_); + initialize_sandbox_ran_ = true; + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + const std::string process_type = command_line->GetSwitchValueASCII( + service_manager::switches::kProcessType); + + // We need to make absolutely sure that our sandbox is "sealed" before + // returning. + // Unretained() since the current object is a Singleton. + base::ScopedClosureRunner sandbox_sealer( + base::BindOnce(&SandboxLinux::SealSandbox, base::Unretained(this))); + // Make sure that this function enables sandboxes as promised by GetStatus(). + // Unretained() since the current object is a Singleton. + base::ScopedClosureRunner sandbox_promise_keeper( + base::BindOnce(&SandboxLinux::CheckForBrokenPromises, + base::Unretained(this), sandbox_type)); + + const bool has_threads = !IsSingleThreaded(); + + // For now, restrict the |options.allow_threads_during_sandbox_init| option to + // the GPU process + DCHECK(process_type == switches::kGpuProcess || + !options.allow_threads_during_sandbox_init); + if (has_threads && !options.allow_threads_during_sandbox_init) { + std::string error_message = + "InitializeSandbox() called with multiple threads in process " + + process_type + "."; + // TSAN starts a helper thread, so we don't start the sandbox and don't + // even report an error about it. + if (IsRunningTSAN()) + return false; + + // The GPU process is allowed to call InitializeSandbox() with threads. + bool sandbox_failure_fatal = process_type != switches::kGpuProcess; + // This can be disabled with the '--gpu-sandbox-failures-fatal' flag. + // Setting the flag with no value or any value different than 'yes' or 'no' + // is equal to setting '--gpu-sandbox-failures-fatal=yes'. + if (process_type == switches::kGpuProcess && + command_line->HasSwitch(switches::kGpuSandboxFailuresFatal)) { + const std::string switch_value = + command_line->GetSwitchValueASCII(switches::kGpuSandboxFailuresFatal); + sandbox_failure_fatal = switch_value != "no"; + } + + if (sandbox_failure_fatal) { + error_message += " Try waiting for /proc to be updated."; + LOG(ERROR) << error_message; + // This will return if /proc/self eventually reports this process is + // single-threaded, or crash if it does not after a number of retries. + ThreadHelpers::AssertSingleThreaded(); + } else { + LOG(ERROR) << error_message; + return false; + } + } + + // At this point we are either single threaded, or we won't be engaging the + // semantic layer of the sandbox and we won't care if there are file + // descriptors left open. + + // Pre-initialize if not already done. + if (!pre_initialized_) + PreinitializeSandbox(); + + // Turn on the namespace sandbox if our caller wants it (and the zygote hasn't + // done so already). + if (options.engage_namespace_sandbox) + EngageNamespaceSandbox(false /* from_zygote */); + + // Check for open directories, which can break the semantic sandbox layer. In + // some cases the caller doesn't want to enable the semantic sandbox layer, + // and this CHECK should be skipped. In this case, the caller should unset + // |options.check_for_open_directories|. + CHECK(!options.check_for_open_directories || !HasOpenDirectories()) + << "InitializeSandbox() called after unexpected directories have been " + << "opened. This breaks the security of the setuid sandbox."; + + InitLibcLocaltimeFunctions(); + + // Attempt to limit the future size of the address space of the process. + // Fine to call with multiple threads as we don't use RLIMIT_STACK. + int error = 0; + const bool limited_as = LimitAddressSpace(&error); + if (error) { + // Restore errno. Internally to |LimitAddressSpace|, the errno due to + // setrlimit may be lost. + errno = error; + PCHECK(limited_as); + } + + return StartSeccompBPF(sandbox_type, std::move(hook), options); +} + +void SandboxLinux::StopThread(base::Thread* thread) { + DCHECK(thread); + StopThreadAndEnsureNotCounted(thread); +} + +bool SandboxLinux::seccomp_bpf_supported() const { + CHECK(pre_initialized_); + return seccomp_bpf_supported_; +} + +bool SandboxLinux::seccomp_bpf_with_tsync_supported() const { + CHECK(pre_initialized_); + return seccomp_bpf_with_tsync_supported_; +} + +rlim_t GetProcessDataSizeLimit(SandboxType sandbox_type) { +#if defined(ARCH_CPU_64_BITS) + if (sandbox_type == SandboxType::kGpu || + sandbox_type == SandboxType::kRenderer) { + // Allow the GPU/RENDERER process's sandbox to access more physical memory + // if it's available on the system. + // + // Renderer processes are allowed to access 16 GB; the GPU process, up + // to 64 GB. + constexpr rlim_t GB = 1024 * 1024 * 1024; + const rlim_t physical_memory = base::SysInfo::AmountOfPhysicalMemory(); + if (sandbox_type == SandboxType::kGpu && physical_memory > 64 * GB) { + return 64 * GB; + } else if (sandbox_type == SandboxType::kGpu && physical_memory > 32 * GB) { + return 32 * GB; + } else if (physical_memory > 16 * GB) { + return 16 * GB; + } else if (physical_memory > 8 * GB) { + return 8 * GB; + } + } +#endif + + return static_cast<rlim_t>(kDataSizeLimit); +} + +bool SandboxLinux::LimitAddressSpace(int* error) { +#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \ + !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER) + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + SandboxType sandbox_type = SandboxTypeFromCommandLine(*command_line); + if (sandbox_type == SandboxType::kNoSandbox) { + return false; + } + + // Unfortunately, it does not appear possible to set RLIMIT_AS such that it + // will both (a) be high enough to support V8's and WebAssembly's address + // space requirements while also (b) being low enough to mitigate exploits + // using integer overflows that require large allocations, heap spray, or + // other memory-hungry attack modes. + + rlim_t process_data_size_limit = GetProcessDataSizeLimit(sandbox_type); + // Fine to call with multiple threads as we don't use RLIMIT_STACK. + *error = ResourceLimits::Lower(RLIMIT_DATA, process_data_size_limit); + + // Cache the resource limit before turning on the sandbox. + base::SysInfo::AmountOfVirtualMemory(); + + return *error == 0; +#else + base::SysInfo::AmountOfVirtualMemory(); + return false; +#endif // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && + // !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER) +} + +void SandboxLinux::StartBrokerProcess( + const syscall_broker::BrokerCommandSet& allowed_command_set, + std::vector<syscall_broker::BrokerFilePermission> permissions, + PreSandboxHook broker_side_hook, + const Options& options) { + // Leaked at shutdown, so use bare |new|. + broker_process_ = new syscall_broker::BrokerProcess( + BPFBasePolicy::GetFSDeniedErrno(), allowed_command_set, permissions); + + // The initialization callback will perform generic initialization and then + // call broker_sandboxer_callback. + CHECK(broker_process_->Init(base::BindOnce(&UpdateProcessTypeAndEnableSandbox, + std::move(broker_side_hook), + options, allowed_command_set))); +} + +bool SandboxLinux::HasOpenDirectories() const { + return ProcUtil::HasOpenDirectory(proc_fd_); +} + +void SandboxLinux::SealSandbox() { + if (proc_fd_ >= 0) { + int ret = IGNORE_EINTR(close(proc_fd_)); + CHECK_EQ(0, ret); + proc_fd_ = -1; + } +} + +void SandboxLinux::CheckForBrokenPromises(SandboxType sandbox_type) { + if (sandbox_type != SandboxType::kRenderer && + sandbox_type != SandboxType::kPpapi) { + return; + } + // Make sure that any promise made with GetStatus() wasn't broken. + bool promised_seccomp_bpf_would_start = + (sandbox_status_flags_ != kInvalid) && (GetStatus() & kSeccompBPF); + CHECK(!promised_seccomp_bpf_would_start || seccomp_bpf_started_); +} + +void SandboxLinux::StopThreadAndEnsureNotCounted(base::Thread* thread) const { + DCHECK(thread); + base::ScopedFD proc_fd(OpenProc(proc_fd_)); + PCHECK(proc_fd.is_valid()); + CHECK(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.get(), thread)); +} + +bool SandboxLinux::EngageNamespaceSandboxInternal(bool from_zygote) { + CHECK(pre_initialized_); + CHECK(IsSingleThreaded()) + << "The process cannot have multiple threads when engaging the namespace " + "sandbox, because the thread engaging the sandbox cannot ensure that " + "other threads close all their open directories."; + + if (from_zygote) { + // Check being in a new PID namespace created by the namespace sandbox and + // being the init process. + CHECK(NamespaceSandbox::InNewPidNamespace()); + const pid_t pid = getpid(); + CHECK_EQ(1, pid); + } + + // After we successfully move to a new user ns, we don't allow this function + // to fail. + if (!Credentials::MoveToNewUserNS()) { + return false; + } + + // Note: this requires SealSandbox() to be called later in this process to be + // safe, as this class is keeping a file descriptor to /proc/. + CHECK(Credentials::DropFileSystemAccess(proc_fd_)); + + // Now we drop all capabilities that we can. In the zygote process, we need + // to keep CAP_SYS_ADMIN, to place each child in its own PID namespace + // later on. + std::vector<Credentials::Capability> caps; + if (from_zygote) { + caps.push_back(Credentials::Capability::SYS_ADMIN); + } + CHECK(Credentials::SetCapabilities(proc_fd_, caps)); + return true; +} + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/sandbox_linux.h b/chromium/sandbox/policy/linux/sandbox_linux.h new file mode 100644 index 00000000000..3f818b9ad3a --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_linux.h @@ -0,0 +1,299 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_SANDBOX_LINUX_H_ +#define SANDBOX_POLICY_LINUX_SANDBOX_LINUX_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/check_op.h" +#include "base/macros.h" +#include "base/posix/global_descriptors.h" +#include "sandbox/linux/syscall_broker/broker_command.h" +#include "sandbox/linux/syscall_broker/broker_file_permission.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" +#include "sandbox/policy/sandbox_type.h" +#include "sandbox/policy/sanitizer_buildflags.h" + +#if BUILDFLAG(USING_SANITIZER) +#include <sanitizer/common_interface_defs.h> +#endif + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +class Thread; +} // namespace base + +namespace sandbox { +namespace syscall_broker { +class BrokerProcess; +} // namespace syscall_broker +class SetuidSandboxClient; +} // namespace sandbox + +namespace sandbox { +namespace policy { + +// A singleton class to represent and change our sandboxing state for the +// three main Linux sandboxes. +// The sandboxing model allows using two layers of sandboxing. The first layer +// can be implemented either with unprivileged namespaces or with the setuid +// sandbox. This class provides a way to engage the namespace sandbox, but does +// not deal with the legacy setuid sandbox directly. +// The second layer is mainly based on seccomp-bpf and is engaged with +// InitializeSandbox(). InitializeSandbox() is also responsible for "sealing" +// the first layer of sandboxing. That is, InitializeSandbox must always be +// called to have any meaningful sandboxing at all. +class SANDBOX_POLICY_EXPORT SandboxLinux { + public: + // This is a list of sandbox IPC methods which the renderer may send to the + // sandbox host. See + // https://chromium.googlesource.com/chromium/src/+/master/docs/linux/sandbox_ipc.md + // This isn't the full list, values < 32 are reserved for methods called from + // Skia, and values < 64 are reserved for libc_interceptor.cc. + enum LinuxSandboxIPCMethods { + DEPRECATED_METHOD_GET_FALLBACK_FONT_FOR_CHAR = 64, + DEPRECATED_METHOD_GET_CHILD_WITH_INODE, + DEPRECATED_METHOD_GET_STYLE_FOR_STRIKE, + METHOD_MAKE_SHARED_MEMORY_SEGMENT, + DEPRECATED_METHOD_MATCH_WITH_FALLBACK, + }; + + // These form a bitmask which describes the conditions of the Linux sandbox. + // Note: this doesn't strictly give you the current status, it states + // what will be enabled when the relevant processes are initialized. + enum Status { + // SUID sandbox active. + kSUID = 1 << 0, + + // Sandbox is using a new PID namespace. + kPIDNS = 1 << 1, + + // Sandbox is using a new network namespace. + kNetNS = 1 << 2, + + // seccomp-bpf sandbox active. + kSeccompBPF = 1 << 3, + + // The Yama LSM module is present and enforcing. + kYama = 1 << 4, + + // seccomp-bpf sandbox is active and the kernel supports TSYNC. + kSeccompTSYNC = 1 << 5, + + // User namespace sandbox active. + kUserNS = 1 << 6, + + // A flag that denotes an invalid sandbox status. + kInvalid = 1 << 31, + }; + + // SandboxLinux Options are a superset of SandboxSecompBPF Options. + struct Options : public SandboxSeccompBPF::Options { + // When running with a zygote, the namespace sandbox will have already + // been engaged prior to initializing SandboxLinux itself, and need not + // be done so again. Set to true to indicate that there isn't a zygote + // for this process and the step is to be performed here explicitly. + bool engage_namespace_sandbox = false; + + // Allow starting the sandbox with multiple threads already running. This + // will enable TSYNC for seccomp-BPF, which syncs the seccomp-BPF policy + // across all running threads. + bool allow_threads_during_sandbox_init = false; + + // Enables the CHECK for open directories. The open directory check is only + // useful for the chroot jail (from the semantic layer of the sandbox), and + // can safely be disabled if we are only enabling the seccomp-BPF layer. + bool check_for_open_directories = true; + }; + + // Callers can provide this hook to run code right before the policy + // is passed to the BPF compiler and the sandbox is engaged. If + // pre_sandbox_hook() returns true, the sandbox will be engaged + // afterwards, otherwise the process is terminated. + using PreSandboxHook = base::OnceCallback<bool(Options)>; + + // Get our singleton instance. + static SandboxLinux* GetInstance(); + + // Do some initialization that can only be done before any of the sandboxes + // are enabled. If using the setuid sandbox, this should be called manually + // before the setuid sandbox is engaged. + // Security: When this runs, it is imperative that either InitializeSandbox() + // runs as well or that all file descriptors returned in + // GetFileDescriptorsToClose() get closed. + // Otherwise file descriptors that bypass the security of the setuid sandbox + // would be kept open. One must be particularly careful if a process performs + // a fork(). + void PreinitializeSandbox(); + + // Check that the current process is the init process of a new PID + // namespace and then proceed to drop access to the file system by using + // a new unprivileged namespace. This is a layer-1 sandbox. + // In order for this sandbox to be effective, it must be "sealed" by calling + // InitializeSandbox(). + // Terminates the process in case the sandboxing operations cannot complete + // successfully. + void EngageNamespaceSandbox(bool from_zygote); + + // Performs the same actions as EngageNamespaceSandbox, but is allowed to + // to fail. This is useful when sandboxed non-renderer processes could + // benefit from extra sandboxing but is not strictly required on systems that + // don't support unprivileged user namespaces. + // Zygote should use EngageNamespaceSandbox instead. + bool EngageNamespaceSandboxIfPossible(); + + // Return a list of file descriptors to close if PreinitializeSandbox() ran + // but InitializeSandbox() won't. Avoid using. + // TODO(jln): get rid of this hack. + std::vector<int> GetFileDescriptorsToClose(); + + // Seal an eventual layer-1 sandbox and initialize the layer-2 sandbox with + // an adequate policy depending on the process type and command line + // arguments. + // Currently the layer-2 sandbox is composed of seccomp-bpf and address space + // limitations. + // This function should only be called without any thread running. + bool InitializeSandbox(SandboxType sandbox_type, + PreSandboxHook hook, + const Options& options); + + // Stop |thread| in a way that can be trusted by the sandbox. + void StopThread(base::Thread* thread); + + // Returns the status of the renderer, worker and ppapi sandbox. Can only + // be queried after going through PreinitializeSandbox(). This is a bitmask + // and uses the constants defined in "enum Status" above. Since the + // status needs to be provided before the sandboxes are actually started, + // this returns what will actually happen once InitializeSandbox() + // is called from inside these processes. + int GetStatus(); + + // Returns true if the current process is single-threaded or if the number + // of threads cannot be determined. + bool IsSingleThreaded() const; + + // Returns true if we started Seccomp BPF. + bool seccomp_bpf_started() const; + + // Simple accessor for our instance of the setuid sandbox. Will never return + // NULL. + // There is no StartSetuidSandbox(), the SetuidSandboxClient instance should + // be used directly. + SetuidSandboxClient* setuid_sandbox_client() const; + + // Check the policy and eventually start the seccomp-bpf sandbox. Fine to be + // called with threads, as long as + // |options.allow_threads_during_sandbox_init| is true and the kernel + // supports seccomp's TSYNC feature. If TSYNC is not available we treat + // multiple threads as a fatal error. + bool StartSeccompBPF(SandboxType sandbox_type, + PreSandboxHook hook, + const Options& options); + + // Limit the address space of the current process (and its children) to make + // some vulnerabilities harder to exploit. Writes the errno due to setrlimit + // (including 0 if no error) into |error|. + bool LimitAddressSpace(int* error); + + // Returns a file descriptor to proc. The file descriptor is no longer valid + // after the sandbox has been sealed. + int proc_fd() const { + DCHECK_NE(-1, proc_fd_); + return proc_fd_; + } + +#if BUILDFLAG(USING_SANITIZER) + __sanitizer_sandbox_arguments* sanitizer_args() const { + return sanitizer_args_.get(); + } +#endif + + // A BrokerProcess is a helper that is started before the sandbox is engaged, + // typically from a pre-sandbox hook, that will serve requests to access + // files over an IPC channel. The client of this runs from a SIGSYS handler + // triggered by the seccomp-bpf sandbox. + // |client_sandbox_policy| is the policy being run by the client, and is + // used to derive the equivalent broker-side policy. + // |broker_side_hook| is an alternate pre-sandbox hook to be run before the + // broker itself gets sandboxed, to which the broker side policy and + // |options| are passed. + // Crashes the process if the broker can not be started since continuation + // is impossible (and presumably unsafe). + // This should never be destroyed, as after the sandbox is started it is + // vital to the process. + void StartBrokerProcess( + const syscall_broker::BrokerCommandSet& allowed_command_set, + std::vector<syscall_broker::BrokerFilePermission> permissions, + PreSandboxHook broker_side_hook, + const Options& options); + + syscall_broker::BrokerProcess* broker_process() const { + return broker_process_; + } + + private: + friend struct base::DefaultSingletonTraits<SandboxLinux>; + + SandboxLinux(); + ~SandboxLinux(); + + // We must have been pre_initialized_ before using these. + bool seccomp_bpf_supported() const; + bool seccomp_bpf_with_tsync_supported() const; + + // Returns true if it can be determined that the current process has open + // directories that are not managed by the SandboxLinux class. This would + // be a vulnerability as it would allow to bypass the setuid sandbox. + bool HasOpenDirectories() const; + + // The last part of the initialization is to make sure any temporary "hole" + // in the sandbox is closed. For now, this consists of closing proc_fd_. + void SealSandbox(); + + // GetStatus() makes promises as to how the sandbox will behave. This + // checks that no promises have been broken. + void CheckForBrokenPromises(SandboxType sandbox_type); + + // Stop |thread| and make sure it does not appear in /proc/self/tasks/ + // anymore. + void StopThreadAndEnsureNotCounted(base::Thread* thread) const; + + // Engages the namespace sandbox as described for EngageNamespaceSandbox. + // Returns false if it fails to transition to a new user namespace, but + // after transitioning to a new user namespace we don't allow this function + // to fail. + bool EngageNamespaceSandboxInternal(bool from_zygote); + + // A file descriptor to /proc. It's dangerous to have it around as it could + // allow for sandbox bypasses. It needs to be closed before we consider + // ourselves sandboxed. + int proc_fd_; + + bool seccomp_bpf_started_; + // The value returned by GetStatus(). Gets computed once and then cached. + int sandbox_status_flags_; + // Did PreinitializeSandbox() run? + bool pre_initialized_; + bool seccomp_bpf_supported_; // Accurate if pre_initialized_. + bool seccomp_bpf_with_tsync_supported_; // Accurate if pre_initialized_. + bool yama_is_enforcing_; // Accurate if pre_initialized_. + bool initialize_sandbox_ran_; // InitializeSandbox() was called. + std::unique_ptr<SetuidSandboxClient> setuid_sandbox_client_; +#if BUILDFLAG(USING_SANITIZER) + std::unique_ptr<__sanitizer_sandbox_arguments> sanitizer_args_; +#endif + syscall_broker::BrokerProcess* broker_process_; // Leaked as global. + + DISALLOW_COPY_AND_ASSIGN(SandboxLinux); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_SANDBOX_LINUX_H_ diff --git a/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc b/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc new file mode 100644 index 00000000000..ab45dc7766a --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc @@ -0,0 +1,288 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h" + +#include <errno.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <memory> +#include <utility> + +#include "base/check_op.h" +#include "base/command_line.h" +#include "base/macros.h" +#include "base/notreached.h" +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/bpf_dsl/trap_registry.h" +#include "sandbox/policy/sandbox_type.h" +#include "sandbox/policy/switches.h" +#include "sandbox/sandbox_buildflags.h" + +#if BUILDFLAG(USE_SECCOMP_BPF) + +#include "base/files/scoped_file.h" +#include "base/posix/eintr_wrapper.h" +#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" +#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" +#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" +#include "sandbox/policy/linux/bpf_audio_policy_linux.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" +#include "sandbox/policy/linux/bpf_cdm_policy_linux.h" +#include "sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h" +#include "sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h" +#include "sandbox/policy/linux/bpf_gpu_policy_linux.h" +#include "sandbox/policy/linux/bpf_network_policy_linux.h" +#include "sandbox/policy/linux/bpf_ppapi_policy_linux.h" +#include "sandbox/policy/linux/bpf_print_compositor_policy_linux.h" +#include "sandbox/policy/linux/bpf_renderer_policy_linux.h" +#include "sandbox/policy/linux/bpf_sharing_service_policy_linux.h" +#include "sandbox/policy/linux/bpf_speech_recognition_policy_linux.h" +#include "sandbox/policy/linux/bpf_utility_policy_linux.h" + +#if !defined(OS_NACL_NONSFI) +#include "sandbox/policy/chromecast_sandbox_allowlist_buildflags.h" +#endif // !defined(OS_NACL_NONSFI) + +#if defined(OS_CHROMEOS) +#include "sandbox/policy/features.h" +#include "sandbox/policy/linux/bpf_ime_policy_linux.h" +#include "sandbox/policy/linux/bpf_tts_policy_linux.h" +#endif // defined(OS_CHROMEOS) + +using sandbox::bpf_dsl::Allow; +using sandbox::bpf_dsl::ResultExpr; + +#else // BUILDFLAG(USE_SECCOMP_BPF) + +// Make sure that seccomp-bpf does not get disabled by mistake. Also make sure +// that we think twice about this when adding a new architecture. +#if !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL) +#error "Seccomp-bpf disabled on supported architecture!" +#endif // !defined(ARCH_CPU_ARM64) && !defined(ARCH_CPU_MIPS64EL) + +#endif // BUILDFLAG(USE_SECCOMP_BPF) + +namespace sandbox { +namespace policy { + +#if BUILDFLAG(USE_SECCOMP_BPF) +namespace { + +#if !defined(OS_NACL_NONSFI) + +// nacl_helper needs to be tiny and includes only part of content/ +// in its dependencies. Make sure to not link things that are not needed. +#if !defined(IN_NACL_HELPER) +inline bool IsChromeOS() { +#if defined(OS_CHROMEOS) + return true; +#else + return false; +#endif +} + +inline bool UseChromecastSandboxAllowlist() { +#if BUILDFLAG(ENABLE_CHROMECAST_GPU_SANDBOX_ALLOWLIST) + return true; +#else + return false; +#endif +} + +inline bool IsArchitectureArm() { +#if defined(ARCH_CPU_ARM_FAMILY) + return true; +#else + return false; +#endif +} + +std::unique_ptr<BPFBasePolicy> GetGpuProcessSandbox( + bool use_amd_specific_policies) { + if (IsChromeOS() || UseChromecastSandboxAllowlist()) { + if (IsArchitectureArm()) { + return std::make_unique<CrosArmGpuProcessPolicy>( + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kGpuSandboxAllowSysVShm)); + } + if (use_amd_specific_policies) + return std::make_unique<CrosAmdGpuProcessPolicy>(); + } + return std::make_unique<GpuProcessPolicy>(); +} +#endif // !defined(IN_NACL_HELPER) +#endif // !defined(OS_NACL_NONSFI) + +} // namespace + +#endif // USE_SECCOMP_BPF + +// Is seccomp BPF globally enabled? +bool SandboxSeccompBPF::IsSeccompBPFDesired() { +#if BUILDFLAG(USE_SECCOMP_BPF) + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + return !command_line.HasSwitch(switches::kNoSandbox) && + !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox); +#else + return false; +#endif // USE_SECCOMP_BPF +} + +bool SandboxSeccompBPF::SupportsSandbox() { +#if BUILDFLAG(USE_SECCOMP_BPF) + return SandboxBPF::SupportsSeccompSandbox( + SandboxBPF::SeccompLevel::SINGLE_THREADED); +#else + return false; +#endif +} + +#if !defined(OS_NACL_NONSFI) + +bool SandboxSeccompBPF::SupportsSandboxWithTsync() { +#if BUILDFLAG(USE_SECCOMP_BPF) + return SandboxBPF::SupportsSeccompSandbox( + SandboxBPF::SeccompLevel::MULTI_THREADED); +#else + return false; +#endif +} + +std::unique_ptr<BPFBasePolicy> SandboxSeccompBPF::PolicyForSandboxType( + SandboxType sandbox_type, + const SandboxSeccompBPF::Options& options) { + switch (sandbox_type) { + case SandboxType::kGpu: + return GetGpuProcessSandbox(options.use_amd_specific_policies); + case SandboxType::kRenderer: + return std::make_unique<RendererProcessPolicy>(); + case SandboxType::kPpapi: + return std::make_unique<PpapiProcessPolicy>(); + case SandboxType::kUtility: + return std::make_unique<UtilityProcessPolicy>(); + case SandboxType::kCdm: + return std::make_unique<CdmProcessPolicy>(); + case SandboxType::kPrintCompositor: + return std::make_unique<PrintCompositorProcessPolicy>(); + case SandboxType::kNetwork: + return std::make_unique<NetworkProcessPolicy>(); + case SandboxType::kAudio: + return std::make_unique<AudioProcessPolicy>(); + case SandboxType::kSharingService: + return std::make_unique<SharingServiceProcessPolicy>(); + case SandboxType::kSpeechRecognition: + return std::make_unique<SpeechRecognitionProcessPolicy>(); +#if defined(OS_CHROMEOS) + case SandboxType::kIme: + return std::make_unique<ImeProcessPolicy>(); + case SandboxType::kTts: + return std::make_unique<TtsProcessPolicy>(); +#endif // defined(OS_CHROMEOS) + case SandboxType::kZygoteIntermediateSandbox: + case SandboxType::kNoSandbox: + case SandboxType::kVideoCapture: + NOTREACHED(); + return nullptr; + } +} + +// If a BPF policy is engaged for |process_type|, run a few sanity checks. +void SandboxSeccompBPF::RunSandboxSanityChecks( + SandboxType sandbox_type, + const SandboxSeccompBPF::Options& options) { + switch (sandbox_type) { + case SandboxType::kRenderer: + case SandboxType::kGpu: + case SandboxType::kPpapi: + case SandboxType::kPrintCompositor: + case SandboxType::kCdm: { + int syscall_ret; + errno = 0; + + // Without the sandbox, this would EBADF. + syscall_ret = fchmod(-1, 07777); + CHECK_EQ(-1, syscall_ret); + CHECK_EQ(EPERM, errno); + +// Run most of the sanity checks only in DEBUG mode to avoid a perf. +// impact. +#if !defined(NDEBUG) + // open() must be restricted. + syscall_ret = open("/etc/passwd", O_RDONLY); + CHECK_EQ(-1, syscall_ret); + CHECK_EQ(BPFBasePolicy::GetFSDeniedErrno(), errno); + + // We should never allow the creation of netlink sockets. + syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); + CHECK_EQ(-1, syscall_ret); + CHECK_EQ(EPERM, errno); +#endif // !defined(NDEBUG) + } break; +#if defined(OS_CHROMEOS) + case SandboxType::kIme: + case SandboxType::kTts: +#endif // defined(OS_CHROMEOS) + case SandboxType::kAudio: + case SandboxType::kSharingService: + case SandboxType::kSpeechRecognition: + case SandboxType::kNetwork: + case SandboxType::kUtility: + case SandboxType::kNoSandbox: + case SandboxType::kVideoCapture: + case SandboxType::kZygoteIntermediateSandbox: + // Otherwise, no checks required. + break; + } +} +#endif // !defined(OS_NACL_NONSFI) + +bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( + std::unique_ptr<bpf_dsl::Policy> policy, + base::ScopedFD proc_fd, + SandboxBPF::SeccompLevel seccomp_level) { +#if BUILDFLAG(USE_SECCOMP_BPF) + if (IsSeccompBPFDesired() && SupportsSandbox()) { + CHECK(policy); + // Starting the sandbox is a one-way operation. The kernel doesn't allow + // us to unload a sandbox policy after it has been started. Nonetheless, + // in order to make the use of the "Sandbox" object easier, we allow for + // the object to be destroyed after the sandbox has been started. Note that + // doing so does not stop the sandbox. + SandboxBPF sandbox(std::move(policy)); + sandbox.SetProcFd(std::move(proc_fd)); + bool enable_ibpb = true; +#if defined(OS_CHROMEOS) + enable_ibpb = + base::FeatureList::IsEnabled( + features::kForceSpectreVariant2Mitigation) || + base::FeatureList::IsEnabled(features::kSpectreVariant2Mitigation); +#endif // defined(OS_CHROMEOS) + CHECK(sandbox.StartSandbox(seccomp_level, enable_ibpb)); + return true; + } +#endif // BUILDFLAG(USE_SECCOMP_BPF) + return false; +} + +#if !defined(OS_NACL_NONSFI) +std::unique_ptr<bpf_dsl::Policy> SandboxSeccompBPF::GetBaselinePolicy() { +#if BUILDFLAG(USE_SECCOMP_BPF) + return std::make_unique<BaselinePolicy>(); +#else + return nullptr; +#endif // BUILDFLAG(USE_SECCOMP_BPF) +} +#endif // !defined(OS_NACL_NONSFI) + +} // namespace policy +} // namespace sandbox diff --git a/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.h b/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.h new file mode 100644 index 00000000000..46a985e7fae --- /dev/null +++ b/chromium/sandbox/policy/linux/sandbox_seccomp_bpf_linux.h @@ -0,0 +1,80 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_POLICY_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ +#define SANDBOX_POLICY_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "sandbox/linux/bpf_dsl/policy.h" +#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" +#include "sandbox/policy/export.h" +#include "sandbox/policy/linux/bpf_base_policy_linux.h" +#include "sandbox/policy/sandbox_type.h" + +namespace sandbox { +namespace policy { + +// This class has two main sets of APIs. One can be used to start the sandbox +// for internal content process types, the other is indirectly exposed as +// a public content/ API and uses a supplied policy. +class SANDBOX_POLICY_EXPORT SandboxSeccompBPF { + public: + struct Options { + bool use_amd_specific_policies = false; // For ChromiumOS. + bool use_intel_specific_policies = false; // For ChromiumOS. + + // Options for GPU's PreSandboxHook. + bool accelerated_video_decode_enabled = false; + bool accelerated_video_encode_enabled = false; + }; + + // This is the API to enable a seccomp-bpf sandbox for content/ + // process-types: + // Is the sandbox globally enabled, can anything use it at all ? + // This looks at global command line flags to see if the sandbox + // should be enabled at all. + static bool IsSeccompBPFDesired(); + + // Check if the kernel supports seccomp-bpf. + static bool SupportsSandbox(); + +#if !defined(OS_NACL_NONSFI) + // Check if the kernel supports TSYNC (thread synchronization) with seccomp. + static bool SupportsSandboxWithTsync(); + + // Return a policy suitable for use with StartSandboxWithExternalPolicy. + static std::unique_ptr<BPFBasePolicy> PolicyForSandboxType( + SandboxType sandbox_type, + const SandboxSeccompBPF::Options& options); + + // Prove that the sandbox was engaged by the StartSandbox() call. Crashes + // the process if the sandbox failed to engage. + static void RunSandboxSanityChecks(SandboxType sandbox_type, + const SandboxSeccompBPF::Options& options); +#endif // !defined(OS_NACL_NONSFI) + + // This is the API to enable a seccomp-bpf sandbox by using an + // external policy. + static bool StartSandboxWithExternalPolicy( + std::unique_ptr<bpf_dsl::Policy> policy, + base::ScopedFD proc_fd, + SandboxBPF::SeccompLevel seccomp_level = + SandboxBPF::SeccompLevel::SINGLE_THREADED); + + // The "baseline" policy can be a useful base to build a sandbox policy. + static std::unique_ptr<bpf_dsl::Policy> GetBaselinePolicy(); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxSeccompBPF); +}; + +} // namespace policy +} // namespace sandbox + +#endif // SANDBOX_POLICY_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ |