Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: content/common/sandbox_linux/sandbox_seccomp_bpf_linux.cc

Issue 733303004: Linux sandbox: change API to start the sandbox (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rewrap comment. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/types.h> 11 #include <sys/types.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
18 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" 18 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
19 19
20 #if defined(USE_SECCOMP_BPF) 20 #if defined(USE_SECCOMP_BPF)
21 21
22 #include "base/files/scoped_file.h"
23 #include "base/memory/scoped_ptr.h"
22 #include "base/posix/eintr_wrapper.h" 24 #include "base/posix/eintr_wrapper.h"
23 #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"
24 #include "content/common/sandbox_linux/bpf_gpu_policy_linux.h" 26 #include "content/common/sandbox_linux/bpf_gpu_policy_linux.h"
25 #include "content/common/sandbox_linux/bpf_ppapi_policy_linux.h" 27 #include "content/common/sandbox_linux/bpf_ppapi_policy_linux.h"
26 #include "content/common/sandbox_linux/bpf_renderer_policy_linux.h" 28 #include "content/common/sandbox_linux/bpf_renderer_policy_linux.h"
27 #include "content/common/sandbox_linux/bpf_utility_policy_linux.h" 29 #include "content/common/sandbox_linux/bpf_utility_policy_linux.h"
28 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h" 30 #include "content/common/sandbox_linux/sandbox_bpf_base_policy_linux.h"
29 #include "content/common/sandbox_linux/sandbox_linux.h" 31 #include "content/common/sandbox_linux/sandbox_linux.h"
30 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" 32 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
31 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" 33 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
(...skipping 20 matching lines...) Expand all
52 #error "Seccomp-bpf disabled on supported architecture!" 54 #error "Seccomp-bpf disabled on supported architecture!"
53 #endif // !defined(ARCH_CPU_ARM64) 55 #endif // !defined(ARCH_CPU_ARM64)
54 56
55 #endif // 57 #endif //
56 58
57 namespace content { 59 namespace content {
58 60
59 #if defined(USE_SECCOMP_BPF) 61 #if defined(USE_SECCOMP_BPF)
60 namespace { 62 namespace {
61 63
62 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy); 64 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy,
65 base::ScopedFD proc_task_fd);
63 66
64 inline bool IsChromeOS() { 67 inline bool IsChromeOS() {
65 #if defined(OS_CHROMEOS) 68 #if defined(OS_CHROMEOS)
66 return true; 69 return true;
67 #else 70 #else
68 return false; 71 return false;
69 #endif 72 #endif
70 } 73 }
71 74
72 inline bool IsArchitectureArm() { 75 inline bool IsArchitectureArm() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 // We should never allow the creation of netlink sockets. 140 // We should never allow the creation of netlink sockets.
138 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0); 141 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0);
139 CHECK_EQ(-1, syscall_ret); 142 CHECK_EQ(-1, syscall_ret);
140 CHECK_EQ(EPERM, errno); 143 CHECK_EQ(EPERM, errno);
141 #endif // !defined(NDEBUG) 144 #endif // !defined(NDEBUG)
142 } 145 }
143 } 146 }
144 147
145 148
146 // This function takes ownership of |policy|. 149 // This function takes ownership of |policy|.
147 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy) { 150 void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy,
151 base::ScopedFD proc_task_fd) {
148 // Starting the sandbox is a one-way operation. The kernel doesn't allow 152 // Starting the sandbox is a one-way operation. The kernel doesn't allow
149 // us to unload a sandbox policy after it has been started. Nonetheless, 153 // us to unload a sandbox policy after it has been started. Nonetheless,
150 // in order to make the use of the "Sandbox" object easier, we allow for 154 // in order to make the use of the "Sandbox" object easier, we allow for
151 // the object to be destroyed after the sandbox has been started. Note that 155 // the object to be destroyed after the sandbox has been started. Note that
152 // doing so does not stop the sandbox. 156 // doing so does not stop the sandbox.
153 SandboxBPF sandbox; 157 SandboxBPF sandbox;
154 sandbox.SetSandboxPolicy(policy); 158 sandbox.SetSandboxPolicy(policy);
159
160 sandbox.set_proc_task_fd(proc_task_fd.release());
155 CHECK(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); 161 CHECK(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED));
156 } 162 }
157 163
158 // nacl_helper needs to be tiny and includes only part of content/ 164 // nacl_helper needs to be tiny and includes only part of content/
159 // in its dependencies. Make sure to not link things that are not needed. 165 // in its dependencies. Make sure to not link things that are not needed.
160 #if !defined(IN_NACL_HELPER) 166 #if !defined(IN_NACL_HELPER)
161 scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() { 167 scoped_ptr<SandboxBPFBasePolicy> GetGpuProcessSandbox() {
162 const base::CommandLine& command_line = 168 const base::CommandLine& command_line =
163 *base::CommandLine::ForCurrentProcess(); 169 *base::CommandLine::ForCurrentProcess();
164 bool allow_sysv_shm = false; 170 bool allow_sysv_shm = false;
165 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) { 171 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm)) {
166 DCHECK(IsArchitectureArm()); 172 DCHECK(IsArchitectureArm());
167 allow_sysv_shm = true; 173 allow_sysv_shm = true;
168 } 174 }
169 175
170 if (IsChromeOS() && IsArchitectureArm()) { 176 if (IsChromeOS() && IsArchitectureArm()) {
171 return scoped_ptr<SandboxBPFBasePolicy>( 177 return scoped_ptr<SandboxBPFBasePolicy>(
172 new CrosArmGpuProcessPolicy(allow_sysv_shm)); 178 new CrosArmGpuProcessPolicy(allow_sysv_shm));
173 } else { 179 } else {
174 bool allow_mincore = command_line.HasSwitch(switches::kUseGL) && 180 bool allow_mincore = command_line.HasSwitch(switches::kUseGL) &&
175 command_line.GetSwitchValueASCII(switches::kUseGL) == 181 command_line.GetSwitchValueASCII(switches::kUseGL) ==
176 gfx::kGLImplementationEGLName; 182 gfx::kGLImplementationEGLName;
177 return scoped_ptr<SandboxBPFBasePolicy>( 183 return scoped_ptr<SandboxBPFBasePolicy>(
178 new GpuProcessPolicy(allow_mincore)); 184 new GpuProcessPolicy(allow_mincore));
179 } 185 }
180 } 186 }
181 187
182 // Initialize the seccomp-bpf sandbox. 188 // Initialize the seccomp-bpf sandbox.
183 bool StartBPFSandbox(const base::CommandLine& command_line, 189 bool StartBPFSandbox(const base::CommandLine& command_line,
184 const std::string& process_type) { 190 const std::string& process_type,
191 base::ScopedFD proc_task_fd) {
185 scoped_ptr<SandboxBPFBasePolicy> policy; 192 scoped_ptr<SandboxBPFBasePolicy> policy;
186 193
187 if (process_type == switches::kGpuProcess) { 194 if (process_type == switches::kGpuProcess) {
188 policy.reset(GetGpuProcessSandbox().release()); 195 policy.reset(GetGpuProcessSandbox().release());
189 } else if (process_type == switches::kRendererProcess) { 196 } else if (process_type == switches::kRendererProcess) {
190 policy.reset(new RendererProcessPolicy); 197 policy.reset(new RendererProcessPolicy);
191 } else if (process_type == switches::kPpapiPluginProcess) { 198 } else if (process_type == switches::kPpapiPluginProcess) {
192 policy.reset(new PpapiProcessPolicy); 199 policy.reset(new PpapiProcessPolicy);
193 } else if (process_type == switches::kUtilityProcess) { 200 } else if (process_type == switches::kUtilityProcess) {
194 policy.reset(new UtilityProcessPolicy); 201 policy.reset(new UtilityProcessPolicy);
195 } else { 202 } else {
196 NOTREACHED(); 203 NOTREACHED();
197 policy.reset(new AllowAllPolicy); 204 policy.reset(new AllowAllPolicy);
198 } 205 }
199 206
200 CHECK(policy->PreSandboxHook()); 207 CHECK(policy->PreSandboxHook());
201 StartSandboxWithPolicy(policy.release()); 208 StartSandboxWithPolicy(policy.release(), proc_task_fd.Pass());
202 209
203 RunSandboxSanityChecks(process_type); 210 RunSandboxSanityChecks(process_type);
204 return true; 211 return true;
205 } 212 }
206 #else // defined(IN_NACL_HELPER) 213 #else // defined(IN_NACL_HELPER)
207 bool StartBPFSandbox(const base::CommandLine& command_line, 214 bool StartBPFSandbox(const base::CommandLine& command_line,
208 const std::string& process_type) { 215 const std::string& process_type) {
209 NOTREACHED(); 216 NOTREACHED();
210 // Avoid -Wunused-function with no-op code. 217 // Avoid -Wunused-function with no-op code.
211 ignore_result(IsChromeOS); 218 ignore_result(IsChromeOS);
(...skipping 27 matching lines...) Expand all
239 if (process_type == switches::kGpuProcess) 246 if (process_type == switches::kGpuProcess)
240 return !command_line.HasSwitch(switches::kDisableGpuSandbox); 247 return !command_line.HasSwitch(switches::kDisableGpuSandbox);
241 248
242 return true; 249 return true;
243 #endif // USE_SECCOMP_BPF 250 #endif // USE_SECCOMP_BPF
244 return false; 251 return false;
245 } 252 }
246 253
247 bool SandboxSeccompBPF::SupportsSandbox() { 254 bool SandboxSeccompBPF::SupportsSandbox() {
248 #if defined(USE_SECCOMP_BPF) 255 #if defined(USE_SECCOMP_BPF)
249 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton
250 // here.
251 SandboxBPF::SandboxStatus bpf_sandbox_status = 256 SandboxBPF::SandboxStatus bpf_sandbox_status =
252 SandboxBPF::SupportsSeccompSandbox(-1); 257 SandboxBPF::SupportsSeccompSandbox();
253 // Kernel support is what we are interested in here. Other status 258 if (bpf_sandbox_status == SandboxBPF::STATUS_AVAILABLE) {
254 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support.
255 // We make this a negative check, since if there is a bug, we would rather
256 // "fail closed" (expect a sandbox to be available and try to start it).
257 if (bpf_sandbox_status != SandboxBPF::STATUS_UNSUPPORTED) {
258 return true; 259 return true;
259 } 260 }
260 #endif 261 #endif
261 return false; 262 return false;
262 } 263 }
263 264
264 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type) { 265 bool SandboxSeccompBPF::StartSandbox(const std::string& process_type,
266 base::ScopedFD proc_task_fd) {
265 #if defined(USE_SECCOMP_BPF) 267 #if defined(USE_SECCOMP_BPF)
266 const base::CommandLine& command_line = 268 const base::CommandLine& command_line =
267 *base::CommandLine::ForCurrentProcess(); 269 *base::CommandLine::ForCurrentProcess();
268 270
269 if (IsSeccompBPFDesired() && // Global switches policy. 271 if (IsSeccompBPFDesired() && // Global switches policy.
270 ShouldEnableSeccompBPF(process_type) && // Process-specific policy. 272 ShouldEnableSeccompBPF(process_type) && // Process-specific policy.
271 SupportsSandbox()) { 273 SupportsSandbox()) {
272 // If the kernel supports the sandbox, and if the command line says we 274 // If the kernel supports the sandbox, and if the command line says we
273 // should enable it, enable it or die. 275 // should enable it, enable it or die.
274 bool started_sandbox = StartBPFSandbox(command_line, process_type); 276 bool started_sandbox =
277 StartBPFSandbox(command_line, process_type, proc_task_fd.Pass());
275 CHECK(started_sandbox); 278 CHECK(started_sandbox);
276 return true; 279 return true;
277 } 280 }
278 #endif 281 #endif
279 return false; 282 return false;
280 } 283 }
281 284
282 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy( 285 bool SandboxSeccompBPF::StartSandboxWithExternalPolicy(
283 scoped_ptr<sandbox::bpf_dsl::Policy> policy) { 286 scoped_ptr<sandbox::bpf_dsl::Policy> policy,
287 base::ScopedFD proc_task_fd) {
284 #if defined(USE_SECCOMP_BPF) 288 #if defined(USE_SECCOMP_BPF)
285 if (IsSeccompBPFDesired() && SupportsSandbox()) { 289 if (IsSeccompBPFDesired() && SupportsSandbox()) {
286 CHECK(policy); 290 CHECK(policy);
287 StartSandboxWithPolicy(policy.release()); 291 StartSandboxWithPolicy(policy.release(), proc_task_fd.Pass());
288 return true; 292 return true;
289 } 293 }
290 #endif // defined(USE_SECCOMP_BPF) 294 #endif // defined(USE_SECCOMP_BPF)
291 return false; 295 return false;
292 } 296 }
293 297
294 scoped_ptr<sandbox::bpf_dsl::Policy> SandboxSeccompBPF::GetBaselinePolicy() { 298 scoped_ptr<sandbox::bpf_dsl::Policy> SandboxSeccompBPF::GetBaselinePolicy() {
295 #if defined(USE_SECCOMP_BPF) 299 #if defined(USE_SECCOMP_BPF)
296 return scoped_ptr<sandbox::bpf_dsl::Policy>(new BaselinePolicy); 300 return scoped_ptr<sandbox::bpf_dsl::Policy>(new BaselinePolicy);
297 #else 301 #else
298 return scoped_ptr<sandbox::bpf_dsl::Policy>(); 302 return scoped_ptr<sandbox::bpf_dsl::Policy>();
299 #endif // defined(USE_SECCOMP_BPF) 303 #endif // defined(USE_SECCOMP_BPF)
300 } 304 }
301 305
302 } // namespace content 306 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698