| Index: content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc
|
| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..09ccdeba1f32f60e036dd8f823711d387dd7f262
|
| --- /dev/null
|
| +++ b/content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc
|
| @@ -0,0 +1,226 @@
|
| +// 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
|
|
|