diff options
author | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 06:21:43 +0000 |
---|---|---|
committer | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 06:21:43 +0000 |
commit | be5a79f679e77f11bfe566012a738ad7016ed264 (patch) | |
tree | 376ae76d2d2e6aee6a384d9be1cfae970cdd87c9 | |
parent | 8af0e34899426328404a938f8e57a7d47e2ae4ba (diff) | |
download | chromium_src-be5a79f679e77f11bfe566012a738ad7016ed264.zip chromium_src-be5a79f679e77f11bfe566012a738ad7016ed264.tar.gz chromium_src-be5a79f679e77f11bfe566012a738ad7016ed264.tar.bz2 |
Revert of https://codereview.chromium.org/99133015/
Reason for revert: Appears to have caused failures on linux dbg test 1
TBR=jorgelo@chromium.org,rsesek@chromium.org,mseaborn@chromium.org,piman@chromium.org,jln@chromium.org
NOTREECHECKS=true
NOTRY=true
Review URL: https://codereview.chromium.org/114483003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240527 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 845 insertions, 1048 deletions
diff --git a/components/nacl.gyp b/components/nacl.gyp index 3a86d2d..a964bc1 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp @@ -181,9 +181,6 @@ ], 'defines': [ '<@(nacl_defines)', - # Allow .cc files to know if they're being compiled as part - # of nacl_helper. - 'IN_NACL_HELPER=1', ], 'sources': [ 'nacl/loader/nacl_sandbox_linux.cc', @@ -191,9 +188,9 @@ 'nacl/loader/nacl_helper_linux.h', '../base/posix/unix_domain_socket_linux.cc', '../content/common/child_process_sandbox_support_impl_shm_linux.cc', - '../content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc', - '../content/common/sandbox_linux/sandbox_init_linux.cc', - '../content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc', + '../content/common/sandbox_bpf_base_policy_linux.cc', + '../content/common/sandbox_init_linux.cc', + '../content/common/sandbox_seccomp_bpf_linux.cc', '../content/public/common/content_switches.cc', ], 'conditions': [ diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc index 19cbc5b..d17b1ca 100644 --- a/content/browser/renderer_host/render_sandbox_host_linux.cc +++ b/content/browser/renderer_host/render_sandbox_host_linux.cc @@ -30,7 +30,7 @@ #include "base/strings/string_util.h" #include "content/child/webkitplatformsupport_impl.h" #include "content/common/font_config_ipc_linux.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/common/set_process_title.h" #include "content/public/common/content_switches.h" #include "skia/ext/skia_utils_base.h" diff --git a/content/common/OWNERS b/content/common/OWNERS index 1e5943d..fae82f1 100644 --- a/content/common/OWNERS +++ b/content/common/OWNERS @@ -18,6 +18,11 @@ per-file pepper*=bauerb@chromium.org per-file plugin*=ananta@chromium.org per-file plugin*=bauerb@chromium.org +# Linux sandbox seccomp-bpf policies: +per-file sandbox_seccomp_bpf_linux.*=jln@chromium.org +per-file sandbox_seccomp_bpf_linux.*=cevans@chromium.org +per-file sandbox_seccomp_bpf_linux.*=jorgelo@chromium.org + # Changes to IPC messages require a security review to avoid introducing # new sandbox escapes. per-file *_messages*.h=set noparent diff --git a/content/common/child_process_sandbox_support_impl_linux.cc b/content/common/child_process_sandbox_support_impl_linux.cc index 62124ae..1bfb658 100644 --- a/content/common/child_process_sandbox_support_impl_linux.cc +++ b/content/common/child_process_sandbox_support_impl_linux.cc @@ -13,7 +13,7 @@ #include "base/posix/unix_domain_socket_linux.h" #include "base/safe_numerics.h" #include "base/sys_byteorder.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "third_party/WebKit/public/platform/linux/WebFontFamily.h" #include "third_party/WebKit/public/platform/linux/WebFontRenderStyle.h" diff --git a/content/common/child_process_sandbox_support_impl_shm_linux.cc b/content/common/child_process_sandbox_support_impl_shm_linux.cc index 0c634c1..1aaa1c0 100644 --- a/content/common/child_process_sandbox_support_impl_shm_linux.cc +++ b/content/common/child_process_sandbox_support_impl_shm_linux.cc @@ -6,7 +6,7 @@ #include "base/pickle.h" #include "base/posix/unix_domain_socket_linux.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" namespace content { diff --git a/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc b/content/common/sandbox_bpf_base_policy_linux.cc index d1e5af3..4341e92 100644 --- a/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.cc +++ b/content/common/sandbox_bpf_base_policy_linux.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" +#include "content/common/sandbox_bpf_base_policy_linux.h" #include <errno.h> @@ -29,10 +29,6 @@ ErrorCode SandboxBPFBasePolicy::EvaluateSyscall(SandboxBPF* sandbox_compiler, system_call_number); } -bool SandboxBPFBasePolicy::PreSandboxHook() { - return true; -} - int SandboxBPFBasePolicy::GetFSDeniedErrno() { return kFSDeniedErrno; } diff --git a/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h b/content/common/sandbox_bpf_base_policy_linux.h index 6d9d83f..8edba1d 100644 --- a/content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h +++ b/content/common/sandbox_bpf_base_policy_linux.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_ -#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_ +#ifndef CONTENT_COMMON_SANDBOX_BPF_BASE_POLICY_LINUX_H_ +#define CONTENT_COMMON_SANDBOX_BPF_BASE_POLICY_LINUX_H_ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" @@ -26,15 +26,6 @@ class SandboxBPFBasePolicy : public sandbox::SandboxBPFPolicy { virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, int system_call_number) const OVERRIDE; - - // A policy can implement this hook to run code right before the policy - // is passed to the SandboxBPF class and the sandbox is engaged. - // If PreSandboxHook() returns true, the sandbox is guaranteed to be - // engaged afterwards. - // This will be used when enabling the sandbox though - // SandboxSeccompBPF::StartSandbox(). - virtual bool PreSandboxHook(); - // Get the errno(3) to return for filesystem errors. static int GetFSDeniedErrno(); @@ -46,4 +37,4 @@ class SandboxBPFBasePolicy : public sandbox::SandboxBPFPolicy { } // namespace content -#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_BPF_BASE_POLICY_LINUX_H_ +#endif // CONTENT_COMMON_SANDBOX_BPF_BASE_POLICY_LINUX_H_ diff --git a/content/common/sandbox_linux/sandbox_init_linux.cc b/content/common/sandbox_init_linux.cc index 516c611..b2e6b4a 100644 --- a/content/common/sandbox_linux/sandbox_init_linux.cc +++ b/content/common/sandbox_init_linux.cc @@ -5,7 +5,7 @@ #include "content/public/common/sandbox_init.h" #include "base/memory/scoped_ptr.h" -#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" +#include "content/common/sandbox_seccomp_bpf_linux.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" namespace content { diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux.cc index 2aa4f28..ea8144f 100644 --- a/content/common/sandbox_linux/sandbox_linux.cc +++ b/content/common/sandbox_linux.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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. @@ -19,8 +19,8 @@ #include "base/posix/eintr_wrapper.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" -#include "content/common/sandbox_linux/sandbox_linux.h" -#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" +#include "content/common/sandbox_linux.h" +#include "content/common/sandbox_seccomp_bpf_linux.h" #include "content/public/common/content_switches.h" #include "content/public/common/sandbox_linux.h" #include "sandbox/linux/services/credentials.h" diff --git a/content/common/sandbox_linux/sandbox_linux.h b/content/common/sandbox_linux.h index 9afca59..15852a5 100644 --- a/content/common/sandbox_linux/sandbox_linux.h +++ b/content/common/sandbox_linux.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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 CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_LINUX_H_ -#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_LINUX_H_ +#ifndef CONTENT_COMMON_SANDBOX_LINUX_H_ +#define CONTENT_COMMON_SANDBOX_LINUX_H_ #include <string> @@ -104,4 +104,5 @@ class LinuxSandbox { } // namespace content -#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_LINUX_H_ +#endif // CONTENT_COMMON_SANDBOX_LINUX_H_ + diff --git a/content/common/sandbox_linux/OWNERS b/content/common/sandbox_linux/OWNERS deleted file mode 100644 index 35643d1..0000000 --- a/content/common/sandbox_linux/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -cevans@chromium.org -jln@chromium.org -jorgelo@chromium.org diff --git a/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc deleted file mode 100644 index 09ccdeb..0000000 --- a/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc +++ /dev/null @@ -1,226 +0,0 @@ -// 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 "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h" - -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" -#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" -#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/services/linux_syscalls.h" - -using sandbox::ErrorCode; -using sandbox::SandboxBPF; -using sandbox::SyscallSets; - -namespace content { - -namespace { - -inline bool IsChromeOS() { -#if defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureArm() { -#if defined(__arm__) - return true; -#else - return false; -#endif -} - -void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist, - std::vector<std::string>* write_whitelist) { - // Device file needed by the ARM GPU userspace. - static const char kMali0Path[] = "/dev/mali0"; - - // Devices needed for video decode acceleration on ARM. - static const char kDevMfcDecPath[] = "/dev/mfc-dec"; - static const char kDevGsc1Path[] = "/dev/gsc1"; - - // Devices needed for video encode acceleration on ARM. - static const char kDevMfcEncPath[] = "/dev/mfc-enc"; - - read_whitelist->push_back(kMali0Path); - read_whitelist->push_back(kDevMfcDecPath); - read_whitelist->push_back(kDevGsc1Path); - read_whitelist->push_back(kDevMfcEncPath); - - write_whitelist->push_back(kMali0Path); - write_whitelist->push_back(kDevMfcDecPath); - write_whitelist->push_back(kDevGsc1Path); - write_whitelist->push_back(kDevMfcEncPath); -} - -void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist, - std::vector<std::string>* write_whitelist) { - // Device files needed by the Tegra GPU userspace. - static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl"; - static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d"; - static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d"; - static const char kDevNvhostIspPath[] = "/dev/nvhost-isp"; - static const char kDevNvhostViPath[] = "/dev/nvhost-vi"; - static const char kDevNvmapPath[] = "/dev/nvmap"; - static const char kDevTegraSemaPath[] = "/dev/tegra_sema"; - - read_whitelist->push_back(kDevNvhostCtrlPath); - read_whitelist->push_back(kDevNvhostGr2dPath); - read_whitelist->push_back(kDevNvhostGr3dPath); - read_whitelist->push_back(kDevNvhostIspPath); - read_whitelist->push_back(kDevNvhostViPath); - read_whitelist->push_back(kDevNvmapPath); - read_whitelist->push_back(kDevTegraSemaPath); - - write_whitelist->push_back(kDevNvhostCtrlPath); - write_whitelist->push_back(kDevNvhostGr2dPath); - write_whitelist->push_back(kDevNvhostGr3dPath); - write_whitelist->push_back(kDevNvhostIspPath); - write_whitelist->push_back(kDevNvhostViPath); - write_whitelist->push_back(kDevNvmapPath); - write_whitelist->push_back(kDevTegraSemaPath); -} - -void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, - std::vector<std::string>* write_whitelist) { - // On ARM we're enabling the sandbox before the X connection is made, - // so we need to allow access to |.Xauthority|. - static const char kXAuthorityPath[] = "/home/chronos/.Xauthority"; - static const char kLdSoCache[] = "/etc/ld.so.cache"; - - // Files needed by the ARM GPU userspace. - static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2"; - static const char kLibEglPath[] = "/usr/lib/libEGL.so.1"; - - read_whitelist->push_back(kXAuthorityPath); - read_whitelist->push_back(kLdSoCache); - read_whitelist->push_back(kLibGlesPath); - read_whitelist->push_back(kLibEglPath); - - AddArmMaliGpuWhitelist(read_whitelist, write_whitelist); - AddArmTegraGpuWhitelist(read_whitelist, write_whitelist); -} - -class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy { - public: - CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {} - virtual ~CrosArmGpuBrokerProcessPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy); -}; - -// A GPU broker policy is the same as a GPU policy with open and -// openat allowed. -ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - switch (sysno) { - case __NR_access: - case __NR_open: - case __NR_openat: - return ErrorCode(ErrorCode::ERR_ALLOWED); - default: - return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); - } -} - -bool EnableArmGpuBrokerPolicyCallback() { - return SandboxSeccompBPF::StartSandboxWithExternalPolicy( - scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy)); -} - -} // namespace - -CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat) - : allow_shmat_(allow_shmat) {} - -CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {} - -ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { -#if defined(__arm__) - if (allow_shmat_ && sysno == __NR_shmat) - return ErrorCode(ErrorCode::ERR_ALLOWED); -#endif // defined(__arm__) - - switch (sysno) { -#if defined(__arm__) - // 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 ErrorCode(ErrorCode::ERR_ALLOWED); - // Allow only AF_UNIX for |domain|. - case __NR_socket: - case __NR_socketpair: - return sandbox->Cond(0, ErrorCode::TP_32BIT, - ErrorCode::OP_EQUAL, AF_UNIX, - ErrorCode(ErrorCode::ERR_ALLOWED), - ErrorCode(EPERM)); -#endif // defined(__arm__) - default: - if (SyscallSets::IsAdvancedScheduler(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); - - // Default to the generic GPU policy. - return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); - } -} - -bool CrosArmGpuProcessPolicy::PreSandboxHook() { - DCHECK(IsChromeOS() && IsArchitectureArm()); - // Create a new broker process. - DCHECK(!broker_process()); - - std::vector<std::string> read_whitelist_extra; - std::vector<std::string> write_whitelist_extra; - // Add ARM-specific files to whitelist in the broker. - - AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra); - InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback, - read_whitelist_extra, - write_whitelist_extra); - - const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE; - - // Preload the Mali library. - dlopen("/usr/lib/libmali.so", dlopen_flag); - - // Preload the Tegra libraries. - dlopen("/usr/lib/libnvrm.so", dlopen_flag); - dlopen("/usr/lib/libnvrm_graphics.so", dlopen_flag); - dlopen("/usr/lib/libnvos.so", dlopen_flag); - dlopen("/usr/lib/libnvddk_2d.so", dlopen_flag); - dlopen("/usr/lib/libardrv_dynamic.so", dlopen_flag); - dlopen("/usr/lib/libnvwsi.so", dlopen_flag); - dlopen("/usr/lib/libnvglsi.so", dlopen_flag); - dlopen("/usr/lib/libcgdrv.so", dlopen_flag); - - return true; -} - -} // namespace content diff --git a/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h b/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h deleted file mode 100644 index 0ccc93c..0000000 --- a/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h +++ /dev/null @@ -1,29 +0,0 @@ -// 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 CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ -#define CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ - -#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h" - -namespace content { - -// This policy is for Chrome OS ARM. -class CrosArmGpuProcessPolicy : public GpuProcessPolicy { - public: - explicit CrosArmGpuProcessPolicy(bool allow_shmat); - virtual ~CrosArmGpuProcessPolicy(); - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - virtual bool PreSandboxHook() OVERRIDE; - - private: - const bool allow_shmat_; // Allow shmat(2). - DISALLOW_COPY_AND_ASSIGN(CrosArmGpuProcessPolicy); -}; - -} // namespace content - -#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_CROS_ARM_GPU_POLICY_LINUX_H_ diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc deleted file mode 100644 index 820f255..0000000 --- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc +++ /dev/null @@ -1,247 +0,0 @@ -// 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 "content/common/sandbox_linux/bpf_gpu_policy_linux.h" - -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> -#include <vector> - -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" -#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" -#include "content/public/common/content_switches.h" -#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" -#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" -#include "sandbox/linux/services/broker_process.h" -#include "sandbox/linux/services/linux_syscalls.h" - -using sandbox::BrokerProcess; -using sandbox::ErrorCode; -using sandbox::SandboxBPF; -using sandbox::SyscallSets; -using sandbox::arch_seccomp_data; - -namespace content { - -namespace { - -inline bool IsChromeOS() { -#if defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureX86_64() { -#if defined(__x86_64__) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureI386() { -#if defined(__i386__) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureArm() { -#if defined(__arm__) - return true; -#else - return false; -#endif -} - -bool IsAcceleratedVideoDecodeEnabled() { - // Accelerated video decode is currently enabled on Chrome OS, - // but not on Linux: crbug.com/137247. - bool is_enabled = IsChromeOS(); - - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - is_enabled &= - !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode); - - return is_enabled; -} - -intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args, - void* aux_broker_process) { - RAW_CHECK(aux_broker_process); - BrokerProcess* broker_process = - static_cast<BrokerProcess*>(aux_broker_process); - switch (args.nr) { - case __NR_access: - return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), - static_cast<int>(args.args[1])); - case __NR_open: - return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), - static_cast<int>(args.args[1])); - case __NR_openat: - // Allow using openat() as open(). - if (static_cast<int>(args.args[0]) == AT_FDCWD) { - return - broker_process->Open(reinterpret_cast<const char*>(args.args[1]), - static_cast<int>(args.args[2])); - } else { - return -EPERM; - } - default: - RAW_CHECK(false); - return -ENOSYS; - } -} - -class GpuBrokerProcessPolicy : public GpuProcessPolicy { - public: - GpuBrokerProcessPolicy() {} - virtual ~GpuBrokerProcessPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); -}; - -// x86_64/i386 or desktop ARM. -// A GPU broker policy is the same as a GPU policy with open and -// openat allowed. -ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - switch (sysno) { - case __NR_access: - case __NR_open: - case __NR_openat: - return ErrorCode(ErrorCode::ERR_ALLOWED); - default: - return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); - } -} - -bool EnableGpuBrokerPolicyCallback() { - return SandboxSeccompBPF::StartSandboxWithExternalPolicy( - scoped_ptr<sandbox::SandboxBPFPolicy>(new GpuBrokerProcessPolicy)); -} - -} // namespace - -GpuProcessPolicy::GpuProcessPolicy() : broker_process_(NULL) {} - -GpuProcessPolicy::~GpuProcessPolicy() {} - -// Main policy for x86_64/i386. Extended by CrosArmGpuProcessPolicy. -ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - switch (sysno) { - case __NR_ioctl: -#if defined(__i386__) || defined(__x86_64__) - // The Nvidia driver uses flags not in the baseline policy - // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) - case __NR_mmap: -#endif - // We also hit this on the linux_chromeos bot but don't yet know what - // weird flags were involved. - case __NR_mprotect: - case __NR_sched_getaffinity: - case __NR_sched_setaffinity: - case __NR_setpriority: - return ErrorCode(ErrorCode::ERR_ALLOWED); - case __NR_access: - case __NR_open: - case __NR_openat: - DCHECK(broker_process_); - return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); - default: - if (SyscallSets::IsEventFd(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); - - // Default on the baseline policy. - return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); - } -} - -bool GpuProcessPolicy::PreSandboxHook() { - // Warm up resources needed by the policy we're about to enable and - // eventually start a broker process. - const bool chromeos_arm_gpu = IsChromeOS() && IsArchitectureArm(); - // This policy is for x86 or Desktop. - DCHECK(!chromeos_arm_gpu); - - DCHECK(!broker_process()); - // Create a new broker process. - InitGpuBrokerProcess( - EnableGpuBrokerPolicyCallback, - std::vector<std::string>(), // No extra files in whitelist. - std::vector<std::string>()); - - if (IsArchitectureX86_64() || IsArchitectureI386()) { - // Accelerated video decode dlopen()'s some shared objects - // inside the sandbox, so preload them now. - if (IsAcceleratedVideoDecodeEnabled()) { - const char* I965DrvVideoPath = NULL; - - if (IsArchitectureX86_64()) { - I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so"; - } else if (IsArchitectureI386()) { - I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so"; - } - - dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); - dlopen("libva.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); - dlopen("libva-x11.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); - } - } - - return true; -} - -void GpuProcessPolicy::InitGpuBrokerProcess( - bool (*broker_sandboxer_callback)(void), - const std::vector<std::string>& read_whitelist_extra, - const std::vector<std::string>& write_whitelist_extra) { - static const char kDriRcPath[] = "/etc/drirc"; - static const char kDriCard0Path[] = "/dev/dri/card0"; - - CHECK(broker_process_ == NULL); - - // All GPU process policies need these files brokered out. - std::vector<std::string> read_whitelist; - read_whitelist.push_back(kDriCard0Path); - read_whitelist.push_back(kDriRcPath); - // Add eventual extra files from read_whitelist_extra. - read_whitelist.insert(read_whitelist.end(), - read_whitelist_extra.begin(), - read_whitelist_extra.end()); - - std::vector<std::string> write_whitelist; - write_whitelist.push_back(kDriCard0Path); - // Add eventual extra files from write_whitelist_extra. - write_whitelist.insert(write_whitelist.end(), - write_whitelist_extra.begin(), - write_whitelist_extra.end()); - - broker_process_ = new BrokerProcess(GetFSDeniedErrno(), - read_whitelist, - write_whitelist); - // Initialize the broker process and give it a sandbox callback. - CHECK(broker_process_->Init(broker_sandboxer_callback)); -} - -} // namespace content diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.h b/content/common/sandbox_linux/bpf_gpu_policy_linux.h deleted file mode 100644 index 6b1ba4a..0000000 --- a/content/common/sandbox_linux/bpf_gpu_policy_linux.h +++ /dev/null @@ -1,57 +0,0 @@ -// 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 CONTENT_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_ -#define CONTENT_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_ - -#include <string> -#include <vector> - -#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" - -namespace sandbox { -class BrokerProcess; -} - -namespace content { - -class GpuProcessPolicy : public SandboxBPFBasePolicy { - public: - GpuProcessPolicy(); - virtual ~GpuProcessPolicy(); - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - virtual bool PreSandboxHook() OVERRIDE; - - protected: - // Start a broker process to handle open() inside the sandbox. - // |broker_sandboxer_callback| is a callback that will enable a suitable - // sandbox for the broker process itself. - // |read_whitelist_extra| and |write_whitelist_extra| are lists of file - // names that should be whitelisted by the broker process, in addition to - // the basic ones. - void InitGpuBrokerProcess( - bool (*broker_sandboxer_callback)(void), - const std::vector<std::string>& read_whitelist_extra, - const std::vector<std::string>& write_whitelist_extra); - - sandbox::BrokerProcess* broker_process() { return broker_process_; } - - private: - // A BrokerProcess is a helper that is started before the sandbox is engaged - // and 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. - // This should never be destroyed, as after the sandbox is started it is - // vital to the process. - // This is allocated by InitGpuBrokerProcess, called from PreSandboxHook(), - // which executes iff the sandbox is going to be enabled afterwards. - sandbox::BrokerProcess* broker_process_; - DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); -}; - -} // namespace content - -#endif // CONTENT_COMMON_SANDBOX_LINUX_BPF_GPU_POLICY_LINUX_H_ diff --git a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc deleted file mode 100644 index 846a36e..0000000 --- a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc +++ /dev/null @@ -1,430 +0,0 @@ -// 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 <asm/unistd.h> -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <linux/net.h> -#include <signal.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/prctl.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <ucontext.h> -#include <unistd.h> - -#include <vector> - -#include "base/basictypes.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "build/build_config.h" -#include "content/public/common/content_switches.h" - -// These are the only architectures supported for now. -#if defined(__i386__) || defined(__x86_64__) || \ - (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) -#define SECCOMP_BPF_SANDBOX -#endif - -#if defined(SECCOMP_BPF_SANDBOX) -#include "base/posix/eintr_wrapper.h" -#include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h" -#include "content/common/sandbox_linux/bpf_gpu_policy_linux.h" -#include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" -#include "content/common/sandbox_linux/sandbox_linux.h" -#include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.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/seccomp-bpf/sandbox_bpf_policy.h" -#include "sandbox/linux/services/linux_syscalls.h" - -using sandbox::BaselinePolicy; -using sandbox::ErrorCode; -using sandbox::SandboxBPF; -using sandbox::SyscallSets; -using sandbox::arch_seccomp_data; - -namespace content { - -namespace { - -void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); - -inline bool IsChromeOS() { -#if defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - -inline bool IsArchitectureArm() { -#if defined(__arm__) - return true; -#else - return false; -#endif -} - -inline bool IsUsingToolKitGtk() { -#if defined(TOOLKIT_GTK) - return true; -#else - return false; -#endif -} - -// Policy for renderer and worker processes. -// TODO(jln): move to renderer/ - -class RendererOrWorkerProcessPolicy : public SandboxBPFBasePolicy { - public: - RendererOrWorkerProcessPolicy() {} - virtual ~RendererOrWorkerProcessPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(RendererOrWorkerProcessPolicy); -}; - -ErrorCode RendererOrWorkerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - switch (sysno) { - case __NR_clone: - return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); - case __NR_ioctl: - return sandbox::RestrictIoctl(sandbox); - case __NR_prctl: - return sandbox::RestrictPrctl(sandbox); - // Allow the system calls below. - case __NR_fdatasync: - case __NR_fsync: - case __NR_getpriority: -#if defined(__i386__) || defined(__x86_64__) - case __NR_getrlimit: -#endif -#if defined(__i386__) || defined(__arm__) - case __NR_ugetrlimit: -#endif - case __NR_mremap: // See crbug.com/149834. - case __NR_pread64: - case __NR_pwrite64: - case __NR_sched_getaffinity: - case __NR_sched_get_priority_max: - case __NR_sched_get_priority_min: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_setscheduler: - case __NR_setpriority: - case __NR_sysinfo: - case __NR_times: - case __NR_uname: - return ErrorCode(ErrorCode::ERR_ALLOWED); - case __NR_prlimit64: - return ErrorCode(EPERM); // See crbug.com/160157. - default: - if (IsUsingToolKitGtk()) { -#if defined(__x86_64__) || defined(__arm__) - if (SyscallSets::IsSystemVSharedMemory(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); -#endif -#if defined(__i386__) - if (SyscallSets::IsSystemVIpc(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); -#endif - } - - // Default on the content baseline policy. - return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); - } -} - -// Policy for PPAPI plugins. -// TODO(jln): move to ppapi_plugin/. -class FlashProcessPolicy : public SandboxBPFBasePolicy { - public: - FlashProcessPolicy() {} - virtual ~FlashProcessPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(FlashProcessPolicy); -}; - -ErrorCode FlashProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - switch (sysno) { - case __NR_clone: - return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); - case __NR_pread64: - case __NR_pwrite64: - case __NR_sched_get_priority_max: - case __NR_sched_get_priority_min: - case __NR_sched_getaffinity: - case __NR_sched_getparam: - case __NR_sched_getscheduler: - case __NR_sched_setscheduler: - case __NR_times: - return ErrorCode(ErrorCode::ERR_ALLOWED); - case __NR_ioctl: - return ErrorCode(ENOTTY); // Flash Access. - default: - if (IsUsingToolKitGtk()) { -#if defined(__x86_64__) || defined(__arm__) - if (SyscallSets::IsSystemVSharedMemory(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); -#endif -#if defined(__i386__) - if (SyscallSets::IsSystemVIpc(sysno)) - return ErrorCode(ErrorCode::ERR_ALLOWED); -#endif - } - - // Default on the baseline policy. - return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); - } -} - -class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy { - public: - BlacklistDebugAndNumaPolicy() {} - virtual ~BlacklistDebugAndNumaPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy); -}; - -ErrorCode BlacklistDebugAndNumaPolicy::EvaluateSyscall(SandboxBPF* sandbox, - int sysno) const { - if (!SandboxBPF::IsValidSyscallNumber(sysno)) { - // TODO(jln) we should not have to do that in a trivial policy. - return ErrorCode(ENOSYS); - } - if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno)) - return sandbox->Trap(sandbox::CrashSIGSYS_Handler, NULL); - - return ErrorCode(ErrorCode::ERR_ALLOWED); -} - -class AllowAllPolicy : public SandboxBPFBasePolicy { - public: - AllowAllPolicy() {} - virtual ~AllowAllPolicy() {} - - virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, - int system_call_number) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); -}; - -// Allow all syscalls. -// This will still deny x32 or IA32 calls in 64 bits mode or -// 64 bits system calls in compatibility mode. -ErrorCode AllowAllPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { - if (!SandboxBPF::IsValidSyscallNumber(sysno)) { - // TODO(jln) we should not have to do that in a trivial policy. - return ErrorCode(ENOSYS); - } else { - return ErrorCode(ErrorCode::ERR_ALLOWED); - } -} - -// If a BPF policy is engaged for |process_type|, run a few sanity checks. -void RunSandboxSanityChecks(const std::string& process_type) { - if (process_type == switches::kRendererProcess || - process_type == switches::kWorkerProcess || - process_type == switches::kGpuProcess || - process_type == switches::kPpapiPluginProcess) { - 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(SandboxBPFBasePolicy::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) - } -} - - -// This function takes ownership of |policy|. -void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* 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; - sandbox.SetSandboxPolicy(policy); - sandbox.StartSandbox(); -} - -// 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) -scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - bool allow_sysv_shm = false; - if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { - DCHECK(IsArchitectureArm()); - allow_sysv_shm = true; - } - - if (IsChromeOS() && IsArchitectureArm()) { - return scoped_ptr<SandboxBPFBasePolicy>( - new CrosArmGpuProcessPolicy(allow_sysv_shm)); - } else { - return scoped_ptr<SandboxBPFBasePolicy>(new GpuProcessPolicy); - } -} - -// Initialize the seccomp-bpf sandbox. -bool StartBPFSandbox(const CommandLine& command_line, - const std::string& process_type) { - scoped_ptr<SandboxBPFBasePolicy> policy; - - if (process_type == switches::kGpuProcess) { - policy.reset(GetGpuProcessSandbox().release()); - } else if (process_type == switches::kRendererProcess || - process_type == switches::kWorkerProcess) { - policy.reset(new RendererOrWorkerProcessPolicy); - } else if (process_type == switches::kPpapiPluginProcess) { - policy.reset(new FlashProcessPolicy); - } else if (process_type == switches::kUtilityProcess) { - policy.reset(new BlacklistDebugAndNumaPolicy); - } else { - NOTREACHED(); - policy.reset(new AllowAllPolicy); - } - - CHECK(policy->PreSandboxHook()); - StartSandboxWithPolicy(policy.release()); - - RunSandboxSanityChecks(process_type); - return true; -} -#else // defined(IN_NACL_HELPER) -bool StartBPFSandbox(const CommandLine& command_line, - const std::string& process_type) { - NOTREACHED(); - // Avoid -Wunused-function with no-op code. - ignore_result(IsChromeOS); - ignore_result(IsArchitectureArm); - ignore_result(RunSandboxSanityChecks); - return false; -} -#endif // !defined(IN_NACL_HELPER) - -} // namespace - -#endif // SECCOMP_BPF_SANDBOX - -// Is seccomp BPF globally enabled? -bool SandboxSeccompBPF::IsSeccompBPFDesired() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (!command_line.HasSwitch(switches::kNoSandbox) && - !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { - return true; - } else { - return false; - } -} - -bool SandboxSeccompBPF::ShouldEnableSeccompBPF( - const std::string& process_type) { -#if defined(SECCOMP_BPF_SANDBOX) - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (process_type == switches::kGpuProcess) - return !command_line.HasSwitch(switches::kDisableGpuSandbox); - - return true; -#endif // SECCOMP_BPF_SANDBOX - return false; -} - -bool SandboxSeccompBPF::SupportsSandbox() { -#if defined(SECCOMP_BPF_SANDBOX) - // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton - // here. - SandboxBPF::SandboxStatus bpf_sandbox_status = - SandboxBPF::SupportsSeccompSandbox(-1); - // Kernel support is what we are interested in here. Other status - // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. - // We make this a negative check, since if there is a bug, we would rather - // "fail closed" (expect a sandbox to be available and try to start it). - if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { - return true; - } -#endif - return false; -} - -bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { -#if defined(SECCOMP_BPF_SANDBOX) - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - - if (IsSeccompBPFDesired() && // Global switches policy. - ShouldEnableSeccompBPF(process_type) && // Process-specific policy. - SupportsSandbox()) { - // If the kernel supports the sandbox, and if the command line says we - // should enable it, enable it or die. - bool started_sandbox = StartBPFSandbox(command_line, process_type); - CHECK(started_sandbox); - return true; - } -#endif - return false; -} - -bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( - scoped_ptr<sandbox::SandboxBPFPolicy> policy) { -#if defined(SECCOMP_BPF_SANDBOX) - if (IsSeccompBPFDesired() && SupportsSandbox()) { - CHECK(policy); - StartSandboxWithPolicy(policy.release()); - return true; - } -#endif // defined(SECCOMP_BPF_SANDBOX) - return false; -} - -scoped_ptr<sandbox::SandboxBPFPolicy> -SandboxSeccompBPF::GetBaselinePolicy() { -#if defined(SECCOMP_BPF_SANDBOX) - return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); -#else - return scoped_ptr<sandbox::SandboxBPFPolicy>(); -#endif // defined(SECCOMP_BPF_SANDBOX) -} - -} // namespace content diff --git a/content/common/sandbox_seccomp_bpf_linux.cc b/content/common/sandbox_seccomp_bpf_linux.cc new file mode 100644 index 0000000..528d7e0 --- /dev/null +++ b/content/common/sandbox_seccomp_bpf_linux.cc @@ -0,0 +1,803 @@ +// 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 <asm/unistd.h> +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <linux/net.h> +#include <signal.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/prctl.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <ucontext.h> +#include <unistd.h> + +#include <vector> + +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "build/build_config.h" +#include "content/common/sandbox_linux.h" +#include "content/common/sandbox_seccomp_bpf_linux.h" +#include "content/public/common/content_switches.h" +#include "sandbox/linux/services/broker_process.h" + +// These are the only architectures supported for now. +#if defined(__i386__) || defined(__x86_64__) || \ + (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) +#define SECCOMP_BPF_SANDBOX +#endif + +#if defined(SECCOMP_BPF_SANDBOX) +#include "base/posix/eintr_wrapper.h" +#include "content/common/sandbox_bpf_base_policy_linux.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/seccomp-bpf/sandbox_bpf_policy.h" +#include "sandbox/linux/services/linux_syscalls.h" + +using sandbox::BaselinePolicy; +using sandbox::BrokerProcess; +using sandbox::ErrorCode; +using sandbox::SandboxBPF; +using sandbox::SyscallSets; +using sandbox::arch_seccomp_data; + +namespace content { + +namespace { + +void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); + +inline bool IsChromeOS() { +#if defined(OS_CHROMEOS) + return true; +#else + return false; +#endif +} + +inline bool IsArchitectureX86_64() { +#if defined(__x86_64__) + return true; +#else + return false; +#endif +} + +inline bool IsArchitectureI386() { +#if defined(__i386__) + return true; +#else + return false; +#endif +} + +inline bool IsArchitectureArm() { +#if defined(__arm__) + return true; +#else + return false; +#endif +} + +inline bool IsUsingToolKitGtk() { +#if defined(TOOLKIT_GTK) + return true; +#else + return false; +#endif +} + +// Policies for the GPU process. +// TODO(jln): move to gpu/ + +bool IsAcceleratedVideoDecodeEnabled() { + // Accelerated video decode is currently enabled on Chrome OS, + // but not on Linux: crbug.com/137247. + bool is_enabled = IsChromeOS(); + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + is_enabled = is_enabled && + !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode); + + return is_enabled; +} + +intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args, + void* aux_broker_process) { + RAW_CHECK(aux_broker_process); + BrokerProcess* broker_process = + static_cast<BrokerProcess*>(aux_broker_process); + switch (args.nr) { + case __NR_access: + return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), + static_cast<int>(args.args[1])); + case __NR_open: + return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), + static_cast<int>(args.args[1])); + case __NR_openat: + // Allow using openat() as open(). + if (static_cast<int>(args.args[0]) == AT_FDCWD) { + return + broker_process->Open(reinterpret_cast<const char*>(args.args[1]), + static_cast<int>(args.args[2])); + } else { + return -EPERM; + } + default: + RAW_CHECK(false); + return -ENOSYS; + } +} + +class GpuProcessPolicy : public SandboxBPFBasePolicy { + public: + explicit GpuProcessPolicy(void* broker_process) + : broker_process_(broker_process) {} + virtual ~GpuProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + const void* broker_process_; // Non-owning pointer. + DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); +}; + +// Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy. +ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + switch (sysno) { + case __NR_ioctl: +#if defined(__i386__) || defined(__x86_64__) + // The Nvidia driver uses flags not in the baseline policy + // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) + case __NR_mmap: +#endif + // We also hit this on the linux_chromeos bot but don't yet know what + // weird flags were involved. + case __NR_mprotect: + case __NR_sched_getaffinity: + case __NR_sched_setaffinity: + case __NR_setpriority: + return ErrorCode(ErrorCode::ERR_ALLOWED); + case __NR_access: + case __NR_open: + case __NR_openat: + return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); + default: + if (SyscallSets::IsEventFd(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); + + // Default on the baseline policy. + return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); + } +} + +class GpuBrokerProcessPolicy : public GpuProcessPolicy { + public: + GpuBrokerProcessPolicy() : GpuProcessPolicy(NULL) {} + virtual ~GpuBrokerProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); +}; + +// x86_64/i386. +// A GPU broker policy is the same as a GPU policy with open and +// openat allowed. +ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + switch (sysno) { + case __NR_access: + case __NR_open: + case __NR_openat: + return ErrorCode(ErrorCode::ERR_ALLOWED); + default: + return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); + } +} + +class ArmGpuProcessPolicy : public GpuProcessPolicy { + public: + explicit ArmGpuProcessPolicy(void* broker_process, bool allow_shmat) + : GpuProcessPolicy(broker_process), allow_shmat_(allow_shmat) {} + virtual ~ArmGpuProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + const bool allow_shmat_; // Allow shmat(2). + DISALLOW_COPY_AND_ASSIGN(ArmGpuProcessPolicy); +}; + +// Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy. +ErrorCode ArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { +#if defined(__arm__) + if (allow_shmat_ && sysno == __NR_shmat) + return ErrorCode(ErrorCode::ERR_ALLOWED); +#endif // defined(__arm__) + + switch (sysno) { +#if defined(__arm__) + // 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 ErrorCode(ErrorCode::ERR_ALLOWED); + // Allow only AF_UNIX for |domain|. + case __NR_socket: + case __NR_socketpair: + return sandbox->Cond(0, ErrorCode::TP_32BIT, + ErrorCode::OP_EQUAL, AF_UNIX, + ErrorCode(ErrorCode::ERR_ALLOWED), + ErrorCode(EPERM)); +#endif // defined(__arm__) + default: + if (SyscallSets::IsAdvancedScheduler(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); + + // Default to the generic GPU policy. + return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); + } +} + +class ArmGpuBrokerProcessPolicy : public ArmGpuProcessPolicy { + public: + ArmGpuBrokerProcessPolicy() : ArmGpuProcessPolicy(NULL, false) {} + virtual ~ArmGpuBrokerProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(ArmGpuBrokerProcessPolicy); +}; + +// A GPU broker policy is the same as a GPU policy with open and +// openat allowed. +ErrorCode ArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + switch (sysno) { + case __NR_access: + case __NR_open: + case __NR_openat: + return ErrorCode(ErrorCode::ERR_ALLOWED); + default: + return ArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); + } +} + +// Policy for renderer and worker processes. +// TODO(jln): move to renderer/ + +class RendererOrWorkerProcessPolicy : public SandboxBPFBasePolicy { + public: + RendererOrWorkerProcessPolicy() {} + virtual ~RendererOrWorkerProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(RendererOrWorkerProcessPolicy); +}; + +ErrorCode RendererOrWorkerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + switch (sysno) { + case __NR_clone: + return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); + case __NR_ioctl: + return sandbox::RestrictIoctl(sandbox); + case __NR_prctl: + return sandbox::RestrictPrctl(sandbox); + // Allow the system calls below. + case __NR_fdatasync: + case __NR_fsync: + case __NR_getpriority: +#if defined(__i386__) || defined(__x86_64__) + case __NR_getrlimit: +#endif +#if defined(__i386__) || defined(__arm__) + case __NR_ugetrlimit: +#endif + case __NR_mremap: // See crbug.com/149834. + case __NR_pread64: + case __NR_pwrite64: + case __NR_sched_getaffinity: + case __NR_sched_get_priority_max: + case __NR_sched_get_priority_min: + case __NR_sched_getparam: + case __NR_sched_getscheduler: + case __NR_sched_setscheduler: + case __NR_setpriority: + case __NR_sysinfo: + case __NR_times: + case __NR_uname: + return ErrorCode(ErrorCode::ERR_ALLOWED); + case __NR_prlimit64: + return ErrorCode(EPERM); // See crbug.com/160157. + default: + if (IsUsingToolKitGtk()) { +#if defined(__x86_64__) || defined(__arm__) + if (SyscallSets::IsSystemVSharedMemory(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); +#endif +#if defined(__i386__) + if (SyscallSets::IsSystemVIpc(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); +#endif + } + + // Default on the content baseline policy. + return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); + } +} + +// Policy for PPAPI plugins. +// TODO(jln): move to ppapi_plugin/. +class FlashProcessPolicy : public SandboxBPFBasePolicy { + public: + FlashProcessPolicy() {} + virtual ~FlashProcessPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(FlashProcessPolicy); +}; + +ErrorCode FlashProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + switch (sysno) { + case __NR_clone: + return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); + case __NR_pread64: + case __NR_pwrite64: + case __NR_sched_get_priority_max: + case __NR_sched_get_priority_min: + case __NR_sched_getaffinity: + case __NR_sched_getparam: + case __NR_sched_getscheduler: + case __NR_sched_setscheduler: + case __NR_times: + return ErrorCode(ErrorCode::ERR_ALLOWED); + case __NR_ioctl: + return ErrorCode(ENOTTY); // Flash Access. + default: + if (IsUsingToolKitGtk()) { +#if defined(__x86_64__) || defined(__arm__) + if (SyscallSets::IsSystemVSharedMemory(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); +#endif +#if defined(__i386__) + if (SyscallSets::IsSystemVIpc(sysno)) + return ErrorCode(ErrorCode::ERR_ALLOWED); +#endif + } + + // Default on the baseline policy. + return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); + } +} + +class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy { + public: + BlacklistDebugAndNumaPolicy() {} + virtual ~BlacklistDebugAndNumaPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy); +}; + +ErrorCode BlacklistDebugAndNumaPolicy::EvaluateSyscall(SandboxBPF* sandbox, + int sysno) const { + if (!SandboxBPF::IsValidSyscallNumber(sysno)) { + // TODO(jln) we should not have to do that in a trivial policy. + return ErrorCode(ENOSYS); + } + if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno)) + return sandbox->Trap(sandbox::CrashSIGSYS_Handler, NULL); + + return ErrorCode(ErrorCode::ERR_ALLOWED); +} + +class AllowAllPolicy : public SandboxBPFBasePolicy { + public: + AllowAllPolicy() {} + virtual ~AllowAllPolicy() {} + + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, + int system_call_number) const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); +}; + +// Allow all syscalls. +// This will still deny x32 or IA32 calls in 64 bits mode or +// 64 bits system calls in compatibility mode. +ErrorCode AllowAllPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { + if (!SandboxBPF::IsValidSyscallNumber(sysno)) { + // TODO(jln) we should not have to do that in a trivial policy. + return ErrorCode(ENOSYS); + } else { + return ErrorCode(ErrorCode::ERR_ALLOWED); + } +} + +// If a BPF policy is engaged for |process_type|, run a few sanity checks. +void RunSandboxSanityChecks(const std::string& process_type) { + if (process_type == switches::kRendererProcess || + process_type == switches::kWorkerProcess || + process_type == switches::kGpuProcess || + process_type == switches::kPpapiPluginProcess) { + 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(SandboxBPFBasePolicy::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) + } +} + +bool EnableGpuBrokerPolicyCallback() { + StartSandboxWithPolicy(new GpuBrokerProcessPolicy); + return true; +} + +bool EnableArmGpuBrokerPolicyCallback() { + StartSandboxWithPolicy(new ArmGpuBrokerProcessPolicy); + return true; +} + +// Files needed by the ARM GPU userspace. +static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2"; +static const char kLibEglPath[] = "/usr/lib/libEGL.so.1"; + +void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist, + std::vector<std::string>* write_whitelist) { + // Device file needed by the ARM GPU userspace. + static const char kMali0Path[] = "/dev/mali0"; + + // Devices needed for video decode acceleration on ARM. + static const char kDevMfcDecPath[] = "/dev/mfc-dec"; + static const char kDevGsc1Path[] = "/dev/gsc1"; + + // Devices needed for video encode acceleration on ARM. + static const char kDevMfcEncPath[] = "/dev/mfc-enc"; + + read_whitelist->push_back(kMali0Path); + read_whitelist->push_back(kDevMfcDecPath); + read_whitelist->push_back(kDevGsc1Path); + read_whitelist->push_back(kDevMfcEncPath); + + write_whitelist->push_back(kMali0Path); + write_whitelist->push_back(kDevMfcDecPath); + write_whitelist->push_back(kDevGsc1Path); + write_whitelist->push_back(kDevMfcEncPath); +} + +void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist, + std::vector<std::string>* write_whitelist) { + // Device files needed by the Tegra GPU userspace. + static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl"; + static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d"; + static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d"; + static const char kDevNvhostIspPath[] = "/dev/nvhost-isp"; + static const char kDevNvhostViPath[] = "/dev/nvhost-vi"; + static const char kDevNvmapPath[] = "/dev/nvmap"; + static const char kDevTegraSemaPath[] = "/dev/tegra_sema"; + + read_whitelist->push_back(kDevNvhostCtrlPath); + read_whitelist->push_back(kDevNvhostGr2dPath); + read_whitelist->push_back(kDevNvhostGr3dPath); + read_whitelist->push_back(kDevNvhostIspPath); + read_whitelist->push_back(kDevNvhostViPath); + read_whitelist->push_back(kDevNvmapPath); + read_whitelist->push_back(kDevTegraSemaPath); + + write_whitelist->push_back(kDevNvhostCtrlPath); + write_whitelist->push_back(kDevNvhostGr2dPath); + write_whitelist->push_back(kDevNvhostGr3dPath); + write_whitelist->push_back(kDevNvhostIspPath); + write_whitelist->push_back(kDevNvhostViPath); + write_whitelist->push_back(kDevNvmapPath); + write_whitelist->push_back(kDevTegraSemaPath); +} + +void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, + std::vector<std::string>* write_whitelist) { + // On ARM we're enabling the sandbox before the X connection is made, + // so we need to allow access to |.Xauthority|. + static const char kXAuthorityPath[] = "/home/chronos/.Xauthority"; + static const char kLdSoCache[] = "/etc/ld.so.cache"; + + read_whitelist->push_back(kXAuthorityPath); + read_whitelist->push_back(kLdSoCache); + read_whitelist->push_back(kLibGlesPath); + read_whitelist->push_back(kLibEglPath); + + AddArmMaliGpuWhitelist(read_whitelist, write_whitelist); + AddArmTegraGpuWhitelist(read_whitelist, write_whitelist); +} + +// Start a broker process to handle open() inside the sandbox. +void InitGpuBrokerProcess(bool for_chromeos_arm, + BrokerProcess** broker_process) { + static const char kDriRcPath[] = "/etc/drirc"; + static const char kDriCard0Path[] = "/dev/dri/card0"; + + CHECK(broker_process); + CHECK(*broker_process == NULL); + + bool (*sandbox_callback)(void) = NULL; + + // All GPU process policies need these files brokered out. + std::vector<std::string> read_whitelist; + read_whitelist.push_back(kDriCard0Path); + read_whitelist.push_back(kDriRcPath); + + std::vector<std::string> write_whitelist; + write_whitelist.push_back(kDriCard0Path); + + if (for_chromeos_arm) { + // We shouldn't be using this policy on non-ARM architectures. + DCHECK(IsArchitectureArm()); + AddArmGpuWhitelist(&read_whitelist, &write_whitelist); + sandbox_callback = EnableArmGpuBrokerPolicyCallback; + } else { + sandbox_callback = EnableGpuBrokerPolicyCallback; + } + + *broker_process = new BrokerProcess(SandboxBPFBasePolicy::GetFSDeniedErrno(), + read_whitelist, + write_whitelist); + // Initialize the broker process and give it a sandbox callback. + CHECK((*broker_process)->Init(sandbox_callback)); +} + +// Warms up/preloads resources needed by the policies. +// Eventually start a broker process and return it in broker_process. +void WarmupPolicy(bool chromeos_arm_gpu, + BrokerProcess** broker_process) { + if (!chromeos_arm_gpu) { + // Create a new broker process. + InitGpuBrokerProcess(false /* not for ChromeOS ARM */, broker_process); + + if (IsArchitectureX86_64() || IsArchitectureI386()) { + // Accelerated video decode dlopen()'s some shared objects + // inside the sandbox, so preload them now. + if (IsAcceleratedVideoDecodeEnabled()) { + const char* I965DrvVideoPath = NULL; + + if (IsArchitectureX86_64()) { + I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so"; + } else if (IsArchitectureI386()) { + I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so"; + } + + dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("libva.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("libva-x11.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + } + } + } else { + // ChromeOS ARM GPU policy. + // Create a new broker process. + InitGpuBrokerProcess(true /* for ChromeOS ARM */, broker_process); + + // Preload the Mali library. + dlopen("/usr/lib/libmali.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + + // Preload the Tegra libraries. + dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + } +} + +void StartGpuProcessSandbox(const CommandLine& command_line, + const std::string& process_type) { + bool chromeos_arm_gpu = false; + bool allow_sysv_shm = false; + + if (process_type == switches::kGpuProcess) { + // On Chrome OS ARM, we need a specific GPU process policy. + if (IsChromeOS() && IsArchitectureArm()) { + chromeos_arm_gpu = true; + if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { + allow_sysv_shm = true; + } + } + } + + // This should never be destroyed, as after the sandbox is started it is + // vital to the process. Ownership is transfered to the policies and then to + // the BPF sandbox which will keep it around to service SIGSYS traps from the + // kernel. + BrokerProcess* broker_process = NULL; + // Warm up resources needed by the policy we're about to enable and + // eventually start a broker process. + WarmupPolicy(chromeos_arm_gpu, &broker_process); + + scoped_ptr<SandboxBPFBasePolicy> gpu_policy; + if (chromeos_arm_gpu) { + gpu_policy.reset(new ArmGpuProcessPolicy(broker_process, allow_sysv_shm)); + } else { + gpu_policy.reset(new GpuProcessPolicy(broker_process)); + } + StartSandboxWithPolicy(gpu_policy.release()); +} + +// This function takes ownership of |policy|. +void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* 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; + sandbox.SetSandboxPolicy(policy); + sandbox.StartSandbox(); +} + +void StartNonGpuSandbox(const std::string& process_type) { + scoped_ptr<SandboxBPFBasePolicy> policy; + + if (process_type == switches::kRendererProcess || + process_type == switches::kWorkerProcess) { + policy.reset(new RendererOrWorkerProcessPolicy); + } else if (process_type == switches::kPpapiPluginProcess) { + policy.reset(new FlashProcessPolicy); + } else if (process_type == switches::kUtilityProcess) { + policy.reset(new BlacklistDebugAndNumaPolicy); + } else { + NOTREACHED(); + policy.reset(new AllowAllPolicy); + } + + StartSandboxWithPolicy(policy.release()); +} + +// Initialize the seccomp-bpf sandbox. +bool StartBPFSandbox(const CommandLine& command_line, + const std::string& process_type) { + + if (process_type == switches::kGpuProcess) { + StartGpuProcessSandbox(command_line, process_type); + } else { + StartNonGpuSandbox(process_type); + } + + RunSandboxSanityChecks(process_type); + return true; +} + +} // namespace + +#endif // SECCOMP_BPF_SANDBOX + +// Is seccomp BPF globally enabled? +bool SandboxSeccompBPF::IsSeccompBPFDesired() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (!command_line.HasSwitch(switches::kNoSandbox) && + !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { + return true; + } else { + return false; + } +} + +bool SandboxSeccompBPF::ShouldEnableSeccompBPF( + const std::string& process_type) { +#if defined(SECCOMP_BPF_SANDBOX) + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (process_type == switches::kGpuProcess) + return !command_line.HasSwitch(switches::kDisableGpuSandbox); + + return true; +#endif // SECCOMP_BPF_SANDBOX + return false; +} + +bool SandboxSeccompBPF::SupportsSandbox() { +#if defined(SECCOMP_BPF_SANDBOX) + // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton + // here. + SandboxBPF::SandboxStatus bpf_sandbox_status = + SandboxBPF::SupportsSeccompSandbox(-1); + // Kernel support is what we are interested in here. Other status + // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. + // We make this a negative check, since if there is a bug, we would rather + // "fail closed" (expect a sandbox to be available and try to start it). + if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { + return true; + } +#endif + return false; +} + +bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { +#if defined(SECCOMP_BPF_SANDBOX) + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + + if (IsSeccompBPFDesired() && // Global switches policy. + ShouldEnableSeccompBPF(process_type) && // Process-specific policy. + SupportsSandbox()) { + // If the kernel supports the sandbox, and if the command line says we + // should enable it, enable it or die. + bool started_sandbox = StartBPFSandbox(command_line, process_type); + CHECK(started_sandbox); + return true; + } +#endif + return false; +} + +bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( + scoped_ptr<sandbox::SandboxBPFPolicy> policy) { +#if defined(SECCOMP_BPF_SANDBOX) + if (IsSeccompBPFDesired() && SupportsSandbox()) { + CHECK(policy); + StartSandboxWithPolicy(policy.release()); + return true; + } +#endif // defined(SECCOMP_BPF_SANDBOX) + return false; +} + +scoped_ptr<sandbox::SandboxBPFPolicy> +SandboxSeccompBPF::GetBaselinePolicy() { +#if defined(SECCOMP_BPF_SANDBOX) + return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); +#else + return scoped_ptr<sandbox::SandboxBPFPolicy>(); +#endif // defined(SECCOMP_BPF_SANDBOX) +} + +} // namespace content diff --git a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h b/content/common/sandbox_seccomp_bpf_linux.h index cbf6daf..a3f6877 100644 --- a/content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h +++ b/content/common/sandbox_seccomp_bpf_linux.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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 CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ -#define CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ +#ifndef CONTENT_COMMON_SANDBOX_SECCOMP_BPF_LINUX_H_ +#define CONTENT_COMMON_SANDBOX_SECCOMP_BPF_LINUX_H_ #include <string> @@ -49,5 +49,5 @@ class SandboxSeccompBPF { } // namespace content -#endif // CONTENT_COMMON_SANDBOX_LINUX_SANDBOX_SECCOMP_BPF_LINUX_H_ +#endif // CONTENT_COMMON_SANDBOX_SECCOMP_BPF_LINUX_H_ diff --git a/content/content_common.gypi b/content/content_common.gypi index bafc275..a7ef06c 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -347,22 +347,18 @@ 'common/quota_messages.h', 'common/resource_messages.cc', 'common/resource_messages.h', + 'common/sandbox_bpf_base_policy_linux.cc', + 'common/sandbox_bpf_base_policy_linux.h', + 'common/sandbox_init_linux.cc', 'common/sandbox_init_mac.cc', 'common/sandbox_init_mac.h', 'common/sandbox_init_win.cc', - 'common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc', - 'common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h', - 'common/sandbox_linux/bpf_gpu_policy_linux.cc', - 'common/sandbox_linux/bpf_gpu_policy_linux.h', - 'common/sandbox_linux/sandbox_bpf_base_policy_linux.cc', - 'common/sandbox_linux/sandbox_bpf_base_policy_linux.h', - 'common/sandbox_linux/sandbox_init_linux.cc', - 'common/sandbox_linux/sandbox_linux.cc', - 'common/sandbox_linux/sandbox_linux.h', - 'common/sandbox_linux/sandbox_seccomp_bpf_linux.cc', - 'common/sandbox_linux/sandbox_seccomp_bpf_linux.h', + 'common/sandbox_linux.cc', + 'common/sandbox_linux.h', 'common/sandbox_mac.h', 'common/sandbox_mac.mm', + 'common/sandbox_seccomp_bpf_linux.cc', + 'common/sandbox_seccomp_bpf_linux.h', 'common/sandbox_util.cc', 'common/sandbox_util.h', 'common/sandbox_win.cc', diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 35fa4be..766fc91 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc @@ -22,7 +22,7 @@ #include "content/common/content_constants_internal.h" #include "content/common/gpu/gpu_config.h" #include "content/common/gpu/gpu_messages.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/gpu/gpu_child_thread.h" #include "content/gpu/gpu_process.h" #include "content/gpu/gpu_watchdog_thread.h" diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc index 58ca930..dc7cf4a 100644 --- a/content/ppapi_plugin/ppapi_plugin_main.cc +++ b/content/ppapi_plugin/ppapi_plugin_main.cc @@ -10,7 +10,7 @@ #include "build/build_config.h" #include "content/child/child_process.h" #include "content/common/content_constants_internal.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/ppapi_plugin/ppapi_thread.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" diff --git a/content/renderer/renderer_main_platform_delegate_linux.cc b/content/renderer/renderer_main_platform_delegate_linux.cc index bc9deec..135a084 100644 --- a/content/renderer/renderer_main_platform_delegate_linux.cc +++ b/content/renderer/renderer_main_platform_delegate_linux.cc @@ -10,7 +10,7 @@ #include "base/command_line.h" #include "base/file_util.h" #include "base/logging.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/public/common/content_switches.h" #include "content/public/common/sandbox_init.h" diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc index a522427..c150d94 100644 --- a/content/utility/utility_main.cc +++ b/content/utility/utility_main.cc @@ -8,7 +8,7 @@ #include "base/threading/platform_thread.h" #include "base/timer/hi_res_timer_manager.h" #include "content/child/child_process.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/public/common/sandbox_init.h" diff --git a/content/worker/worker_main.cc b/content/worker/worker_main.cc index 8cc8ed0..4dae444 100644 --- a/content/worker/worker_main.cc +++ b/content/worker/worker_main.cc @@ -9,7 +9,7 @@ #include "base/threading/platform_thread.h" #include "base/timer/hi_res_timer_manager.h" #include "content/child/child_process.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/public/common/main_function_params.h" #include "content/public/common/sandbox_init.h" #include "content/worker/worker_thread.h" diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc index 2f0bd20..759a920 100644 --- a/content/zygote/zygote_linux.cc +++ b/content/zygote/zygote_linux.cc @@ -21,7 +21,7 @@ #include "base/posix/unix_domain_socket_linux.h" #include "base/process/kill.h" #include "content/common/child_process_sandbox_support_impl_linux.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/common/set_process_title.h" #include "content/common/zygote_commands_linux.h" #include "content/public/common/content_descriptors.h" diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index 8e91c2f..9189321 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc @@ -29,7 +29,7 @@ #include "content/common/child_process_sandbox_support_impl_linux.h" #include "content/common/font_config_ipc_linux.h" #include "content/common/pepper_plugin_list.h" -#include "content/common/sandbox_linux/sandbox_linux.h" +#include "content/common/sandbox_linux.h" #include "content/common/zygote_commands_linux.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" |