OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h" | |
6 | |
7 #include <dlfcn.h> | |
8 #include <errno.h> | |
9 #include <fcntl.h> | |
10 #include <sys/socket.h> | |
11 #include <sys/stat.h> | |
12 #include <sys/types.h> | |
13 #include <unistd.h> | |
14 | |
15 #include <string> | |
16 #include <vector> | |
17 | |
18 #include "base/compiler_specific.h" | |
19 #include "base/logging.h" | |
20 #include "base/memory/scoped_ptr.h" | |
21 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" | |
22 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" | |
23 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" | |
24 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | |
25 #include "sandbox/linux/services/linux_syscalls.h" | |
26 | |
27 using sandbox::ErrorCode; | |
28 using sandbox::SandboxBPF; | |
29 using sandbox::SyscallSets; | |
30 | |
31 namespace content { | |
32 | |
33 namespace { | |
34 | |
35 inline bool IsChromeOS() { | |
36 #if defined(OS_CHROMEOS) | |
37 return true; | |
38 #else | |
39 return false; | |
40 #endif | |
41 } | |
42 | |
43 inline bool IsArchitectureArm() { | |
44 #if defined(__arm__) | |
45 return true; | |
46 #else | |
47 return false; | |
48 #endif | |
49 } | |
50 | |
51 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist, | |
52 std::vector<std::string>* write_whitelist) { | |
53 // Device file needed by the ARM GPU userspace. | |
54 static const char kMali0Path[] = "/dev/mali0"; | |
55 | |
56 // Devices needed for video decode acceleration on ARM. | |
57 static const char kDevMfcDecPath[] = "/dev/mfc-dec"; | |
58 static const char kDevGsc1Path[] = "/dev/gsc1"; | |
59 | |
60 // Devices needed for video encode acceleration on ARM. | |
61 static const char kDevMfcEncPath[] = "/dev/mfc-enc"; | |
62 | |
63 read_whitelist->push_back(kMali0Path); | |
64 read_whitelist->push_back(kDevMfcDecPath); | |
65 read_whitelist->push_back(kDevGsc1Path); | |
66 read_whitelist->push_back(kDevMfcEncPath); | |
67 | |
68 write_whitelist->push_back(kMali0Path); | |
69 write_whitelist->push_back(kDevMfcDecPath); | |
70 write_whitelist->push_back(kDevGsc1Path); | |
71 write_whitelist->push_back(kDevMfcEncPath); | |
72 } | |
73 | |
74 void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist, | |
75 std::vector<std::string>* write_whitelist) { | |
76 // Device files needed by the Tegra GPU userspace. | |
77 static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl"; | |
78 static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d"; | |
79 static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d"; | |
80 static const char kDevNvhostIspPath[] = "/dev/nvhost-isp"; | |
81 static const char kDevNvhostViPath[] = "/dev/nvhost-vi"; | |
82 static const char kDevNvmapPath[] = "/dev/nvmap"; | |
83 static const char kDevTegraSemaPath[] = "/dev/tegra_sema"; | |
84 | |
85 read_whitelist->push_back(kDevNvhostCtrlPath); | |
86 read_whitelist->push_back(kDevNvhostGr2dPath); | |
87 read_whitelist->push_back(kDevNvhostGr3dPath); | |
88 read_whitelist->push_back(kDevNvhostIspPath); | |
89 read_whitelist->push_back(kDevNvhostViPath); | |
90 read_whitelist->push_back(kDevNvmapPath); | |
91 read_whitelist->push_back(kDevTegraSemaPath); | |
92 | |
93 write_whitelist->push_back(kDevNvhostCtrlPath); | |
94 write_whitelist->push_back(kDevNvhostGr2dPath); | |
95 write_whitelist->push_back(kDevNvhostGr3dPath); | |
96 write_whitelist->push_back(kDevNvhostIspPath); | |
97 write_whitelist->push_back(kDevNvhostViPath); | |
98 write_whitelist->push_back(kDevNvmapPath); | |
99 write_whitelist->push_back(kDevTegraSemaPath); | |
100 } | |
101 | |
102 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, | |
103 std::vector<std::string>* write_whitelist) { | |
104 // On ARM we're enabling the sandbox before the X connection is made, | |
105 // so we need to allow access to |.Xauthority|. | |
106 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority"; | |
107 static const char kLdSoCache[] = "/etc/ld.so.cache"; | |
108 | |
109 // Files needed by the ARM GPU userspace. | |
110 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2"; | |
111 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1"; | |
112 | |
113 read_whitelist->push_back(kXAuthorityPath); | |
114 read_whitelist->push_back(kLdSoCache); | |
115 read_whitelist->push_back(kLibGlesPath); | |
116 read_whitelist->push_back(kLibEglPath); | |
117 | |
118 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist); | |
119 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist); | |
120 } | |
121 | |
122 class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy { | |
123 public: | |
124 CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {} | |
125 virtual ~CrosArmGpuBrokerProcessPolicy() {} | |
126 | |
127 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | |
128 int system_call_number) const OVERRIDE; | |
129 | |
130 private: | |
131 DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy); | |
132 }; | |
133 | |
134 // A GPU broker policy is the same as a GPU policy with open and | |
135 // openat allowed. | |
136 ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
137 int sysno) const { | |
138 switch (sysno) { | |
139 case __NR_access: | |
140 case __NR_open: | |
141 case __NR_openat: | |
142 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
143 default: | |
144 return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | |
145 } | |
146 } | |
147 | |
148 bool EnableArmGpuBrokerPolicyCallback() { | |
149 return SandboxSeccompBPF::StartSandboxWithExternalPolicy( | |
150 scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy)); | |
151 } | |
152 | |
153 } // namespace | |
154 | |
155 CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_shmat) | |
156 : allow_shmat_(allow_shmat) {} | |
157 | |
158 CrosArmGpuProcessPolicy::~CrosArmGpuProcessPolicy() {} | |
159 | |
160 ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
161 int sysno) const { | |
162 #if defined(__arm__) | |
163 if (allow_shmat_ && sysno == __NR_shmat) | |
164 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
165 #endif // defined(__arm__) | |
166 | |
167 switch (sysno) { | |
168 #if defined(__arm__) | |
169 // ARM GPU sandbox is started earlier so we need to allow networking | |
170 // in the sandbox. | |
171 case __NR_connect: | |
172 case __NR_getpeername: | |
173 case __NR_getsockname: | |
174 case __NR_sysinfo: | |
175 case __NR_uname: | |
176 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
177 // Allow only AF_UNIX for |domain|. | |
178 case __NR_socket: | |
179 case __NR_socketpair: | |
180 return sandbox->Cond(0, ErrorCode::TP_32BIT, | |
181 ErrorCode::OP_EQUAL, AF_UNIX, | |
182 ErrorCode(ErrorCode::ERR_ALLOWED), | |
183 ErrorCode(EPERM)); | |
184 #endif // defined(__arm__) | |
185 default: | |
186 if (SyscallSets::IsAdvancedScheduler(sysno)) | |
187 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
188 | |
189 // Default to the generic GPU policy. | |
190 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | |
191 } | |
192 } | |
193 | |
194 bool CrosArmGpuProcessPolicy::PreSandboxHook() { | |
195 DCHECK(IsChromeOS() && IsArchitectureArm()); | |
196 // Create a new broker process. | |
197 DCHECK(!broker_process()); | |
198 | |
199 std::vector<std::string> read_whitelist_extra; | |
200 std::vector<std::string> write_whitelist_extra; | |
201 // Add ARM-specific files to whitelist in the broker. | |
202 | |
203 AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra); | |
204 InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback, | |
205 read_whitelist_extra, | |
206 write_whitelist_extra); | |
207 | |
208 const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE; | |
209 | |
210 // Preload the Mali library. | |
211 dlopen("/usr/lib/libmali.so", dlopen_flag); | |
212 | |
213 // Preload the Tegra libraries. | |
214 dlopen("/usr/lib/libnvrm.so", dlopen_flag); | |
215 dlopen("/usr/lib/libnvrm_graphics.so", dlopen_flag); | |
216 dlopen("/usr/lib/libnvos.so", dlopen_flag); | |
217 dlopen("/usr/lib/libnvddk_2d.so", dlopen_flag); | |
218 dlopen("/usr/lib/libardrv_dynamic.so", dlopen_flag); | |
219 dlopen("/usr/lib/libnvwsi.so", dlopen_flag); | |
220 dlopen("/usr/lib/libnvglsi.so", dlopen_flag); | |
221 dlopen("/usr/lib/libcgdrv.so", dlopen_flag); | |
222 | |
223 return true; | |
224 } | |
225 | |
226 } // namespace content | |
OLD | NEW |