1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h"
10 #include <sys/socket.h>
12 #include <sys/types.h>
18 #include "base/compiler_specific.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "build/build_config.h"
22 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
23 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h"
24 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
25 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
26 #include "sandbox/linux/services/linux_syscalls.h"
28 using sandbox::ErrorCode;
29 using sandbox::SandboxBPF;
30 using sandbox::SyscallSets;
36 inline bool IsChromeOS() {
37 #if defined(OS_CHROMEOS)
44 inline bool IsArchitectureArm() {
52 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
53 std::vector<std::string>* write_whitelist) {
54 // Device file needed by the ARM GPU userspace.
55 static const char kMali0Path[] = "/dev/mali0";
57 // Devices needed for video decode acceleration on ARM.
58 static const char kDevMfcDecPath[] = "/dev/mfc-dec";
59 static const char kDevGsc1Path[] = "/dev/gsc1";
61 // Devices needed for video encode acceleration on ARM.
62 static const char kDevMfcEncPath[] = "/dev/mfc-enc";
64 read_whitelist->push_back(kMali0Path);
65 read_whitelist->push_back(kDevMfcDecPath);
66 read_whitelist->push_back(kDevGsc1Path);
67 read_whitelist->push_back(kDevMfcEncPath);
69 write_whitelist->push_back(kMali0Path);
70 write_whitelist->push_back(kDevMfcDecPath);
71 write_whitelist->push_back(kDevGsc1Path);
72 write_whitelist->push_back(kDevMfcEncPath);
75 void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
76 std::vector<std::string>* write_whitelist) {
77 // Device files needed by the Tegra GPU userspace.
78 static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
79 static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
80 static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
81 static const char kDevNvmapPath[] = "/dev/nvmap";
82 static const char kDevNvhostGpuPath[] = "/dev/nvhost-gpu";
83 static const char kDevNvhostAsGpuPath[] = "/dev/nvhost-as-gpu";
84 static const char kDevNvhostCtrlGpuPath[] = "/dev/nvhost-ctrl-gpu";
85 static const char kSysDevicesSocIDPath[] = "/sys/devices/soc0/soc_id";
86 static const char kSysDevicesSocRevPath[] = "/sys/devices/soc0/revision";
87 // TODO(davidung): remove these device nodes before nyan launch.
89 read_whitelist->push_back(kDevNvhostCtrlPath);
90 read_whitelist->push_back(kDevNvhostIspPath);
91 read_whitelist->push_back(kDevNvhostViPath);
92 read_whitelist->push_back(kDevNvmapPath);
93 read_whitelist->push_back(kDevNvhostGpuPath);
94 read_whitelist->push_back(kDevNvhostAsGpuPath);
95 read_whitelist->push_back(kDevNvhostCtrlGpuPath);
96 read_whitelist->push_back(kSysDevicesSocIDPath);
97 read_whitelist->push_back(kSysDevicesSocRevPath);
99 write_whitelist->push_back(kDevNvhostCtrlPath);
100 write_whitelist->push_back(kDevNvhostIspPath);
101 write_whitelist->push_back(kDevNvhostViPath);
102 write_whitelist->push_back(kDevNvmapPath);
103 write_whitelist->push_back(kDevNvhostGpuPath);
104 write_whitelist->push_back(kDevNvhostAsGpuPath);
105 write_whitelist->push_back(kDevNvhostCtrlGpuPath);
108 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
109 std::vector<std::string>* write_whitelist) {
110 // On ARM we're enabling the sandbox before the X connection is made,
111 // so we need to allow access to |.Xauthority|.
112 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
113 static const char kLdSoCache[] = "/etc/ld.so.cache";
115 // Files needed by the ARM GPU userspace.
116 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
117 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
119 read_whitelist->push_back(kXAuthorityPath);
120 read_whitelist->push_back(kLdSoCache);
121 read_whitelist->push_back(kLibGlesPath);
122 read_whitelist->push_back(kLibEglPath);
124 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
125 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
128 class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy {
130 CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {}
131 virtual ~CrosArmGpuBrokerProcessPolicy() {}
133 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
134 int system_call_number) const OVERRIDE;
137 DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy);
140 // A GPU broker policy is the same as a GPU policy with open and
142 ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
148 return ErrorCode(ErrorCode::ERR_ALLOWED);
150 return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
154 bool EnableArmGpuBrokerPolicyCallback() {
155 return SandboxSeccompBPF::StartSandboxWithExternalPolicy(
156 scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy));
161 CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat)
162 : allow_shmat_(allow_shmat) {}
164 CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {}
166 ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
169 if (allow_shmat_ && sysno == __NR_shmat)
170 return ErrorCode(ErrorCode::ERR_ALLOWED);
171 #endif // defined(__arm__)
175 // ARM GPU sandbox is started earlier so we need to allow networking
178 case __NR_getpeername:
179 case __NR_getsockname:
182 return ErrorCode(ErrorCode::ERR_ALLOWED);
183 // Allow only AF_UNIX for |domain|.
185 case __NR_socketpair:
186 return sandbox->Cond(0, ErrorCode::TP_32BIT,
187 ErrorCode::OP_EQUAL, AF_UNIX,
188 ErrorCode(ErrorCode::ERR_ALLOWED),
190 #endif // defined(__arm__)
192 if (SyscallSets::IsAdvancedScheduler(sysno))
193 return ErrorCode(ErrorCode::ERR_ALLOWED);
195 // Default to the generic GPU policy.
196 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno);
200 bool CrosArmGpuProcessPolicy::PreSandboxHook() {
201 DCHECK(IsChromeOS() && IsArchitectureArm());
202 // Create a new broker process.
203 DCHECK(!broker_process());
205 std::vector<std::string> read_whitelist_extra;
206 std::vector<std::string> write_whitelist_extra;
207 // Add ARM-specific files to whitelist in the broker.
209 AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra);
210 InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback,
211 read_whitelist_extra,
212 write_whitelist_extra);
214 const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
216 // Preload the Mali library.
217 dlopen("/usr/lib/libmali.so", dlopen_flag);
219 // Preload the Tegra libraries.
220 dlopen("/usr/lib/libnvrm.so", dlopen_flag);
221 dlopen("/usr/lib/libnvrm_graphics.so", dlopen_flag);
222 dlopen("/usr/lib/libnvidia-glsi.so", dlopen_flag);
223 dlopen("/usr/lib/libnvidia-rmapi-tegra.so", dlopen_flag);
224 dlopen("/usr/lib/libnvidia-eglcore.so", dlopen_flag);
225 // TODO(davidung): remove these libraries before nyan launch.
230 } // namespace content