OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <asm/unistd.h> | 5 #include "content/common/sandbox_linux/sandbox_bpf_gpu_policy_linux.h" |
6 | |
6 #include <dlfcn.h> | 7 #include <dlfcn.h> |
7 #include <errno.h> | 8 #include <errno.h> |
8 #include <fcntl.h> | 9 #include <fcntl.h> |
9 #include <linux/net.h> | |
10 #include <signal.h> | |
11 #include <string.h> | |
12 #include <sys/ioctl.h> | |
13 #include <sys/mman.h> | |
14 #include <sys/prctl.h> | |
15 #include <sys/socket.h> | 10 #include <sys/socket.h> |
16 #include <sys/stat.h> | 11 #include <sys/stat.h> |
17 #include <sys/types.h> | 12 #include <sys/types.h> |
18 #include <ucontext.h> | |
19 #include <unistd.h> | 13 #include <unistd.h> |
20 | 14 |
15 #include <string> | |
21 #include <vector> | 16 #include <vector> |
22 | 17 |
23 #include "base/basictypes.h" | |
24 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/compiler_specific.h" | |
25 #include "base/logging.h" | 20 #include "base/logging.h" |
26 #include "build/build_config.h" | 21 #include "base/memory/scoped_ptr.h" |
27 #include "content/common/sandbox_linux.h" | 22 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" |
28 #include "content/common/sandbox_seccomp_bpf_linux.h" | 23 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" |
29 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
30 #include "sandbox/linux/services/broker_process.h" | |
31 | |
32 // These are the only architectures supported for now. | |
33 #if defined(__i386__) || defined(__x86_64__) || \ | |
34 (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) | |
35 #define SECCOMP_BPF_SANDBOX | |
36 #endif | |
37 | |
38 #if defined(SECCOMP_BPF_SANDBOX) | |
39 #include "base/posix/eintr_wrapper.h" | |
40 #include "content/common/sandbox_bpf_base_policy_linux.h" | |
41 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" | |
42 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" | |
43 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | |
44 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" | 25 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" |
45 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 26 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
46 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 27 #include "sandbox/linux/services/broker_process.h" |
47 #include "sandbox/linux/services/linux_syscalls.h" | 28 #include "sandbox/linux/services/linux_syscalls.h" |
48 | 29 |
49 using sandbox::BaselinePolicy; | |
50 using sandbox::BrokerProcess; | 30 using sandbox::BrokerProcess; |
51 using sandbox::ErrorCode; | 31 using sandbox::ErrorCode; |
52 using sandbox::SandboxBPF; | 32 using sandbox::SandboxBPF; |
53 using sandbox::SyscallSets; | 33 using sandbox::SyscallSets; |
54 using sandbox::arch_seccomp_data; | 34 using sandbox::arch_seccomp_data; |
55 | 35 |
56 namespace content { | 36 namespace content { |
57 | 37 |
58 namespace { | 38 namespace { |
59 | 39 |
60 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); | 40 void InitGpuBrokerProcess(bool (*broker_sandboxer_callback)(void), |
41 bool for_chromeos_arm, | |
42 const std::vector<std::string>& read_whitelist_extra, | |
43 const std::vector<std::string>& write_whitelist_extra, | |
44 BrokerProcess** broker_process); | |
45 | |
46 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, | |
47 std::vector<std::string>* write_whitelist); | |
48 bool EnableGpuBrokerPolicyCallback(); | |
49 bool EnableArmGpuBrokerPolicyCallback(); | |
61 | 50 |
62 inline bool IsChromeOS() { | 51 inline bool IsChromeOS() { |
63 #if defined(OS_CHROMEOS) | 52 #if defined(OS_CHROMEOS) |
64 return true; | 53 return true; |
65 #else | 54 #else |
66 return false; | 55 return false; |
67 #endif | 56 #endif |
68 } | 57 } |
69 | 58 |
70 inline bool IsArchitectureX86_64() { | 59 inline bool IsArchitectureX86_64() { |
(...skipping 13 matching lines...) Expand all Loading... | |
84 } | 73 } |
85 | 74 |
86 inline bool IsArchitectureArm() { | 75 inline bool IsArchitectureArm() { |
87 #if defined(__arm__) | 76 #if defined(__arm__) |
88 return true; | 77 return true; |
89 #else | 78 #else |
90 return false; | 79 return false; |
91 #endif | 80 #endif |
92 } | 81 } |
93 | 82 |
94 inline bool IsUsingToolKitGtk() { | |
95 #if defined(TOOLKIT_GTK) | |
96 return true; | |
97 #else | |
98 return false; | |
99 #endif | |
100 } | |
101 | |
102 // Policies for the GPU process. | |
103 // TODO(jln): move to gpu/ | |
104 | |
105 bool IsAcceleratedVideoDecodeEnabled() { | 83 bool IsAcceleratedVideoDecodeEnabled() { |
106 // Accelerated video decode is currently enabled on Chrome OS, | 84 // Accelerated video decode is currently enabled on Chrome OS, |
107 // but not on Linux: crbug.com/137247. | 85 // but not on Linux: crbug.com/137247. |
108 bool is_enabled = IsChromeOS(); | 86 bool is_enabled = IsChromeOS(); |
109 | 87 |
110 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 88 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
111 is_enabled = is_enabled && | 89 is_enabled = is_enabled && |
112 !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode); | 90 !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode); |
113 | 91 |
114 return is_enabled; | 92 return is_enabled; |
(...skipping 21 matching lines...) Expand all Loading... | |
136 return -EPERM; | 114 return -EPERM; |
137 } | 115 } |
138 default: | 116 default: |
139 RAW_CHECK(false); | 117 RAW_CHECK(false); |
140 return -ENOSYS; | 118 return -ENOSYS; |
141 } | 119 } |
142 } | 120 } |
143 | 121 |
144 class GpuProcessPolicy : public SandboxBPFBasePolicy { | 122 class GpuProcessPolicy : public SandboxBPFBasePolicy { |
145 public: | 123 public: |
146 explicit GpuProcessPolicy(void* broker_process) | 124 GpuProcessPolicy() : broker_process_(NULL) {} |
147 : broker_process_(broker_process) {} | |
148 virtual ~GpuProcessPolicy() {} | 125 virtual ~GpuProcessPolicy() {} |
149 | 126 |
150 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 127 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
151 int system_call_number) const OVERRIDE; | 128 int system_call_number) const OVERRIDE; |
129 virtual bool PreSandboxHook() OVERRIDE; | |
130 | |
131 protected: | |
132 BrokerProcess* broker_process() { return broker_process_; } | |
133 void set_broker_process(BrokerProcess* broker_process) { | |
Jorge Lucangeli Obes
2013/12/12 21:37:21
Is this the correct style for the setter?
Robert Sesek
2013/12/12 21:41:43
Yes, simple accessors use unix_hacker_style and ge
jln (very slow on Chromium)
2013/12/12 22:15:14
Done.
jln (very slow on Chromium)
2013/12/12 22:15:14
Done.
| |
134 broker_process_ = broker_process; | |
135 } | |
152 | 136 |
153 private: | 137 private: |
154 const void* broker_process_; // Non-owning pointer. | 138 // A BrokerProcess is a helper that is started before the sandbox is engaged |
139 // and will serve requests to access files over an IPC. The client of this | |
Jorge Lucangeli Obes
2013/12/12 21:37:21
I would say "over IPC" or "over an IPC channel".
jln (very slow on Chromium)
2013/12/12 22:15:14
Done.
| |
140 // runs from a SIGSYS handler triggered by the seccomp-bpf sandbox. | |
141 // This should never be destroyed, as after the sandbox is started it is | |
142 // vital to the process. | |
143 // This is allocated by PreSandboxHook(), which executes iff the sandbox | |
144 // is going to be enabled afterwards. | |
145 BrokerProcess* broker_process_; | |
155 DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); | 146 DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); |
156 }; | 147 }; |
157 | 148 |
158 // Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy. | 149 // Main policy for x86_64/i386. Extended by CrosArmGpuProcessPolicy. |
159 ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 150 ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
160 int sysno) const { | 151 int sysno) const { |
161 switch (sysno) { | 152 switch (sysno) { |
162 case __NR_ioctl: | 153 case __NR_ioctl: |
163 #if defined(__i386__) || defined(__x86_64__) | 154 #if defined(__i386__) || defined(__x86_64__) |
164 // The Nvidia driver uses flags not in the baseline policy | 155 // The Nvidia driver uses flags not in the baseline policy |
165 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) | 156 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) |
166 case __NR_mmap: | 157 case __NR_mmap: |
167 #endif | 158 #endif |
168 // We also hit this on the linux_chromeos bot but don't yet know what | 159 // We also hit this on the linux_chromeos bot but don't yet know what |
169 // weird flags were involved. | 160 // weird flags were involved. |
170 case __NR_mprotect: | 161 case __NR_mprotect: |
171 case __NR_sched_getaffinity: | 162 case __NR_sched_getaffinity: |
172 case __NR_sched_setaffinity: | 163 case __NR_sched_setaffinity: |
173 case __NR_setpriority: | 164 case __NR_setpriority: |
174 return ErrorCode(ErrorCode::ERR_ALLOWED); | 165 return ErrorCode(ErrorCode::ERR_ALLOWED); |
175 case __NR_access: | 166 case __NR_access: |
176 case __NR_open: | 167 case __NR_open: |
177 case __NR_openat: | 168 case __NR_openat: |
169 DCHECK(broker_process_); | |
178 return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); | 170 return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); |
179 default: | 171 default: |
180 if (SyscallSets::IsEventFd(sysno)) | 172 if (SyscallSets::IsEventFd(sysno)) |
181 return ErrorCode(ErrorCode::ERR_ALLOWED); | 173 return ErrorCode(ErrorCode::ERR_ALLOWED); |
182 | 174 |
183 // Default on the baseline policy. | 175 // Default on the baseline policy. |
184 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); | 176 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); |
185 } | 177 } |
186 } | 178 } |
187 | 179 |
180 bool GpuProcessPolicy::PreSandboxHook() { | |
181 // Warm up resources needed by the policy we're about to enable and | |
182 // eventually start a broker process. | |
183 const bool chromeos_arm_gpu = IsChromeOS() && IsArchitectureArm(); | |
184 DCHECK(!chromeos_arm_gpu); | |
Jorge Lucangeli Obes
2013/12/12 21:37:21
Maybe add a comment reminding the reader "This pol
jln (very slow on Chromium)
2013/12/12 22:15:14
Done, but not that it's also used on ARM desktop.
| |
185 | |
186 BrokerProcess* broker_process_temp = NULL; | |
187 DCHECK(!broker_process()); | |
188 // Create a new broker process. | |
189 InitGpuBrokerProcess( | |
190 EnableGpuBrokerPolicyCallback, | |
191 false /* not for ChromeOS ARM */, | |
192 std::vector<std::string>(), // No extra files in whitelist. | |
193 std::vector<std::string>(), | |
194 &broker_process_temp); | |
195 set_broker_process(broker_process_temp); | |
196 | |
197 if (IsArchitectureX86_64() || IsArchitectureI386()) { | |
198 // Accelerated video decode dlopen()'s some shared objects | |
199 // inside the sandbox, so preload them now. | |
200 if (IsAcceleratedVideoDecodeEnabled()) { | |
201 const char* I965DrvVideoPath = NULL; | |
202 | |
203 if (IsArchitectureX86_64()) { | |
204 I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so"; | |
205 } else if (IsArchitectureI386()) { | |
206 I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so"; | |
207 } | |
208 | |
209 dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
210 dlopen("libva.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
211 dlopen("libva-x11.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
212 } | |
213 } | |
214 | |
215 return true; | |
216 } | |
217 | |
188 class GpuBrokerProcessPolicy : public GpuProcessPolicy { | 218 class GpuBrokerProcessPolicy : public GpuProcessPolicy { |
189 public: | 219 public: |
190 GpuBrokerProcessPolicy() : GpuProcessPolicy(NULL) {} | 220 GpuBrokerProcessPolicy() {} |
191 virtual ~GpuBrokerProcessPolicy() {} | 221 virtual ~GpuBrokerProcessPolicy() {} |
192 | 222 |
193 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 223 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
194 int system_call_number) const OVERRIDE; | 224 int system_call_number) const OVERRIDE; |
195 | 225 |
196 private: | 226 private: |
197 DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); | 227 DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); |
198 }; | 228 }; |
199 | 229 |
200 // x86_64/i386. | 230 // x86_64/i386 or desktop ARM. |
201 // A GPU broker policy is the same as a GPU policy with open and | 231 // A GPU broker policy is the same as a GPU policy with open and |
202 // openat allowed. | 232 // openat allowed. |
203 ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 233 ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
204 int sysno) const { | 234 int sysno) const { |
205 switch (sysno) { | 235 switch (sysno) { |
206 case __NR_access: | 236 case __NR_access: |
207 case __NR_open: | 237 case __NR_open: |
208 case __NR_openat: | 238 case __NR_openat: |
209 return ErrorCode(ErrorCode::ERR_ALLOWED); | 239 return ErrorCode(ErrorCode::ERR_ALLOWED); |
210 default: | 240 default: |
211 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 241 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
212 } | 242 } |
213 } | 243 } |
214 | 244 |
215 class ArmGpuProcessPolicy : public GpuProcessPolicy { | 245 // This policy is for Chrome OS ARM. |
246 class CrosArmGpuProcessPolicy : public GpuProcessPolicy { | |
216 public: | 247 public: |
217 explicit ArmGpuProcessPolicy(void* broker_process, bool allow_shmat) | 248 explicit CrosArmGpuProcessPolicy(bool allow_shmat) |
218 : GpuProcessPolicy(broker_process), allow_shmat_(allow_shmat) {} | 249 : allow_shmat_(allow_shmat) {} |
219 virtual ~ArmGpuProcessPolicy() {} | 250 virtual ~CrosArmGpuProcessPolicy() {} |
220 | 251 |
221 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 252 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
222 int system_call_number) const OVERRIDE; | 253 int system_call_number) const OVERRIDE; |
254 virtual bool PreSandboxHook() OVERRIDE; | |
223 | 255 |
224 private: | 256 private: |
225 const bool allow_shmat_; // Allow shmat(2). | 257 const bool allow_shmat_; // Allow shmat(2). |
226 DISALLOW_COPY_AND_ASSIGN(ArmGpuProcessPolicy); | 258 DISALLOW_COPY_AND_ASSIGN(CrosArmGpuProcessPolicy); |
227 }; | 259 }; |
228 | 260 |
229 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy. | 261 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy. |
230 ErrorCode ArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 262 ErrorCode CrosArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
231 int sysno) const { | 263 int sysno) const { |
232 #if defined(__arm__) | 264 #if defined(__arm__) |
233 if (allow_shmat_ && sysno == __NR_shmat) | 265 if (allow_shmat_ && sysno == __NR_shmat) |
234 return ErrorCode(ErrorCode::ERR_ALLOWED); | 266 return ErrorCode(ErrorCode::ERR_ALLOWED); |
235 #endif // defined(__arm__) | 267 #endif // defined(__arm__) |
236 | 268 |
237 switch (sysno) { | 269 switch (sysno) { |
238 #if defined(__arm__) | 270 #if defined(__arm__) |
239 // ARM GPU sandbox is started earlier so we need to allow networking | 271 // ARM GPU sandbox is started earlier so we need to allow networking |
240 // in the sandbox. | 272 // in the sandbox. |
241 case __NR_connect: | 273 case __NR_connect: |
(...skipping 12 matching lines...) Expand all Loading... | |
254 #endif // defined(__arm__) | 286 #endif // defined(__arm__) |
255 default: | 287 default: |
256 if (SyscallSets::IsAdvancedScheduler(sysno)) | 288 if (SyscallSets::IsAdvancedScheduler(sysno)) |
257 return ErrorCode(ErrorCode::ERR_ALLOWED); | 289 return ErrorCode(ErrorCode::ERR_ALLOWED); |
258 | 290 |
259 // Default to the generic GPU policy. | 291 // Default to the generic GPU policy. |
260 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 292 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
261 } | 293 } |
262 } | 294 } |
263 | 295 |
264 class ArmGpuBrokerProcessPolicy : public ArmGpuProcessPolicy { | 296 bool CrosArmGpuProcessPolicy::PreSandboxHook() { |
297 DCHECK(IsChromeOS() && IsArchitectureArm()); | |
298 // Create a new broker process. | |
299 BrokerProcess* broker_process_temp = NULL; | |
300 DCHECK(!broker_process()); | |
301 | |
302 std::vector<std::string> read_whitelist_extra; | |
303 std::vector<std::string> write_whitelist_extra; | |
304 // Add arm specific files to whitelist in the broker. | |
Jorge Lucangeli Obes
2013/12/12 21:37:21
ARM-specific
jln (very slow on Chromium)
2013/12/12 22:15:14
Done.
| |
305 | |
306 AddArmGpuWhitelist(&read_whitelist_extra, &write_whitelist_extra); | |
307 InitGpuBrokerProcess(EnableArmGpuBrokerPolicyCallback, | |
308 true /* for ChromeOS ARM */, | |
309 read_whitelist_extra, | |
310 write_whitelist_extra, | |
311 &broker_process_temp); | |
312 set_broker_process(broker_process_temp); | |
313 | |
314 // Preload the Mali library. | |
315 dlopen("/usr/lib/libmali.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
316 | |
317 // Preload the Tegra libraries. | |
318 dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
319 dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
320 dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
321 dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
322 dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
323 dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
324 dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
325 dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
326 | |
327 return true; | |
328 } | |
329 | |
330 class CrosArmGpuBrokerProcessPolicy : public CrosArmGpuProcessPolicy { | |
265 public: | 331 public: |
266 ArmGpuBrokerProcessPolicy() : ArmGpuProcessPolicy(NULL, false) {} | 332 CrosArmGpuBrokerProcessPolicy() : CrosArmGpuProcessPolicy(false) {} |
267 virtual ~ArmGpuBrokerProcessPolicy() {} | 333 virtual ~CrosArmGpuBrokerProcessPolicy() {} |
268 | 334 |
269 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | 335 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
270 int system_call_number) const OVERRIDE; | 336 int system_call_number) const OVERRIDE; |
271 | 337 |
272 private: | 338 private: |
273 DISALLOW_COPY_AND_ASSIGN(ArmGpuBrokerProcessPolicy); | 339 DISALLOW_COPY_AND_ASSIGN(CrosArmGpuBrokerProcessPolicy); |
274 }; | 340 }; |
275 | 341 |
276 // A GPU broker policy is the same as a GPU policy with open and | 342 // A GPU broker policy is the same as a GPU policy with open and |
277 // openat allowed. | 343 // openat allowed. |
278 ErrorCode ArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | 344 ErrorCode CrosArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
279 int sysno) const { | 345 int sysno) const { |
280 switch (sysno) { | 346 switch (sysno) { |
281 case __NR_access: | 347 case __NR_access: |
282 case __NR_open: | 348 case __NR_open: |
283 case __NR_openat: | 349 case __NR_openat: |
284 return ErrorCode(ErrorCode::ERR_ALLOWED); | 350 return ErrorCode(ErrorCode::ERR_ALLOWED); |
285 default: | 351 default: |
286 return ArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 352 return CrosArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
287 } | |
288 } | |
289 | |
290 // Policy for renderer and worker processes. | |
291 // TODO(jln): move to renderer/ | |
292 | |
293 class RendererOrWorkerProcessPolicy : public SandboxBPFBasePolicy { | |
294 public: | |
295 RendererOrWorkerProcessPolicy() {} | |
296 virtual ~RendererOrWorkerProcessPolicy() {} | |
297 | |
298 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | |
299 int system_call_number) const OVERRIDE; | |
300 | |
301 private: | |
302 DISALLOW_COPY_AND_ASSIGN(RendererOrWorkerProcessPolicy); | |
303 }; | |
304 | |
305 ErrorCode RendererOrWorkerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
306 int sysno) const { | |
307 switch (sysno) { | |
308 case __NR_clone: | |
309 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); | |
310 case __NR_ioctl: | |
311 return sandbox::RestrictIoctl(sandbox); | |
312 case __NR_prctl: | |
313 return sandbox::RestrictPrctl(sandbox); | |
314 // Allow the system calls below. | |
315 case __NR_fdatasync: | |
316 case __NR_fsync: | |
317 case __NR_getpriority: | |
318 #if defined(__i386__) || defined(__x86_64__) | |
319 case __NR_getrlimit: | |
320 #endif | |
321 #if defined(__i386__) || defined(__arm__) | |
322 case __NR_ugetrlimit: | |
323 #endif | |
324 case __NR_mremap: // See crbug.com/149834. | |
325 case __NR_pread64: | |
326 case __NR_pwrite64: | |
327 case __NR_sched_getaffinity: | |
328 case __NR_sched_get_priority_max: | |
329 case __NR_sched_get_priority_min: | |
330 case __NR_sched_getparam: | |
331 case __NR_sched_getscheduler: | |
332 case __NR_sched_setscheduler: | |
333 case __NR_setpriority: | |
334 case __NR_sysinfo: | |
335 case __NR_times: | |
336 case __NR_uname: | |
337 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
338 case __NR_prlimit64: | |
339 return ErrorCode(EPERM); // See crbug.com/160157. | |
340 default: | |
341 if (IsUsingToolKitGtk()) { | |
342 #if defined(__x86_64__) || defined(__arm__) | |
343 if (SyscallSets::IsSystemVSharedMemory(sysno)) | |
344 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
345 #endif | |
346 #if defined(__i386__) | |
347 if (SyscallSets::IsSystemVIpc(sysno)) | |
348 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
349 #endif | |
350 } | |
351 | |
352 // Default on the content baseline policy. | |
353 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); | |
354 } | |
355 } | |
356 | |
357 // Policy for PPAPI plugins. | |
358 // TODO(jln): move to ppapi_plugin/. | |
359 class FlashProcessPolicy : public SandboxBPFBasePolicy { | |
360 public: | |
361 FlashProcessPolicy() {} | |
362 virtual ~FlashProcessPolicy() {} | |
363 | |
364 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | |
365 int system_call_number) const OVERRIDE; | |
366 | |
367 private: | |
368 DISALLOW_COPY_AND_ASSIGN(FlashProcessPolicy); | |
369 }; | |
370 | |
371 ErrorCode FlashProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
372 int sysno) const { | |
373 switch (sysno) { | |
374 case __NR_clone: | |
375 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); | |
376 case __NR_pread64: | |
377 case __NR_pwrite64: | |
378 case __NR_sched_get_priority_max: | |
379 case __NR_sched_get_priority_min: | |
380 case __NR_sched_getaffinity: | |
381 case __NR_sched_getparam: | |
382 case __NR_sched_getscheduler: | |
383 case __NR_sched_setscheduler: | |
384 case __NR_times: | |
385 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
386 case __NR_ioctl: | |
387 return ErrorCode(ENOTTY); // Flash Access. | |
388 default: | |
389 if (IsUsingToolKitGtk()) { | |
390 #if defined(__x86_64__) || defined(__arm__) | |
391 if (SyscallSets::IsSystemVSharedMemory(sysno)) | |
392 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
393 #endif | |
394 #if defined(__i386__) | |
395 if (SyscallSets::IsSystemVIpc(sysno)) | |
396 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
397 #endif | |
398 } | |
399 | |
400 // Default on the baseline policy. | |
401 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); | |
402 } | |
403 } | |
404 | |
405 class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy { | |
406 public: | |
407 BlacklistDebugAndNumaPolicy() {} | |
408 virtual ~BlacklistDebugAndNumaPolicy() {} | |
409 | |
410 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | |
411 int system_call_number) const OVERRIDE; | |
412 | |
413 private: | |
414 DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy); | |
415 }; | |
416 | |
417 ErrorCode BlacklistDebugAndNumaPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
418 int sysno) const { | |
419 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | |
420 // TODO(jln) we should not have to do that in a trivial policy. | |
421 return ErrorCode(ENOSYS); | |
422 } | |
423 if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno)) | |
424 return sandbox->Trap(sandbox::CrashSIGSYS_Handler, NULL); | |
425 | |
426 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
427 } | |
428 | |
429 class AllowAllPolicy : public SandboxBPFBasePolicy { | |
430 public: | |
431 AllowAllPolicy() {} | |
432 virtual ~AllowAllPolicy() {} | |
433 | |
434 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, | |
435 int system_call_number) const OVERRIDE; | |
436 | |
437 private: | |
438 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | |
439 }; | |
440 | |
441 // Allow all syscalls. | |
442 // This will still deny x32 or IA32 calls in 64 bits mode or | |
443 // 64 bits system calls in compatibility mode. | |
444 ErrorCode AllowAllPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { | |
445 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | |
446 // TODO(jln) we should not have to do that in a trivial policy. | |
447 return ErrorCode(ENOSYS); | |
448 } else { | |
449 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
450 } | |
451 } | |
452 | |
453 // If a BPF policy is engaged for |process_type|, run a few sanity checks. | |
454 void RunSandboxSanityChecks(const std::string& process_type) { | |
455 if (process_type == switches::kRendererProcess || | |
456 process_type == switches::kWorkerProcess || | |
457 process_type == switches::kGpuProcess || | |
458 process_type == switches::kPpapiPluginProcess) { | |
459 int syscall_ret; | |
460 errno = 0; | |
461 | |
462 // Without the sandbox, this would EBADF. | |
463 syscall_ret = fchmod(-1, 07777); | |
464 CHECK_EQ(-1, syscall_ret); | |
465 CHECK_EQ(EPERM, errno); | |
466 | |
467 // Run most of the sanity checks only in DEBUG mode to avoid a perf. | |
468 // impact. | |
469 #if !defined(NDEBUG) | |
470 // open() must be restricted. | |
471 syscall_ret = open("/etc/passwd", O_RDONLY); | |
472 CHECK_EQ(-1, syscall_ret); | |
473 CHECK_EQ(SandboxBPFBasePolicy::GetFSDeniedErrno(), errno); | |
474 | |
475 // We should never allow the creation of netlink sockets. | |
476 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); | |
477 CHECK_EQ(-1, syscall_ret); | |
478 CHECK_EQ(EPERM, errno); | |
479 #endif // !defined(NDEBUG) | |
480 } | 353 } |
481 } | 354 } |
482 | 355 |
483 bool EnableGpuBrokerPolicyCallback() { | 356 bool EnableGpuBrokerPolicyCallback() { |
484 StartSandboxWithPolicy(new GpuBrokerProcessPolicy); | 357 return SandboxSeccompBPF::StartSandboxWithExternalPolicy( |
485 return true; | 358 scoped_ptr<sandbox::SandboxBPFPolicy>(new GpuBrokerProcessPolicy)); |
486 } | 359 } |
487 | 360 |
488 bool EnableArmGpuBrokerPolicyCallback() { | 361 bool EnableArmGpuBrokerPolicyCallback() { |
489 StartSandboxWithPolicy(new ArmGpuBrokerProcessPolicy); | 362 return SandboxSeccompBPF::StartSandboxWithExternalPolicy( |
490 return true; | 363 scoped_ptr<sandbox::SandboxBPFPolicy>(new CrosArmGpuBrokerProcessPolicy)); |
491 } | 364 } |
492 | 365 |
493 // Files needed by the ARM GPU userspace. | |
494 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2"; | |
495 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1"; | |
496 | |
497 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist, | 366 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist, |
498 std::vector<std::string>* write_whitelist) { | 367 std::vector<std::string>* write_whitelist) { |
499 // Device file needed by the ARM GPU userspace. | 368 // Device file needed by the ARM GPU userspace. |
500 static const char kMali0Path[] = "/dev/mali0"; | 369 static const char kMali0Path[] = "/dev/mali0"; |
501 | 370 |
502 // Devices needed for video decode acceleration on ARM. | 371 // Devices needed for video decode acceleration on ARM. |
503 static const char kDevMfcDecPath[] = "/dev/mfc-dec"; | 372 static const char kDevMfcDecPath[] = "/dev/mfc-dec"; |
504 static const char kDevGsc1Path[] = "/dev/gsc1"; | 373 static const char kDevGsc1Path[] = "/dev/gsc1"; |
505 | 374 |
506 // Devices needed for video encode acceleration on ARM. | 375 // Devices needed for video encode acceleration on ARM. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 write_whitelist->push_back(kDevTegraSemaPath); | 414 write_whitelist->push_back(kDevTegraSemaPath); |
546 } | 415 } |
547 | 416 |
548 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, | 417 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist, |
549 std::vector<std::string>* write_whitelist) { | 418 std::vector<std::string>* write_whitelist) { |
550 // On ARM we're enabling the sandbox before the X connection is made, | 419 // On ARM we're enabling the sandbox before the X connection is made, |
551 // so we need to allow access to |.Xauthority|. | 420 // so we need to allow access to |.Xauthority|. |
552 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority"; | 421 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority"; |
553 static const char kLdSoCache[] = "/etc/ld.so.cache"; | 422 static const char kLdSoCache[] = "/etc/ld.so.cache"; |
554 | 423 |
424 // Files needed by the ARM GPU userspace. | |
425 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2"; | |
426 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1"; | |
427 | |
555 read_whitelist->push_back(kXAuthorityPath); | 428 read_whitelist->push_back(kXAuthorityPath); |
556 read_whitelist->push_back(kLdSoCache); | 429 read_whitelist->push_back(kLdSoCache); |
557 read_whitelist->push_back(kLibGlesPath); | 430 read_whitelist->push_back(kLibGlesPath); |
558 read_whitelist->push_back(kLibEglPath); | 431 read_whitelist->push_back(kLibEglPath); |
559 | 432 |
560 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist); | 433 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist); |
561 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist); | 434 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist); |
562 } | 435 } |
563 | 436 |
564 // Start a broker process to handle open() inside the sandbox. | 437 // Start a broker process to handle open() inside the sandbox. |
565 void InitGpuBrokerProcess(bool for_chromeos_arm, | 438 // |broker_sandboxer_callback| is a callback that will enable a suitable |
439 // sandbox for the broker process itself. | |
440 // |read_whitelist_extra| and |write_whitelist_extra| are lists of file | |
441 // names that should be whitelisted by the broker process, in addition to | |
442 // the basic ones. | |
443 void InitGpuBrokerProcess(bool (*broker_sandboxer_callback)(void), | |
444 bool for_chromeos_arm, | |
445 const std::vector<std::string>& read_whitelist_extra, | |
446 const std::vector<std::string>& write_whitelist_extra, | |
566 BrokerProcess** broker_process) { | 447 BrokerProcess** broker_process) { |
567 static const char kDriRcPath[] = "/etc/drirc"; | 448 static const char kDriRcPath[] = "/etc/drirc"; |
568 static const char kDriCard0Path[] = "/dev/dri/card0"; | 449 static const char kDriCard0Path[] = "/dev/dri/card0"; |
569 | 450 |
570 CHECK(broker_process); | 451 CHECK(broker_process); |
571 CHECK(*broker_process == NULL); | 452 CHECK(*broker_process == NULL); |
572 | 453 |
573 bool (*sandbox_callback)(void) = NULL; | |
574 | |
575 // All GPU process policies need these files brokered out. | 454 // All GPU process policies need these files brokered out. |
576 std::vector<std::string> read_whitelist; | 455 std::vector<std::string> read_whitelist; |
577 read_whitelist.push_back(kDriCard0Path); | 456 read_whitelist.push_back(kDriCard0Path); |
578 read_whitelist.push_back(kDriRcPath); | 457 read_whitelist.push_back(kDriRcPath); |
458 // Add eventual extra files from read_whitelist_extra. | |
459 read_whitelist.insert(read_whitelist.end(), | |
460 read_whitelist_extra.begin(), | |
461 read_whitelist_extra.end()); | |
579 | 462 |
580 std::vector<std::string> write_whitelist; | 463 std::vector<std::string> write_whitelist; |
581 write_whitelist.push_back(kDriCard0Path); | 464 write_whitelist.push_back(kDriCard0Path); |
582 | 465 // Add eventual extra files from write_whitelist_extra. |
583 if (for_chromeos_arm) { | 466 write_whitelist.insert(write_whitelist.end(), |
584 // We shouldn't be using this policy on non-ARM architectures. | 467 write_whitelist_extra.begin(), |
585 DCHECK(IsArchitectureArm()); | 468 write_whitelist_extra.end()); |
586 AddArmGpuWhitelist(&read_whitelist, &write_whitelist); | |
587 sandbox_callback = EnableArmGpuBrokerPolicyCallback; | |
588 } else { | |
589 sandbox_callback = EnableGpuBrokerPolicyCallback; | |
590 } | |
591 | 469 |
592 *broker_process = new BrokerProcess(SandboxBPFBasePolicy::GetFSDeniedErrno(), | 470 *broker_process = new BrokerProcess(SandboxBPFBasePolicy::GetFSDeniedErrno(), |
593 read_whitelist, | 471 read_whitelist, |
594 write_whitelist); | 472 write_whitelist); |
595 // Initialize the broker process and give it a sandbox callback. | 473 // Initialize the broker process and give it a sandbox callback. |
596 CHECK((*broker_process)->Init(sandbox_callback)); | 474 CHECK((*broker_process)->Init(broker_sandboxer_callback)); |
597 } | |
598 | |
599 // Warms up/preloads resources needed by the policies. | |
600 // Eventually start a broker process and return it in broker_process. | |
601 void WarmupPolicy(bool chromeos_arm_gpu, | |
602 BrokerProcess** broker_process) { | |
603 if (!chromeos_arm_gpu) { | |
604 // Create a new broker process. | |
605 InitGpuBrokerProcess(false /* not for ChromeOS ARM */, broker_process); | |
606 | |
607 if (IsArchitectureX86_64() || IsArchitectureI386()) { | |
608 // Accelerated video decode dlopen()'s some shared objects | |
609 // inside the sandbox, so preload them now. | |
610 if (IsAcceleratedVideoDecodeEnabled()) { | |
611 const char* I965DrvVideoPath = NULL; | |
612 | |
613 if (IsArchitectureX86_64()) { | |
614 I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so"; | |
615 } else if (IsArchitectureI386()) { | |
616 I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so"; | |
617 } | |
618 | |
619 dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
620 dlopen("libva.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
621 dlopen("libva-x11.so.1", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
622 } | |
623 } | |
624 } else { | |
625 // ChromeOS ARM GPU policy. | |
626 // Create a new broker process. | |
627 InitGpuBrokerProcess(true /* for ChromeOS ARM */, broker_process); | |
628 | |
629 // Preload the Mali library. | |
630 dlopen("/usr/lib/libmali.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
631 | |
632 // Preload the Tegra libraries. | |
633 dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
634 dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
635 dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
636 dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
637 dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
638 dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
639 dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
640 dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); | |
641 } | |
642 } | |
643 | |
644 void StartGpuProcessSandbox(const CommandLine& command_line, | |
645 const std::string& process_type) { | |
646 bool chromeos_arm_gpu = false; | |
647 bool allow_sysv_shm = false; | |
648 | |
649 if (process_type == switches::kGpuProcess) { | |
650 // On Chrome OS ARM, we need a specific GPU process policy. | |
651 if (IsChromeOS() && IsArchitectureArm()) { | |
652 chromeos_arm_gpu = true; | |
653 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { | |
654 allow_sysv_shm = true; | |
655 } | |
656 } | |
657 } | |
658 | |
659 // This should never be destroyed, as after the sandbox is started it is | |
660 // vital to the process. Ownership is transfered to the policies and then to | |
661 // the BPF sandbox which will keep it around to service SIGSYS traps from the | |
662 // kernel. | |
663 BrokerProcess* broker_process = NULL; | |
664 // Warm up resources needed by the policy we're about to enable and | |
665 // eventually start a broker process. | |
666 WarmupPolicy(chromeos_arm_gpu, &broker_process); | |
667 | |
668 scoped_ptr<SandboxBPFBasePolicy> gpu_policy; | |
669 if (chromeos_arm_gpu) { | |
670 gpu_policy.reset(new ArmGpuProcessPolicy(broker_process, allow_sysv_shm)); | |
671 } else { | |
672 gpu_policy.reset(new GpuProcessPolicy(broker_process)); | |
673 } | |
674 StartSandboxWithPolicy(gpu_policy.release()); | |
675 } | |
676 | |
677 // This function takes ownership of |policy|. | |
678 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy) { | |
679 // Starting the sandbox is a one-way operation. The kernel doesn't allow | |
680 // us to unload a sandbox policy after it has been started. Nonetheless, | |
681 // in order to make the use of the "Sandbox" object easier, we allow for | |
682 // the object to be destroyed after the sandbox has been started. Note that | |
683 // doing so does not stop the sandbox. | |
684 SandboxBPF sandbox; | |
685 sandbox.SetSandboxPolicy(policy); | |
686 sandbox.StartSandbox(); | |
687 } | |
688 | |
689 void StartNonGpuSandbox(const std::string& process_type) { | |
690 scoped_ptr<SandboxBPFBasePolicy> policy; | |
691 | |
692 if (process_type == switches::kRendererProcess || | |
693 process_type == switches::kWorkerProcess) { | |
694 policy.reset(new RendererOrWorkerProcessPolicy); | |
695 } else if (process_type == switches::kPpapiPluginProcess) { | |
696 policy.reset(new FlashProcessPolicy); | |
697 } else if (process_type == switches::kUtilityProcess) { | |
698 policy.reset(new BlacklistDebugAndNumaPolicy); | |
699 } else { | |
700 NOTREACHED(); | |
701 policy.reset(new AllowAllPolicy); | |
702 } | |
703 | |
704 StartSandboxWithPolicy(policy.release()); | |
705 } | |
706 | |
707 // Initialize the seccomp-bpf sandbox. | |
708 bool StartBPFSandbox(const CommandLine& command_line, | |
709 const std::string& process_type) { | |
710 | |
711 if (process_type == switches::kGpuProcess) { | |
712 StartGpuProcessSandbox(command_line, process_type); | |
713 } else { | |
714 StartNonGpuSandbox(process_type); | |
715 } | |
716 | |
717 RunSandboxSanityChecks(process_type); | |
718 return true; | |
719 } | 475 } |
720 | 476 |
721 } // namespace | 477 } // namespace |
722 | 478 |
723 #endif // SECCOMP_BPF_SANDBOX | 479 scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { |
480 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
481 bool allow_sysv_shm = false; | |
482 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { | |
483 DCHECK(IsArchitectureArm()); | |
484 allow_sysv_shm = true; | |
485 } | |
724 | 486 |
725 // Is seccomp BPF globally enabled? | 487 if (IsChromeOS() && IsArchitectureArm()) { |
726 bool SandboxSeccompBPF::IsSeccompBPFDesired() { | 488 return scoped_ptr<SandboxBPFBasePolicy>( |
727 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 489 new CrosArmGpuProcessPolicy(allow_sysv_shm)); |
728 if (!command_line.HasSwitch(switches::kNoSandbox) && | |
729 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { | |
730 return true; | |
731 } else { | 490 } else { |
732 return false; | 491 return scoped_ptr<SandboxBPFBasePolicy>(new GpuProcessPolicy); |
733 } | 492 } |
734 } | 493 } |
735 | 494 |
736 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( | |
737 const std::string& process_type) { | |
738 #if defined(SECCOMP_BPF_SANDBOX) | |
739 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
740 if (process_type == switches::kGpuProcess) | |
741 return !command_line.HasSwitch(switches::kDisableGpuSandbox); | |
742 | |
743 return true; | |
744 #endif // SECCOMP_BPF_SANDBOX | |
745 return false; | |
746 } | |
747 | |
748 bool SandboxSeccompBPF::SupportsSandbox() { | |
749 #if defined(SECCOMP_BPF_SANDBOX) | |
750 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton | |
751 // here. | |
752 SandboxBPF::SandboxStatus bpf_sandbox_status = | |
753 SandboxBPF::SupportsSeccompSandbox(-1); | |
754 // Kernel support is what we are interested in here. Other status | |
755 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. | |
756 // We make this a negative check, since if there is a bug, we would rather | |
757 // "fail closed" (expect a sandbox to be available and try to start it). | |
758 if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { | |
759 return true; | |
760 } | |
761 #endif | |
762 return false; | |
763 } | |
764 | |
765 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { | |
766 #if defined(SECCOMP_BPF_SANDBOX) | |
767 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
768 | |
769 if (IsSeccompBPFDesired() && // Global switches policy. | |
770 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. | |
771 SupportsSandbox()) { | |
772 // If the kernel supports the sandbox, and if the command line says we | |
773 // should enable it, enable it or die. | |
774 bool started_sandbox = StartBPFSandbox(command_line, process_type); | |
775 CHECK(started_sandbox); | |
776 return true; | |
777 } | |
778 #endif | |
779 return false; | |
780 } | |
781 | |
782 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( | |
783 scoped_ptr<sandbox::SandboxBPFPolicy> policy) { | |
784 #if defined(SECCOMP_BPF_SANDBOX) | |
785 if (IsSeccompBPFDesired() && SupportsSandbox()) { | |
786 CHECK(policy); | |
787 StartSandboxWithPolicy(policy.release()); | |
788 return true; | |
789 } | |
790 #endif // defined(SECCOMP_BPF_SANDBOX) | |
791 return false; | |
792 } | |
793 | |
794 scoped_ptr<sandbox::SandboxBPFPolicy> | |
795 SandboxSeccompBPF::GetBaselinePolicy() { | |
796 #if defined(SECCOMP_BPF_SANDBOX) | |
797 return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); | |
798 #else | |
799 return scoped_ptr<sandbox::SandboxBPFPolicy>(); | |
800 #endif // defined(SECCOMP_BPF_SANDBOX) | |
801 } | |
802 | |
803 } // namespace content | 495 } // namespace content |
OLD | NEW |