| 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 "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" | 5 #include "content/common/sandbox_linux/sandbox_seccomp_bpf_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
| 11 #include <sys/stat.h> | 11 #include <sys/stat.h> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/types.h> | 13 #include <sys/types.h> |
| 14 | 14 |
| 15 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
| 19 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
| 20 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
| 20 | 21 |
| 21 // These are the only architectures supported for now. | 22 #if defined(USE_SECCOMP_BPF) |
| 22 #if defined(__i386__) || defined(__x86_64__) || \ | |
| 23 (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))) | |
| 24 #define SECCOMP_BPF_SANDBOX | |
| 25 #endif | |
| 26 | 23 |
| 27 #if defined(SECCOMP_BPF_SANDBOX) | |
| 28 #include "base/posix/eintr_wrapper.h" | 24 #include "base/posix/eintr_wrapper.h" |
| 29 #include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h" | 25 #include "content/common/sandbox_linux/bpf_cros_arm_gpu_policy_linux.h" |
| 30 #include "content/common/sandbox_linux/bpf_gpu_policy_linux.h" | 26 #include "content/common/sandbox_linux/bpf_gpu_policy_linux.h" |
| 31 #include "content/common/sandbox_linux/bpf_ppapi_policy_linux.h" | 27 #include "content/common/sandbox_linux/bpf_ppapi_policy_linux.h" |
| 32 #include "content/common/sandbox_linux/bpf_renderer_policy_linux.h" | 28 #include "content/common/sandbox_linux/bpf_renderer_policy_linux.h" |
| 33 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" | 29 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" |
| 34 #include "content/common/sandbox_linux/sandbox_linux.h" | 30 #include "content/common/sandbox_linux/sandbox_linux.h" |
| 35 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" | 31 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" |
| 36 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" | 32 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" |
| 37 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" | 33 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" |
| 38 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" | 34 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" |
| 39 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 35 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
| 40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | |
| 41 #include "sandbox/linux/services/linux_syscalls.h" | 36 #include "sandbox/linux/services/linux_syscalls.h" |
| 42 | 37 |
| 43 using sandbox::BaselinePolicy; | 38 using sandbox::BaselinePolicy; |
| 44 using sandbox::SyscallSets; | 39 using sandbox::SyscallSets; |
| 45 | 40 |
| 41 #else |
| 42 |
| 43 // Make sure that seccomp-bpf does not get disabled by mistake. Also make sure |
| 44 // that we think twice about this when adding a new architecture. |
| 45 #if !defined(ARCH_CPU_MIPS_FAMILY) |
| 46 #error "Seccomp-bpf disabled on supported architecture!" |
| 47 #endif // !defined(ARCH_CPU_MIPS_FAMILY) |
| 48 |
| 49 #endif // |
| 50 |
| 46 namespace content { | 51 namespace content { |
| 47 | 52 |
| 53 #if defined(USE_SECCOMP_BPF) |
| 48 namespace { | 54 namespace { |
| 49 | 55 |
| 50 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); | 56 void StartSandboxWithPolicy(sandbox::SandboxBPFPolicy* policy); |
| 51 | 57 |
| 52 inline bool IsChromeOS() { | 58 inline bool IsChromeOS() { |
| 53 #if defined(OS_CHROMEOS) | 59 #if defined(OS_CHROMEOS) |
| 54 return true; | 60 return true; |
| 55 #else | 61 #else |
| 56 return false; | 62 return false; |
| 57 #endif | 63 #endif |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 // Avoid -Wunused-function with no-op code. | 213 // Avoid -Wunused-function with no-op code. |
| 208 ignore_result(IsChromeOS); | 214 ignore_result(IsChromeOS); |
| 209 ignore_result(IsArchitectureArm); | 215 ignore_result(IsArchitectureArm); |
| 210 ignore_result(RunSandboxSanityChecks); | 216 ignore_result(RunSandboxSanityChecks); |
| 211 return false; | 217 return false; |
| 212 } | 218 } |
| 213 #endif // !defined(IN_NACL_HELPER) | 219 #endif // !defined(IN_NACL_HELPER) |
| 214 | 220 |
| 215 } // namespace | 221 } // namespace |
| 216 | 222 |
| 217 #endif // SECCOMP_BPF_SANDBOX | 223 #endif // USE_SECCOMP_BPF |
| 218 | 224 |
| 219 // Is seccomp BPF globally enabled? | 225 // Is seccomp BPF globally enabled? |
| 220 bool SandboxSeccompBPF::IsSeccompBPFDesired() { | 226 bool SandboxSeccompBPF::IsSeccompBPFDesired() { |
| 221 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 227 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 222 if (!command_line.HasSwitch(switches::kNoSandbox) && | 228 if (!command_line.HasSwitch(switches::kNoSandbox) && |
| 223 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { | 229 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { |
| 224 return true; | 230 return true; |
| 225 } else { | 231 } else { |
| 226 return false; | 232 return false; |
| 227 } | 233 } |
| 228 } | 234 } |
| 229 | 235 |
| 230 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( | 236 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( |
| 231 const std::string& process_type) { | 237 const std::string& process_type) { |
| 232 #if defined(SECCOMP_BPF_SANDBOX) | 238 #if defined(USE_SECCOMP_BPF) |
| 233 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 239 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 234 if (process_type == switches::kGpuProcess) | 240 if (process_type == switches::kGpuProcess) |
| 235 return !command_line.HasSwitch(switches::kDisableGpuSandbox); | 241 return !command_line.HasSwitch(switches::kDisableGpuSandbox); |
| 236 | 242 |
| 237 return true; | 243 return true; |
| 238 #endif // SECCOMP_BPF_SANDBOX | 244 #endif // USE_SECCOMP_BPF |
| 239 return false; | 245 return false; |
| 240 } | 246 } |
| 241 | 247 |
| 242 bool SandboxSeccompBPF::SupportsSandbox() { | 248 bool SandboxSeccompBPF::SupportsSandbox() { |
| 243 #if defined(SECCOMP_BPF_SANDBOX) | 249 #if defined(USE_SECCOMP_BPF) |
| 244 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton | 250 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton |
| 245 // here. | 251 // here. |
| 246 SandboxBPF::SandboxStatus bpf_sandbox_status = | 252 SandboxBPF::SandboxStatus bpf_sandbox_status = |
| 247 SandboxBPF::SupportsSeccompSandbox(-1); | 253 SandboxBPF::SupportsSeccompSandbox(-1); |
| 248 // Kernel support is what we are interested in here. Other status | 254 // Kernel support is what we are interested in here. Other status |
| 249 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. | 255 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support. |
| 250 // We make this a negative check, since if there is a bug, we would rather | 256 // We make this a negative check, since if there is a bug, we would rather |
| 251 // "fail closed" (expect a sandbox to be available and try to start it). | 257 // "fail closed" (expect a sandbox to be available and try to start it). |
| 252 if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { | 258 if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) { |
| 253 return true; | 259 return true; |
| 254 } | 260 } |
| 255 #endif | 261 #endif |
| 256 return false; | 262 return false; |
| 257 } | 263 } |
| 258 | 264 |
| 259 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { | 265 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { |
| 260 #if defined(SECCOMP_BPF_SANDBOX) | 266 #if defined(USE_SECCOMP_BPF) |
| 261 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 267 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 262 | 268 |
| 263 if (IsSeccompBPFDesired() && // Global switches policy. | 269 if (IsSeccompBPFDesired() && // Global switches policy. |
| 264 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. | 270 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. |
| 265 SupportsSandbox()) { | 271 SupportsSandbox()) { |
| 266 // If the kernel supports the sandbox, and if the command line says we | 272 // If the kernel supports the sandbox, and if the command line says we |
| 267 // should enable it, enable it or die. | 273 // should enable it, enable it or die. |
| 268 bool started_sandbox = StartBPFSandbox(command_line, process_type); | 274 bool started_sandbox = StartBPFSandbox(command_line, process_type); |
| 269 CHECK(started_sandbox); | 275 CHECK(started_sandbox); |
| 270 return true; | 276 return true; |
| 271 } | 277 } |
| 272 #endif | 278 #endif |
| 273 return false; | 279 return false; |
| 274 } | 280 } |
| 275 | 281 |
| 276 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( | 282 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( |
| 277 scoped_ptr<sandbox::SandboxBPFPolicy> policy) { | 283 scoped_ptr<sandbox::SandboxBPFPolicy> policy) { |
| 278 #if defined(SECCOMP_BPF_SANDBOX) | 284 #if defined(USE_SECCOMP_BPF) |
| 279 if (IsSeccompBPFDesired() && SupportsSandbox()) { | 285 if (IsSeccompBPFDesired() && SupportsSandbox()) { |
| 280 CHECK(policy); | 286 CHECK(policy); |
| 281 StartSandboxWithPolicy(policy.release()); | 287 StartSandboxWithPolicy(policy.release()); |
| 282 return true; | 288 return true; |
| 283 } | 289 } |
| 284 #endif // defined(SECCOMP_BPF_SANDBOX) | 290 #endif // defined(USE_SECCOMP_BPF) |
| 285 return false; | 291 return false; |
| 286 } | 292 } |
| 287 | 293 |
| 288 scoped_ptr<sandbox::SandboxBPFPolicy> | 294 scoped_ptr<sandbox::SandboxBPFPolicy> |
| 289 SandboxSeccompBPF::GetBaselinePolicy() { | 295 SandboxSeccompBPF::GetBaselinePolicy() { |
| 290 #if defined(SECCOMP_BPF_SANDBOX) | 296 #if defined(USE_SECCOMP_BPF) |
| 291 return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); | 297 return scoped_ptr<sandbox::SandboxBPFPolicy>(new BaselinePolicy); |
| 292 #else | 298 #else |
| 293 return scoped_ptr<sandbox::SandboxBPFPolicy>(); | 299 return scoped_ptr<sandbox::SandboxBPFPolicy>(); |
| 294 #endif // defined(SECCOMP_BPF_SANDBOX) | 300 #endif // defined(USE_SECCOMP_BPF) |
| 295 } | 301 } |
| 296 | 302 |
| 297 } // namespace content | 303 } // namespace content |
| OLD | NEW |