| 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> |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 #endif // | 57 #endif // |
| 58 | 58 |
| 59 namespace content { | 59 namespace content { |
| 60 | 60 |
| 61 #if defined(USE_SECCOMP_BPF) | 61 #if defined(USE_SECCOMP_BPF) |
| 62 namespace { | 62 namespace { |
| 63 | 63 |
| 64 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy, | 64 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy, |
| 65 base::ScopedFD proc_fd); | 65 base::ScopedFD proc_fd); |
| 66 | 66 |
| 67 #if !defined(OS_NACL_NONSFI) |
| 68 |
| 67 inline bool IsChromeOS() { | 69 inline bool IsChromeOS() { |
| 68 #if defined(OS_CHROMEOS) | 70 #if defined(OS_CHROMEOS) |
| 69 return true; | 71 return true; |
| 70 #else | 72 #else |
| 71 return false; | 73 return false; |
| 72 #endif | 74 #endif |
| 73 } | 75 } |
| 74 | 76 |
| 75 inline bool IsArchitectureArm() { | 77 inline bool IsArchitectureArm() { |
| 76 #if defined(__arm__) | 78 #if defined(__arm__) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 CHECK_EQ(-1, syscall_ret); | 139 CHECK_EQ(-1, syscall_ret); |
| 138 CHECK_EQ(SandboxBPFBasePolicy::GetFSDeniedErrno(), errno); | 140 CHECK_EQ(SandboxBPFBasePolicy::GetFSDeniedErrno(), errno); |
| 139 | 141 |
| 140 // We should never allow the creation of netlink sockets. | 142 // We should never allow the creation of netlink sockets. |
| 141 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); | 143 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); |
| 142 CHECK_EQ(-1, syscall_ret); | 144 CHECK_EQ(-1, syscall_ret); |
| 143 CHECK_EQ(EPERM, errno); | 145 CHECK_EQ(EPERM, errno); |
| 144 #endif // !defined(NDEBUG) | 146 #endif // !defined(NDEBUG) |
| 145 } | 147 } |
| 146 } | 148 } |
| 147 | 149 #endif // !defined(OS_NACL_NONSFI) |
| 148 | 150 |
| 149 // This function takes ownership of |policy|. | 151 // This function takes ownership of |policy|. |
| 150 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy, | 152 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy, |
| 151 base::ScopedFD proc_fd) { | 153 base::ScopedFD proc_fd) { |
| 152 // Starting the sandbox is a one-way operation. The kernel doesn't allow | 154 // Starting the sandbox is a one-way operation. The kernel doesn't allow |
| 153 // us to unload a sandbox policy after it has been started. Nonetheless, | 155 // us to unload a sandbox policy after it has been started. Nonetheless, |
| 154 // in order to make the use of the "Sandbox" object easier, we allow for | 156 // in order to make the use of the "Sandbox" object easier, we allow for |
| 155 // the object to be destroyed after the sandbox has been started. Note that | 157 // the object to be destroyed after the sandbox has been started. Note that |
| 156 // doing so does not stop the sandbox. | 158 // doing so does not stop the sandbox. |
| 157 SandboxBPF sandbox(policy); | 159 SandboxBPF sandbox(policy); |
| 158 | 160 |
| 159 sandbox.SetProcFd(proc_fd.Pass()); | 161 sandbox.SetProcFd(proc_fd.Pass()); |
| 160 CHECK(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); | 162 CHECK(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); |
| 161 } | 163 } |
| 162 | 164 |
| 165 #if !defined(OS_NACL_NONSFI) |
| 163 // nacl_helper needs to be tiny and includes only part of content/ | 166 // nacl_helper needs to be tiny and includes only part of content/ |
| 164 // in its dependencies. Make sure to not link things that are not needed. | 167 // in its dependencies. Make sure to not link things that are not needed. |
| 165 #if !defined(IN_NACL_HELPER) | 168 #if !defined(IN_NACL_HELPER) |
| 166 scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { | 169 scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { |
| 167 const base::CommandLine& command_line = | 170 const base::CommandLine& command_line = |
| 168 *base::CommandLine::ForCurrentProcess(); | 171 *base::CommandLine::ForCurrentProcess(); |
| 169 bool allow_sysv_shm = false; | 172 bool allow_sysv_shm = false; |
| 170 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { | 173 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { |
| 171 DCHECK(IsArchitectureArm()); | 174 DCHECK(IsArchitectureArm()); |
| 172 allow_sysv_shm = true; | 175 allow_sysv_shm = true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 bool StartBPFSandbox(const base::CommandLine& command_line, | 216 bool StartBPFSandbox(const base::CommandLine& command_line, |
| 214 const std::string& process_type) { | 217 const std::string& process_type) { |
| 215 NOTREACHED(); | 218 NOTREACHED(); |
| 216 // Avoid -Wunused-function with no-op code. | 219 // Avoid -Wunused-function with no-op code. |
| 217 ignore_result(IsChromeOS); | 220 ignore_result(IsChromeOS); |
| 218 ignore_result(IsArchitectureArm); | 221 ignore_result(IsArchitectureArm); |
| 219 ignore_result(RunSandboxSanityChecks); | 222 ignore_result(RunSandboxSanityChecks); |
| 220 return false; | 223 return false; |
| 221 } | 224 } |
| 222 #endif // !defined(IN_NACL_HELPER) | 225 #endif // !defined(IN_NACL_HELPER) |
| 226 #endif // !defined(OS_NACL_NONSFI) |
| 223 | 227 |
| 224 } // namespace | 228 } // namespace |
| 225 | 229 |
| 226 #endif // USE_SECCOMP_BPF | 230 #endif // USE_SECCOMP_BPF |
| 227 | 231 |
| 228 // Is seccomp BPF globally enabled? | 232 // Is seccomp BPF globally enabled? |
| 229 bool SandboxSeccompBPF::IsSeccompBPFDesired() { | 233 bool SandboxSeccompBPF::IsSeccompBPFDesired() { |
| 230 const base::CommandLine& command_line = | 234 const base::CommandLine& command_line = |
| 231 *base::CommandLine::ForCurrentProcess(); | 235 *base::CommandLine::ForCurrentProcess(); |
| 232 if (!command_line.HasSwitch(switches::kNoSandbox) && | 236 if (!command_line.HasSwitch(switches::kNoSandbox) && |
| 233 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { | 237 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) { |
| 234 return true; | 238 return true; |
| 235 } else { | 239 } else { |
| 236 return false; | 240 return false; |
| 237 } | 241 } |
| 238 } | 242 } |
| 239 | 243 |
| 244 #if !defined(OS_NACL_NONSFI) |
| 240 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( | 245 bool SandboxSeccompBPF::ShouldEnableSeccompBPF( |
| 241 const std::string& process_type) { | 246 const std::string& process_type) { |
| 242 #if defined(USE_SECCOMP_BPF) | 247 #if defined(USE_SECCOMP_BPF) |
| 243 const base::CommandLine& command_line = | 248 const base::CommandLine& command_line = |
| 244 *base::CommandLine::ForCurrentProcess(); | 249 *base::CommandLine::ForCurrentProcess(); |
| 245 if (process_type == switches::kGpuProcess) | 250 if (process_type == switches::kGpuProcess) |
| 246 return !command_line.HasSwitch(switches::kDisableGpuSandbox); | 251 return !command_line.HasSwitch(switches::kDisableGpuSandbox); |
| 247 | 252 |
| 248 return true; | 253 return true; |
| 249 #endif // USE_SECCOMP_BPF | 254 #endif // USE_SECCOMP_BPF |
| 250 return false; | 255 return false; |
| 251 } | 256 } |
| 257 #endif // !defined(OS_NACL_NONSFI) |
| 252 | 258 |
| 253 bool SandboxSeccompBPF::SupportsSandbox() { | 259 bool SandboxSeccompBPF::SupportsSandbox() { |
| 254 #if defined(USE_SECCOMP_BPF) | 260 #if defined(USE_SECCOMP_BPF) |
| 255 return SandboxBPF::SupportsSeccompSandbox( | 261 return SandboxBPF::SupportsSeccompSandbox( |
| 256 SandboxBPF::SeccompLevel::SINGLE_THREADED); | 262 SandboxBPF::SeccompLevel::SINGLE_THREADED); |
| 257 #endif | 263 #endif |
| 258 return false; | 264 return false; |
| 259 } | 265 } |
| 260 | 266 |
| 267 #if !defined(OS_NACL_NONSFI) |
| 261 bool SandboxSeccompBPF::SupportsSandboxWithTsync() { | 268 bool SandboxSeccompBPF::SupportsSandboxWithTsync() { |
| 262 #if defined(USE_SECCOMP_BPF) | 269 #if defined(USE_SECCOMP_BPF) |
| 263 return SandboxBPF::SupportsSeccompSandbox( | 270 return SandboxBPF::SupportsSeccompSandbox( |
| 264 SandboxBPF::SeccompLevel::MULTI_THREADED); | 271 SandboxBPF::SeccompLevel::MULTI_THREADED); |
| 265 #endif | 272 #endif |
| 266 return false; | 273 return false; |
| 267 } | 274 } |
| 268 | 275 |
| 269 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type, | 276 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type, |
| 270 base::ScopedFD proc_fd) { | 277 base::ScopedFD proc_fd) { |
| 271 #if defined(USE_SECCOMP_BPF) | 278 #if defined(USE_SECCOMP_BPF) |
| 272 const base::CommandLine& command_line = | 279 const base::CommandLine& command_line = |
| 273 *base::CommandLine::ForCurrentProcess(); | 280 *base::CommandLine::ForCurrentProcess(); |
| 274 | 281 |
| 275 if (IsSeccompBPFDesired() && // Global switches policy. | 282 if (IsSeccompBPFDesired() && // Global switches policy. |
| 276 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. | 283 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. |
| 277 SupportsSandbox()) { | 284 SupportsSandbox()) { |
| 278 // If the kernel supports the sandbox, and if the command line says we | 285 // If the kernel supports the sandbox, and if the command line says we |
| 279 // should enable it, enable it or die. | 286 // should enable it, enable it or die. |
| 280 bool started_sandbox = | 287 bool started_sandbox = |
| 281 StartBPFSandbox(command_line, process_type, proc_fd.Pass()); | 288 StartBPFSandbox(command_line, process_type, proc_fd.Pass()); |
| 282 CHECK(started_sandbox); | 289 CHECK(started_sandbox); |
| 283 return true; | 290 return true; |
| 284 } | 291 } |
| 285 #endif | 292 #endif |
| 286 return false; | 293 return false; |
| 287 } | 294 } |
| 295 #endif // !defined(OS_NACL_NONSFI) |
| 288 | 296 |
| 289 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( | 297 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( |
| 290 scoped_ptr<sandbox::bpf_dsl::Policy> policy, | 298 scoped_ptr<sandbox::bpf_dsl::Policy> policy, |
| 291 base::ScopedFD proc_fd) { | 299 base::ScopedFD proc_fd) { |
| 292 #if defined(USE_SECCOMP_BPF) | 300 #if defined(USE_SECCOMP_BPF) |
| 293 if (IsSeccompBPFDesired() && SupportsSandbox()) { | 301 if (IsSeccompBPFDesired() && SupportsSandbox()) { |
| 294 CHECK(policy); | 302 CHECK(policy); |
| 295 StartSandboxWithPolicy(policy.release(), proc_fd.Pass()); | 303 StartSandboxWithPolicy(policy.release(), proc_fd.Pass()); |
| 296 return true; | 304 return true; |
| 297 } | 305 } |
| 298 #endif // defined(USE_SECCOMP_BPF) | 306 #endif // defined(USE_SECCOMP_BPF) |
| 299 return false; | 307 return false; |
| 300 } | 308 } |
| 301 | 309 |
| 310 #if !defined(OS_NACL_NONSFI) |
| 302 scoped_ptr<sandbox::bpf_dsl::Policy> SandboxSeccompBPF::GetBaselinePolicy() { | 311 scoped_ptr<sandbox::bpf_dsl::Policy> SandboxSeccompBPF::GetBaselinePolicy() { |
| 303 #if defined(USE_SECCOMP_BPF) | 312 #if defined(USE_SECCOMP_BPF) |
| 304 return scoped_ptr<sandbox::bpf_dsl::Policy>(new BaselinePolicy); | 313 return scoped_ptr<sandbox::bpf_dsl::Policy>(new BaselinePolicy); |
| 305 #else | 314 #else |
| 306 return scoped_ptr<sandbox::bpf_dsl::Policy>(); | 315 return scoped_ptr<sandbox::bpf_dsl::Policy>(); |
| 307 #endif // defined(USE_SECCOMP_BPF) | 316 #endif // defined(USE_SECCOMP_BPF) |
| 308 } | 317 } |
| 318 #endif // !defined(OS_NACL_NONSFI) |
| 309 | 319 |
| 310 } // namespace content | 320 } // namespace content |
| OLD | NEW |