Chromium Code Reviews| Index: content/common/sandbox_linux/sandbox_bpf_cros_arm_gpu_policy_linux.cc |
| diff --git a/content/common/sandbox_linux/sandbox_bpf_cros_arm_gpu_policy_linux.cc b/content/common/sandbox_linux/sandbox_bpf_cros_arm_gpu_policy_linux.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4bfe5dd473b4f4b7048ed62ed5b326da12978143 |
| --- /dev/null |
| +++ b/content/common/sandbox_linux/sandbox_bpf_cros_arm_gpu_policy_linux.cc |
| @@ -0,0 +1,219 @@ |
| +// 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/sandbox_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 |
| + |
| +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); |
| + |
| + // Preload the Mali library. |
| + dlopen("/usr/lib/libmali.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); |
|
Robert Sesek
2013/12/12 21:33:48
Maybe pull these flags out into a constant and pas
jln (very slow on Chromium)
2013/12/12 22:15:14
Done.
|
| + |
| + // 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); |
| + |
| + return true; |
| +} |
| + |
| +} // namespace content |