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 |