OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <asm/unistd.h> |
6 #include <dlfcn.h> | 6 #include <dlfcn.h> |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <linux/net.h> | 9 #include <linux/net.h> |
10 #include <signal.h> | 10 #include <signal.h> |
(...skipping 28 matching lines...) Expand all Loading... | |
39 #include "base/posix/eintr_wrapper.h" | 39 #include "base/posix/eintr_wrapper.h" |
40 #include "content/common/sandbox_bpf_base_policy_linux.h" | 40 #include "content/common/sandbox_bpf_base_policy_linux.h" |
41 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" | 41 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" |
42 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" | 42 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" |
43 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | 43 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
44 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" | 44 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" |
45 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 45 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
46 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 46 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
47 #include "sandbox/linux/services/linux_syscalls.h" | 47 #include "sandbox/linux/services/linux_syscalls.h" |
48 | 48 |
49 using playground2::arch_seccomp_data; | 49 using sandbox::BaselinePolicy; |
50 using playground2::ErrorCode; | |
51 using playground2::Sandbox; | |
52 using sandbox::BrokerProcess; | 50 using sandbox::BrokerProcess; |
53 using sandbox::BaselinePolicy; | 51 using sandbox::ErrorCode; |
52 using sandbox::SandboxBPF; | |
54 using sandbox::SyscallSets; | 53 using sandbox::SyscallSets; |
54 using sandbox::arch_seccomp_data; | |
Robert Sesek
2013/12/10 21:15:26
nit: alphabetize
jln (very slow on Chromium)
2013/12/10 21:36:38
I'll keep lowercase -> last. It's what "sort" does
| |
55 | 55 |
56 namespace content { | 56 namespace content { |
57 | 57 |
58 namespace { | 58 namespace { |
59 | 59 |
60 void StartSandboxWithPolicy(playground2::SandboxBpfPolicy* policy); | 60 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); |
61 | 61 |
62 inline bool IsChromeOS() { | 62 inline bool IsChromeOS() { |
63 #if defined(OS_CHROMEOS) | 63 #if defined(OS_CHROMEOS) |
64 return true; | 64 return true; |
65 #else | 65 #else |
66 return false; | 66 return false; |
67 #endif | 67 #endif |
68 } | 68 } |
69 | 69 |
70 inline bool IsArchitectureX86_64() { | 70 inline bool IsArchitectureX86_64() { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 static_cast<int>(args.args[2])); | 134 static_cast<int>(args.args[2])); |
135 } else { | 135 } else { |
136 return -EPERM; | 136 return -EPERM; |
137 } | 137 } |
138 default: | 138 default: |
139 RAW_CHECK(false); | 139 RAW_CHECK(false); |
140 return -ENOSYS; | 140 return -ENOSYS; |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 class GpuProcessPolicy : public SandboxBpfBasePolicy { | 144 class GpuProcessPolicy : public SandboxBPFBasePolicy { |
145 public: | 145 public: |
146 explicit GpuProcessPolicy(void* broker_process) | 146 explicit GpuProcessPolicy(void* broker_process) |
147 : broker_process_(broker_process) {} | 147 : broker_process_(broker_process) {} |
148 virtual ~GpuProcessPolicy() {} | 148 virtual ~GpuProcessPolicy() {} |
149 | 149 |
150 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 150 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
151 int system_call_number) const OVERRIDE; | 151 int system_call_number) const OVERRIDE; |
152 | 152 |
153 private: | 153 private: |
154 const void* broker_process_; // Non-owning pointer. | 154 const void* broker_process_; // Non-owning pointer. |
155 DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); | 155 DISALLOW_COPY_AND_ASSIGN(GpuProcessPolicy); |
156 }; | 156 }; |
157 | 157 |
158 // Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy. | 158 // Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy. |
159 ErrorCode GpuProcessPolicy::EvaluateSyscall(Sandbox* sandbox, int sysno) const { | 159 ErrorCode GpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
160 int sysno) const { | |
160 switch (sysno) { | 161 switch (sysno) { |
161 case __NR_ioctl: | 162 case __NR_ioctl: |
162 #if defined(__i386__) || defined(__x86_64__) | 163 #if defined(__i386__) || defined(__x86_64__) |
163 // The Nvidia driver uses flags not in the baseline policy | 164 // The Nvidia driver uses flags not in the baseline policy |
164 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) | 165 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT) |
165 case __NR_mmap: | 166 case __NR_mmap: |
166 #endif | 167 #endif |
167 // We also hit this on the linux_chromeos bot but don't yet know what | 168 // We also hit this on the linux_chromeos bot but don't yet know what |
168 // weird flags were involved. | 169 // weird flags were involved. |
169 case __NR_mprotect: | 170 case __NR_mprotect: |
170 case __NR_sched_getaffinity: | 171 case __NR_sched_getaffinity: |
171 case __NR_sched_setaffinity: | 172 case __NR_sched_setaffinity: |
172 case __NR_setpriority: | 173 case __NR_setpriority: |
173 return ErrorCode(ErrorCode::ERR_ALLOWED); | 174 return ErrorCode(ErrorCode::ERR_ALLOWED); |
174 case __NR_access: | 175 case __NR_access: |
175 case __NR_open: | 176 case __NR_open: |
176 case __NR_openat: | 177 case __NR_openat: |
177 return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); | 178 return sandbox->Trap(GpuSIGSYS_Handler, broker_process_); |
178 default: | 179 default: |
179 if (SyscallSets::IsEventFd(sysno)) | 180 if (SyscallSets::IsEventFd(sysno)) |
180 return ErrorCode(ErrorCode::ERR_ALLOWED); | 181 return ErrorCode(ErrorCode::ERR_ALLOWED); |
181 | 182 |
182 // Default on the baseline policy. | 183 // Default on the baseline policy. |
183 return SandboxBpfBasePolicy::EvaluateSyscall(sandbox, sysno); | 184 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); |
184 } | 185 } |
185 } | 186 } |
186 | 187 |
187 class GpuBrokerProcessPolicy : public GpuProcessPolicy { | 188 class GpuBrokerProcessPolicy : public GpuProcessPolicy { |
188 public: | 189 public: |
189 GpuBrokerProcessPolicy() : GpuProcessPolicy(NULL) {} | 190 GpuBrokerProcessPolicy() : GpuProcessPolicy(NULL) {} |
190 virtual ~GpuBrokerProcessPolicy() {} | 191 virtual ~GpuBrokerProcessPolicy() {} |
191 | 192 |
192 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 193 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
193 int system_call_number) const OVERRIDE; | 194 int system_call_number) const OVERRIDE; |
194 | 195 |
195 private: | 196 private: |
196 DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); | 197 DISALLOW_COPY_AND_ASSIGN(GpuBrokerProcessPolicy); |
197 }; | 198 }; |
198 | 199 |
199 // x86_64/i386. | 200 // x86_64/i386. |
200 // A GPU broker policy is the same as a GPU policy with open and | 201 // A GPU broker policy is the same as a GPU policy with open and |
201 // openat allowed. | 202 // openat allowed. |
202 ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(Sandbox* sandbox, | 203 ErrorCode GpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
203 int sysno) const { | 204 int sysno) const { |
204 switch (sysno) { | 205 switch (sysno) { |
205 case __NR_access: | 206 case __NR_access: |
206 case __NR_open: | 207 case __NR_open: |
207 case __NR_openat: | 208 case __NR_openat: |
208 return ErrorCode(ErrorCode::ERR_ALLOWED); | 209 return ErrorCode(ErrorCode::ERR_ALLOWED); |
209 default: | 210 default: |
210 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 211 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
211 } | 212 } |
212 } | 213 } |
213 | 214 |
214 class ArmGpuProcessPolicy : public GpuProcessPolicy { | 215 class ArmGpuProcessPolicy : public GpuProcessPolicy { |
215 public: | 216 public: |
216 explicit ArmGpuProcessPolicy(void* broker_process, bool allow_shmat) | 217 explicit ArmGpuProcessPolicy(void* broker_process, bool allow_shmat) |
217 : GpuProcessPolicy(broker_process), allow_shmat_(allow_shmat) {} | 218 : GpuProcessPolicy(broker_process), allow_shmat_(allow_shmat) {} |
218 virtual ~ArmGpuProcessPolicy() {} | 219 virtual ~ArmGpuProcessPolicy() {} |
219 | 220 |
220 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 221 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
221 int system_call_number) const OVERRIDE; | 222 int system_call_number) const OVERRIDE; |
222 | 223 |
223 private: | 224 private: |
224 const bool allow_shmat_; // Allow shmat(2). | 225 const bool allow_shmat_; // Allow shmat(2). |
225 DISALLOW_COPY_AND_ASSIGN(ArmGpuProcessPolicy); | 226 DISALLOW_COPY_AND_ASSIGN(ArmGpuProcessPolicy); |
226 }; | 227 }; |
227 | 228 |
228 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy. | 229 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy. |
229 ErrorCode ArmGpuProcessPolicy::EvaluateSyscall(Sandbox* sandbox, | 230 ErrorCode ArmGpuProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
230 int sysno) const { | 231 int sysno) const { |
231 #if defined(__arm__) | 232 #if defined(__arm__) |
232 if (allow_shmat_ && sysno == __NR_shmat) | 233 if (allow_shmat_ && sysno == __NR_shmat) |
233 return ErrorCode(ErrorCode::ERR_ALLOWED); | 234 return ErrorCode(ErrorCode::ERR_ALLOWED); |
234 #endif // defined(__arm__) | 235 #endif // defined(__arm__) |
235 | 236 |
236 switch (sysno) { | 237 switch (sysno) { |
237 #if defined(__arm__) | 238 #if defined(__arm__) |
238 // ARM GPU sandbox is started earlier so we need to allow networking | 239 // ARM GPU sandbox is started earlier so we need to allow networking |
239 // in the sandbox. | 240 // in the sandbox. |
(...skipping 18 matching lines...) Expand all Loading... | |
258 // Default to the generic GPU policy. | 259 // Default to the generic GPU policy. |
259 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 260 return GpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
260 } | 261 } |
261 } | 262 } |
262 | 263 |
263 class ArmGpuBrokerProcessPolicy : public ArmGpuProcessPolicy { | 264 class ArmGpuBrokerProcessPolicy : public ArmGpuProcessPolicy { |
264 public: | 265 public: |
265 ArmGpuBrokerProcessPolicy() : ArmGpuProcessPolicy(NULL, false) {} | 266 ArmGpuBrokerProcessPolicy() : ArmGpuProcessPolicy(NULL, false) {} |
266 virtual ~ArmGpuBrokerProcessPolicy() {} | 267 virtual ~ArmGpuBrokerProcessPolicy() {} |
267 | 268 |
268 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 269 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
269 int system_call_number) const OVERRIDE; | 270 int system_call_number) const OVERRIDE; |
270 | 271 |
271 private: | 272 private: |
272 DISALLOW_COPY_AND_ASSIGN(ArmGpuBrokerProcessPolicy); | 273 DISALLOW_COPY_AND_ASSIGN(ArmGpuBrokerProcessPolicy); |
273 }; | 274 }; |
274 | 275 |
275 // A GPU broker policy is the same as a GPU policy with open and | 276 // A GPU broker policy is the same as a GPU policy with open and |
276 // openat allowed. | 277 // openat allowed. |
277 ErrorCode ArmGpuBrokerProcessPolicy::EvaluateSyscall(Sandbox* sandbox, | 278 ErrorCode ArmGpuBrokerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
278 int sysno) const { | 279 int sysno) const { |
279 switch (sysno) { | 280 switch (sysno) { |
280 case __NR_access: | 281 case __NR_access: |
281 case __NR_open: | 282 case __NR_open: |
282 case __NR_openat: | 283 case __NR_openat: |
283 return ErrorCode(ErrorCode::ERR_ALLOWED); | 284 return ErrorCode(ErrorCode::ERR_ALLOWED); |
284 default: | 285 default: |
285 return ArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); | 286 return ArmGpuProcessPolicy::EvaluateSyscall(sandbox, sysno); |
286 } | 287 } |
287 } | 288 } |
288 | 289 |
289 // Policy for renderer and worker processes. | 290 // Policy for renderer and worker processes. |
290 // TODO(jln): move to renderer/ | 291 // TODO(jln): move to renderer/ |
291 | 292 |
292 class RendererOrWorkerProcessPolicy : public SandboxBpfBasePolicy { | 293 class RendererOrWorkerProcessPolicy : public SandboxBPFBasePolicy { |
293 public: | 294 public: |
294 RendererOrWorkerProcessPolicy() {} | 295 RendererOrWorkerProcessPolicy() {} |
295 virtual ~RendererOrWorkerProcessPolicy() {} | 296 virtual ~RendererOrWorkerProcessPolicy() {} |
296 | 297 |
297 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 298 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
298 int system_call_number) const OVERRIDE; | 299 int system_call_number) const OVERRIDE; |
299 | 300 |
300 private: | 301 private: |
301 DISALLOW_COPY_AND_ASSIGN(RendererOrWorkerProcessPolicy); | 302 DISALLOW_COPY_AND_ASSIGN(RendererOrWorkerProcessPolicy); |
302 }; | 303 }; |
303 | 304 |
304 ErrorCode RendererOrWorkerProcessPolicy::EvaluateSyscall(Sandbox* sandbox, | 305 ErrorCode RendererOrWorkerProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
305 int sysno) const { | 306 int sysno) const { |
306 switch (sysno) { | 307 switch (sysno) { |
307 case __NR_clone: | 308 case __NR_clone: |
308 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); | 309 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); |
309 case __NR_ioctl: | 310 case __NR_ioctl: |
310 return sandbox::RestrictIoctl(sandbox); | 311 return sandbox::RestrictIoctl(sandbox); |
311 case __NR_prctl: | 312 case __NR_prctl: |
312 return sandbox::RestrictPrctl(sandbox); | 313 return sandbox::RestrictPrctl(sandbox); |
313 // Allow the system calls below. | 314 // Allow the system calls below. |
314 case __NR_fdatasync: | 315 case __NR_fdatasync: |
(...skipping 27 matching lines...) Expand all Loading... | |
342 if (SyscallSets::IsSystemVSharedMemory(sysno)) | 343 if (SyscallSets::IsSystemVSharedMemory(sysno)) |
343 return ErrorCode(ErrorCode::ERR_ALLOWED); | 344 return ErrorCode(ErrorCode::ERR_ALLOWED); |
344 #endif | 345 #endif |
345 #if defined(__i386__) | 346 #if defined(__i386__) |
346 if (SyscallSets::IsSystemVIpc(sysno)) | 347 if (SyscallSets::IsSystemVIpc(sysno)) |
347 return ErrorCode(ErrorCode::ERR_ALLOWED); | 348 return ErrorCode(ErrorCode::ERR_ALLOWED); |
348 #endif | 349 #endif |
349 } | 350 } |
350 | 351 |
351 // Default on the content baseline policy. | 352 // Default on the content baseline policy. |
352 return SandboxBpfBasePolicy::EvaluateSyscall(sandbox, sysno); | 353 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); |
353 } | 354 } |
354 } | 355 } |
355 | 356 |
356 // Policy for PPAPI plugins. | 357 // Policy for PPAPI plugins. |
357 // TODO(jln): move to ppapi_plugin/. | 358 // TODO(jln): move to ppapi_plugin/. |
358 class FlashProcessPolicy : public SandboxBpfBasePolicy { | 359 class FlashProcessPolicy : public SandboxBPFBasePolicy { |
359 public: | 360 public: |
360 FlashProcessPolicy() {} | 361 FlashProcessPolicy() {} |
361 virtual ~FlashProcessPolicy() {} | 362 virtual ~FlashProcessPolicy() {} |
362 | 363 |
363 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 364 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
364 int system_call_number) const OVERRIDE; | 365 int system_call_number) const OVERRIDE; |
365 | 366 |
366 private: | 367 private: |
367 DISALLOW_COPY_AND_ASSIGN(FlashProcessPolicy); | 368 DISALLOW_COPY_AND_ASSIGN(FlashProcessPolicy); |
368 }; | 369 }; |
369 | 370 |
370 ErrorCode FlashProcessPolicy::EvaluateSyscall(Sandbox* sandbox, | 371 ErrorCode FlashProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
371 int sysno) const { | 372 int sysno) const { |
372 switch (sysno) { | 373 switch (sysno) { |
373 case __NR_clone: | 374 case __NR_clone: |
374 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); | 375 return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox); |
375 case __NR_pread64: | 376 case __NR_pread64: |
376 case __NR_pwrite64: | 377 case __NR_pwrite64: |
377 case __NR_sched_get_priority_max: | 378 case __NR_sched_get_priority_max: |
378 case __NR_sched_get_priority_min: | 379 case __NR_sched_get_priority_min: |
379 case __NR_sched_getaffinity: | 380 case __NR_sched_getaffinity: |
380 case __NR_sched_getparam: | 381 case __NR_sched_getparam: |
381 case __NR_sched_getscheduler: | 382 case __NR_sched_getscheduler: |
382 case __NR_sched_setscheduler: | 383 case __NR_sched_setscheduler: |
383 case __NR_times: | 384 case __NR_times: |
384 return ErrorCode(ErrorCode::ERR_ALLOWED); | 385 return ErrorCode(ErrorCode::ERR_ALLOWED); |
385 case __NR_ioctl: | 386 case __NR_ioctl: |
386 return ErrorCode(ENOTTY); // Flash Access. | 387 return ErrorCode(ENOTTY); // Flash Access. |
387 default: | 388 default: |
388 if (IsUsingToolKitGtk()) { | 389 if (IsUsingToolKitGtk()) { |
389 #if defined(__x86_64__) || defined(__arm__) | 390 #if defined(__x86_64__) || defined(__arm__) |
390 if (SyscallSets::IsSystemVSharedMemory(sysno)) | 391 if (SyscallSets::IsSystemVSharedMemory(sysno)) |
391 return ErrorCode(ErrorCode::ERR_ALLOWED); | 392 return ErrorCode(ErrorCode::ERR_ALLOWED); |
392 #endif | 393 #endif |
393 #if defined(__i386__) | 394 #if defined(__i386__) |
394 if (SyscallSets::IsSystemVIpc(sysno)) | 395 if (SyscallSets::IsSystemVIpc(sysno)) |
395 return ErrorCode(ErrorCode::ERR_ALLOWED); | 396 return ErrorCode(ErrorCode::ERR_ALLOWED); |
396 #endif | 397 #endif |
397 } | 398 } |
398 | 399 |
399 // Default on the baseline policy. | 400 // Default on the baseline policy. |
400 return SandboxBpfBasePolicy::EvaluateSyscall(sandbox, sysno); | 401 return SandboxBPFBasePolicy::EvaluateSyscall(sandbox, sysno); |
401 } | 402 } |
402 } | 403 } |
403 | 404 |
404 class BlacklistDebugAndNumaPolicy : public SandboxBpfBasePolicy { | 405 class BlacklistDebugAndNumaPolicy : public SandboxBPFBasePolicy { |
405 public: | 406 public: |
406 BlacklistDebugAndNumaPolicy() {} | 407 BlacklistDebugAndNumaPolicy() {} |
407 virtual ~BlacklistDebugAndNumaPolicy() {} | 408 virtual ~BlacklistDebugAndNumaPolicy() {} |
408 | 409 |
409 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 410 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
410 int system_call_number) const OVERRIDE; | 411 int system_call_number) const OVERRIDE; |
411 | 412 |
412 private: | 413 private: |
413 DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy); | 414 DISALLOW_COPY_AND_ASSIGN(BlacklistDebugAndNumaPolicy); |
414 }; | 415 }; |
415 | 416 |
416 ErrorCode BlacklistDebugAndNumaPolicy::EvaluateSyscall(Sandbox* sandbox, | 417 ErrorCode BlacklistDebugAndNumaPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
417 int sysno) const { | 418 int sysno) const { |
418 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 419 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { |
419 // TODO(jln) we should not have to do that in a trivial policy. | 420 // TODO(jln) we should not have to do that in a trivial policy. |
420 return ErrorCode(ENOSYS); | 421 return ErrorCode(ENOSYS); |
421 } | 422 } |
422 if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno)) | 423 if (SyscallSets::IsDebug(sysno) || SyscallSets::IsNuma(sysno)) |
423 return sandbox->Trap(sandbox::CrashSIGSYS_Handler, NULL); | 424 return sandbox->Trap(sandbox::CrashSIGSYS_Handler, NULL); |
424 | 425 |
425 return ErrorCode(ErrorCode::ERR_ALLOWED); | 426 return ErrorCode(ErrorCode::ERR_ALLOWED); |
426 } | 427 } |
427 | 428 |
428 class AllowAllPolicy : public SandboxBpfBasePolicy { | 429 class AllowAllPolicy : public SandboxBPFBasePolicy { |
429 public: | 430 public: |
430 AllowAllPolicy() {} | 431 AllowAllPolicy() {} |
431 virtual ~AllowAllPolicy() {} | 432 virtual ~AllowAllPolicy() {} |
432 | 433 |
433 virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler, | 434 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
434 int system_call_number) const OVERRIDE; | 435 int system_call_number) const OVERRIDE; |
435 | 436 |
436 private: | 437 private: |
437 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | 438 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); |
438 }; | 439 }; |
439 | 440 |
440 // Allow all syscalls. | 441 // Allow all syscalls. |
441 // This will still deny x32 or IA32 calls in 64 bits mode or | 442 // This will still deny x32 or IA32 calls in 64 bits mode or |
442 // 64 bits system calls in compatibility mode. | 443 // 64 bits system calls in compatibility mode. |
443 ErrorCode AllowAllPolicy::EvaluateSyscall(Sandbox*, int sysno) const { | 444 ErrorCode AllowAllPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { |
444 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 445 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { |
445 // TODO(jln) we should not have to do that in a trivial policy. | 446 // TODO(jln) we should not have to do that in a trivial policy. |
446 return ErrorCode(ENOSYS); | 447 return ErrorCode(ENOSYS); |
447 } else { | 448 } else { |
448 return ErrorCode(ErrorCode::ERR_ALLOWED); | 449 return ErrorCode(ErrorCode::ERR_ALLOWED); |
449 } | 450 } |
450 } | 451 } |
451 | 452 |
452 // If a BPF policy is engaged for |process_type|, run a few sanity checks. | 453 // If a BPF policy is engaged for |process_type|, run a few sanity checks. |
453 void RunSandboxSanityChecks(const std::string& process_type) { | 454 void RunSandboxSanityChecks(const std::string& process_type) { |
454 if (process_type == switches::kRendererProcess || | 455 if (process_type == switches::kRendererProcess || |
455 process_type == switches::kWorkerProcess || | 456 process_type == switches::kWorkerProcess || |
456 process_type == switches::kGpuProcess || | 457 process_type == switches::kGpuProcess || |
457 process_type == switches::kPpapiPluginProcess) { | 458 process_type == switches::kPpapiPluginProcess) { |
458 int syscall_ret; | 459 int syscall_ret; |
459 errno = 0; | 460 errno = 0; |
460 | 461 |
461 // Without the sandbox, this would EBADF. | 462 // Without the sandbox, this would EBADF. |
462 syscall_ret = fchmod(-1, 07777); | 463 syscall_ret = fchmod(-1, 07777); |
463 CHECK_EQ(-1, syscall_ret); | 464 CHECK_EQ(-1, syscall_ret); |
464 CHECK_EQ(EPERM, errno); | 465 CHECK_EQ(EPERM, errno); |
465 | 466 |
466 // Run most of the sanity checks only in DEBUG mode to avoid a perf. | 467 // Run most of the sanity checks only in DEBUG mode to avoid a perf. |
467 // impact. | 468 // impact. |
468 #if !defined(NDEBUG) | 469 #if !defined(NDEBUG) |
469 // open() must be restricted. | 470 // open() must be restricted. |
470 syscall_ret = open("/etc/passwd", O_RDONLY); | 471 syscall_ret = open("/etc/passwd", O_RDONLY); |
471 CHECK_EQ(-1, syscall_ret); | 472 CHECK_EQ(-1, syscall_ret); |
472 CHECK_EQ(SandboxBpfBasePolicy::GetFSDeniedErrno(), errno); | 473 CHECK_EQ(SandboxBPFBasePolicy::GetFSDeniedErrno(), errno); |
473 | 474 |
474 // We should never allow the creation of netlink sockets. | 475 // We should never allow the creation of netlink sockets. |
475 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); | 476 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); |
476 CHECK_EQ(-1, syscall_ret); | 477 CHECK_EQ(-1, syscall_ret); |
477 CHECK_EQ(EPERM, errno); | 478 CHECK_EQ(EPERM, errno); |
478 #endif // !defined(NDEBUG) | 479 #endif // !defined(NDEBUG) |
479 } | 480 } |
480 } | 481 } |
481 | 482 |
482 bool EnableGpuBrokerPolicyCallback() { | 483 bool EnableGpuBrokerPolicyCallback() { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 | 582 |
582 if (for_chromeos_arm) { | 583 if (for_chromeos_arm) { |
583 // We shouldn't be using this policy on non-ARM architectures. | 584 // We shouldn't be using this policy on non-ARM architectures. |
584 DCHECK(IsArchitectureArm()); | 585 DCHECK(IsArchitectureArm()); |
585 AddArmGpuWhitelist(&read_whitelist, &write_whitelist); | 586 AddArmGpuWhitelist(&read_whitelist, &write_whitelist); |
586 sandbox_callback = EnableArmGpuBrokerPolicyCallback; | 587 sandbox_callback = EnableArmGpuBrokerPolicyCallback; |
587 } else { | 588 } else { |
588 sandbox_callback = EnableGpuBrokerPolicyCallback; | 589 sandbox_callback = EnableGpuBrokerPolicyCallback; |
589 } | 590 } |
590 | 591 |
591 *broker_process = new BrokerProcess(SandboxBpfBasePolicy::GetFSDeniedErrno(), | 592 *broker_process = new BrokerProcess(SandboxBPFBasePolicy::GetFSDeniedErrno(), |
592 read_whitelist, | 593 read_whitelist, |
593 write_whitelist); | 594 write_whitelist); |
594 // Initialize the broker process and give it a sandbox callback. | 595 // Initialize the broker process and give it a sandbox callback. |
595 CHECK((*broker_process)->Init(sandbox_callback)); | 596 CHECK((*broker_process)->Init(sandbox_callback)); |
596 } | 597 } |
597 | 598 |
598 // Warms up/preloads resources needed by the policies. | 599 // Warms up/preloads resources needed by the policies. |
599 // Eventually start a broker process and return it in broker_process. | 600 // Eventually start a broker process and return it in broker_process. |
600 void WarmupPolicy(bool chromeos_arm_gpu, | 601 void WarmupPolicy(bool chromeos_arm_gpu, |
601 BrokerProcess** broker_process) { | 602 BrokerProcess** broker_process) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
657 | 658 |
658 // This should never be destroyed, as after the sandbox is started it is | 659 // This should never be destroyed, as after the sandbox is started it is |
659 // vital to the process. Ownership is transfered to the policies and then to | 660 // vital to the process. Ownership is transfered to the policies and then to |
660 // the BPF sandbox which will keep it around to service SIGSYS traps from the | 661 // the BPF sandbox which will keep it around to service SIGSYS traps from the |
661 // kernel. | 662 // kernel. |
662 BrokerProcess* broker_process = NULL; | 663 BrokerProcess* broker_process = NULL; |
663 // Warm up resources needed by the policy we're about to enable and | 664 // Warm up resources needed by the policy we're about to enable and |
664 // eventually start a broker process. | 665 // eventually start a broker process. |
665 WarmupPolicy(chromeos_arm_gpu, &broker_process); | 666 WarmupPolicy(chromeos_arm_gpu, &broker_process); |
666 | 667 |
667 scoped_ptr<SandboxBpfBasePolicy> gpu_policy; | 668 scoped_ptr<SandboxBPFBasePolicy> gpu_policy; |
668 if (chromeos_arm_gpu) { | 669 if (chromeos_arm_gpu) { |
669 gpu_policy.reset(new ArmGpuProcessPolicy(broker_process, allow_sysv_shm)); | 670 gpu_policy.reset(new ArmGpuProcessPolicy(broker_process, allow_sysv_shm)); |
670 } else { | 671 } else { |
671 gpu_policy.reset(new GpuProcessPolicy(broker_process)); | 672 gpu_policy.reset(new GpuProcessPolicy(broker_process)); |
672 } | 673 } |
673 StartSandboxWithPolicy(gpu_policy.release()); | 674 StartSandboxWithPolicy(gpu_policy.release()); |
674 } | 675 } |
675 | 676 |
676 // This function takes ownership of |policy|. | 677 // This function takes ownership of |policy|. |
677 void StartSandboxWithPolicy(playground2::SandboxBpfPolicy* policy) { | 678 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy) { |
678 // Starting the sandbox is a one-way operation. The kernel doesn't allow | 679 // Starting the sandbox is a one-way operation. The kernel doesn't allow |
679 // us to unload a sandbox policy after it has been started. Nonetheless, | 680 // us to unload a sandbox policy after it has been started. Nonetheless, |
680 // in order to make the use of the "Sandbox" object easier, we allow for | 681 // in order to make the use of the "Sandbox" object easier, we allow for |
681 // the object to be destroyed after the sandbox has been started. Note that | 682 // the object to be destroyed after the sandbox has been started. Note that |
682 // doing so does not stop the sandbox. | 683 // doing so does not stop the sandbox. |
683 Sandbox sandbox; | 684 SandboxBPF sandbox; |
684 sandbox.SetSandboxPolicy(policy); | 685 sandbox.SetSandboxPolicy(policy); |
685 sandbox.StartSandbox(); | 686 sandbox.StartSandbox(); |
686 } | 687 } |
687 | 688 |
688 void StartNonGpuSandbox(const std::string& process_type) { | 689 void StartNonGpuSandbox(const std::string& process_type) { |
689 scoped_ptr<SandboxBpfBasePolicy> policy; | 690 scoped_ptr<SandboxBPFBasePolicy> policy; |
690 | 691 |
691 if (process_type == switches::kRendererProcess || | 692 if (process_type == switches::kRendererProcess || |
692 process_type == switches::kWorkerProcess) { | 693 process_type == switches::kWorkerProcess) { |
693 policy.reset(new RendererOrWorkerProcessPolicy); | 694 policy.reset(new RendererOrWorkerProcessPolicy); |
694 } else if (process_type == switches::kPpapiPluginProcess) { | 695 } else if (process_type == switches::kPpapiPluginProcess) { |
695 policy.reset(new FlashProcessPolicy); | 696 policy.reset(new FlashProcessPolicy); |
696 } else if (process_type == switches::kUtilityProcess) { | 697 } else if (process_type == switches::kUtilityProcess) { |
697 policy.reset(new BlacklistDebugAndNumaPolicy); | 698 policy.reset(new BlacklistDebugAndNumaPolicy); |
698 } else { | 699 } else { |
699 NOTREACHED(); | 700 NOTREACHED(); |
700 policy.reset(new AllowAllPolicy); | 701 policy.reset(new AllowAllPolicy); |
701 } | 702 } |
702 | 703 |
703 StartSandboxWithPolicy(policy.release()); | 704 StartSandboxWithPolicy(policy.release()); |
704 } | 705 } |
705 | 706 |
706 // Initialize the seccomp-bpf sandbox. | 707 // Initialize the seccomp-bpf sandbox. |
707 bool StartBpfSandbox(const CommandLine& command_line, | 708 bool StartBPFSandbox(const CommandLine& command_line, |
708 const std::string& process_type) { | 709 const std::string& process_type) { |
709 | 710 |
710 if (process_type == switches::kGpuProcess) { | 711 if (process_type == switches::kGpuProcess) { |
711 StartGpuProcessSandbox(command_line, process_type); | 712 StartGpuProcessSandbox(command_line, process_type); |
712 } else { | 713 } else { |
713 StartNonGpuSandbox(process_type); | 714 StartNonGpuSandbox(process_type); |
714 } | 715 } |
715 | 716 |
716 RunSandboxSanityChecks(process_type); | 717 RunSandboxSanityChecks(process_type); |
717 return true; | 718 return true; |
718 } | 719 } |
719 | 720 |
720 } // namespace | 721 } // namespace |
721 | 722 |
722 #endif // SECCOMP_BPF_SANDBOX | 723 #endif // SECCOMP_BPF_SANDBOX |
723 | 724 |
724 // Is seccomp BPF globally enabled? | 725 // Is seccomp BPF globally enabled? |
725 bool SandboxSeccompBpf::IsSeccompBpfDesired() { | 726 bool SandboxSeccompBPF::IsSeccompBPFDesired() { |
726 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 727 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
727 if (!command_line.HasSwitch(switches::kNoSandbox) && | 728 if (!command_line.HasSwitch(switches::kNoSandbox) && |
728 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { | 729 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { |
729 return true; | 730 return true; |
730 } else { | 731 } else { |
731 return false; | 732 return false; |
732 } | 733 } |
733 } | 734 } |
734 | 735 |
735 bool SandboxSeccompBpf::ShouldEnableSeccompBpf( | 736 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( |
736 const std::string& process_type) { | 737 const std::string& process_type) { |
737 #if defined(SECCOMP_BPF_SANDBOX) | 738 #if defined(SECCOMP_BPF_SANDBOX) |
738 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 739 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
739 if (process_type == switches::kGpuProcess) | 740 if (process_type == switches::kGpuProcess) |
740 return !command_line.HasSwitch(switches::kDisableGpuSandbox); | 741 return !command_line.HasSwitch(switches::kDisableGpuSandbox); |
741 | 742 |
742 return true; | 743 return true; |
743 #endif // SECCOMP_BPF_SANDBOX | 744 #endif // SECCOMP_BPF_SANDBOX |
744 return false; | 745 return false; |
745 } | 746 } |
746 | 747 |
747 bool SandboxSeccompBpf::SupportsSandbox() { | 748 bool SandboxSeccompBPF::SupportsSandbox() { |
748 #if defined(SECCOMP_BPF_SANDBOX) | 749 #if defined(SECCOMP_BPF_SANDBOX) |
749 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton | 750 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton |
750 // here. | 751 // here. |
751 Sandbox::SandboxStatus bpf_sandbox_status = | 752 SandboxBPF::SandboxStatus bpf_sandbox_status = |
752 Sandbox::SupportsSeccompSandbox(-1); | 753 SandboxBPF::SupportsSeccompSandbox(-1); |
753 // Kernel support is what we are interested in here. Other status | 754 // Kernel support is what we are interested in here. Other status |
754 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. | 755 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. |
755 // We make this a negative check, since if there is a bug, we would rather | 756 // We make this a negative check, since if there is a bug, we would rather |
756 // "fail closed" (expect a sandbox to be available and try to start it). | 757 // "fail closed" (expect a sandbox to be available and try to start it). |
757 if (bpf_sandbox_status != Sandbox::STATUS_UNSUPPORTED) { | 758 if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { |
758 return true; | 759 return true; |
759 } | 760 } |
760 #endif | 761 #endif |
761 return false; | 762 return false; |
762 } | 763 } |
763 | 764 |
764 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) { | 765 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { |
765 #if defined(SECCOMP_BPF_SANDBOX) | 766 #if defined(SECCOMP_BPF_SANDBOX) |
766 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 767 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
767 | 768 |
768 if (IsSeccompBpfDesired() && // Global switches policy. | 769 if (IsSeccompBPFDesired() && // Global switches policy. |
769 ShouldEnableSeccompBpf(process_type) && // Process-specific policy. | 770 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. |
770 SupportsSandbox()) { | 771 SupportsSandbox()) { |
771 // If the kernel supports the sandbox, and if the command line says we | 772 // If the kernel supports the sandbox, and if the command line says we |
772 // should enable it, enable it or die. | 773 // should enable it, enable it or die. |
773 bool started_sandbox = StartBpfSandbox(command_line, process_type); | 774 bool started_sandbox = StartBPFSandbox(command_line, process_type); |
774 CHECK(started_sandbox); | 775 CHECK(started_sandbox); |
775 return true; | 776 return true; |
776 } | 777 } |
777 #endif | 778 #endif |
778 return false; | 779 return false; |
779 } | 780 } |
780 | 781 |
781 bool SandboxSeccompBpf::StartSandboxWithExternalPolicy( | 782 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( |
782 scoped_ptr<playground2::SandboxBpfPolicy> policy) { | 783 scoped_ptr<sandbox::SandboxBPFPolicy> policy) { |
783 #if defined(SECCOMP_BPF_SANDBOX) | 784 #if defined(SECCOMP_BPF_SANDBOX) |
784 if (IsSeccompBpfDesired() && SupportsSandbox()) { | 785 if (IsSeccompBPFDesired() && SupportsSandbox()) { |
785 CHECK(policy); | 786 CHECK(policy); |
786 StartSandboxWithPolicy(policy.release()); | 787 StartSandboxWithPolicy(policy.release()); |
787 return true; | 788 return true; |
788 } | 789 } |
789 #endif // defined(SECCOMP_BPF_SANDBOX) | 790 #endif // defined(SECCOMP_BPF_SANDBOX) |
790 return false; | 791 return false; |
791 } | 792 } |
792 | 793 |
793 scoped_ptr<playground2::SandboxBpfPolicy> | 794 scoped_ptr<sandbox::SandboxBPFPolicy> |
794 SandboxSeccompBpf::GetBaselinePolicy() { | 795 SandboxSeccompBPF::GetBaselinePolicy() { |
795 #if defined(SECCOMP_BPF_SANDBOX) | 796 #if defined(SECCOMP_BPF_SANDBOX) |
796 return scoped_ptr<playground2::SandboxBpfPolicy>(new BaselinePolicy); | 797 return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); |
797 #else | 798 #else |
798 return scoped_ptr<playground2::SandboxBpfPolicy>(); | 799 return scoped_ptr<sandbox::SandboxBPFPolicy>(); |
799 #endif // defined(SECCOMP_BPF_SANDBOX) | 800 #endif // defined(SECCOMP_BPF_SANDBOX) |
800 } | 801 } |
801 | 802 |
802 } // namespace content | 803 } // namespace content |
OLD | NEW |