// 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 #include #include #include #include #include #include #include #include #include "base/bind.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "build/build_config.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/bpf_dsl/bpf_dsl.h" #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" #include "sandbox/linux/syscall_broker/broker_file_permission.h" #include "sandbox/linux/system_headers/linux_syscalls.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::syscall_broker::BrokerFilePermission; 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__) || defined(__aarch64__) return true; #else return false; #endif } void AddArmMaliGpuWhitelist(std::vector* permissions) { // Device file needed by the ARM GPU userspace. static const char kMali0Path[] = "/dev/mali0"; // Image processor used on ARM platforms. static const char kDevImageProc0Path[] = "/dev/image-proc0"; permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path)); permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path)); } void AddArmGpuWhitelist(std::vector* permissions) { // 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"; permissions->push_back(BrokerFilePermission::ReadOnly(kXAuthorityPath)); permissions->push_back(BrokerFilePermission::ReadOnly(kLdSoCache)); permissions->push_back(BrokerFilePermission::ReadOnly(kLibGlesPath)); permissions->push_back(BrokerFilePermission::ReadOnly(kLibEglPath)); AddArmMaliGpuWhitelist(permissions); } class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy { public: static sandbox::bpf_dsl::Policy* Create() { return new CrosArmGpuBrokerProcessPolicy(); } ~CrosArmGpuBrokerProcessPolicy() override {} ResultExpr EvaluateSyscall(int system_call_number) const override; private: CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {} DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy); }; // A GPU broker policy is the same as a GPU policy with open and // openat allowed. ResultExpr CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(int sysno) const { switch (sysno) { #if !defined(__aarch64__) case __NR_access: case __NR_open: #endif // !defined(__aarch64__) case __NR_faccessat: case __NR_openat: return Allow(); default: return CrosArmGpuProcessPolicy::EvaluateSyscall(sysno); } } } // namespace CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat) : allow_shmat_(allow_shmat) {} 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 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); } } bool CrosArmGpuProcessPolicy::PreSandboxHook() { DCHECK(IsChromeOS() && IsArchitectureArm()); // Create a new broker process. DCHECK(!broker_process()); // Add ARM-specific files to whitelist in the broker. std::vector permissions; AddArmGpuWhitelist(&permissions); InitGpuBrokerProcess(CrosArmGpuBrokerProcessPolicy::Create, permissions); const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE; // Preload the Mali library. dlopen("/usr/lib/libmali.so", dlopen_flag); // Preload the Tegra V4L2 (video decode acceleration) library. dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag); // Resetting errno since platform-specific libraries will fail on other // platforms. errno = 0; return true; } } // namespace content