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

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.cc

Issue 681713002: Update from chromium https://crrev.com/301315 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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 "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
6 6
7 // Some headers on Android are missing cdefs: crbug.com/172337. 7 // Some headers on Android are missing cdefs: crbug.com/172337.
8 // (We can't use OS_ANDROID here since build_config.h is not included). 8 // (We can't use OS_ANDROID here since build_config.h is not included).
9 #if defined(ANDROID) 9 #if defined(ANDROID)
10 #include <sys/cdefs.h> 10 #include <sys/cdefs.h>
(...skipping 11 matching lines...) Expand all
22 #include <sys/wait.h> 22 #include <sys/wait.h>
23 #include <time.h> 23 #include <time.h>
24 #include <unistd.h> 24 #include <unistd.h>
25 25
26 #include "base/compiler_specific.h" 26 #include "base/compiler_specific.h"
27 #include "base/logging.h" 27 #include "base/logging.h"
28 #include "base/macros.h" 28 #include "base/macros.h"
29 #include "base/memory/scoped_ptr.h" 29 #include "base/memory/scoped_ptr.h"
30 #include "base/posix/eintr_wrapper.h" 30 #include "base/posix/eintr_wrapper.h"
31 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" 31 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
32 #include "sandbox/linux/bpf_dsl/policy.h"
32 #include "sandbox/linux/bpf_dsl/policy_compiler.h" 33 #include "sandbox/linux/bpf_dsl/policy_compiler.h"
33 #include "sandbox/linux/seccomp-bpf/codegen.h" 34 #include "sandbox/linux/seccomp-bpf/codegen.h"
34 #include "sandbox/linux/seccomp-bpf/die.h" 35 #include "sandbox/linux/seccomp-bpf/die.h"
35 #include "sandbox/linux/seccomp-bpf/errorcode.h" 36 #include "sandbox/linux/seccomp-bpf/errorcode.h"
36 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 37 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
37 #include "sandbox/linux/seccomp-bpf/syscall.h" 38 #include "sandbox/linux/seccomp-bpf/syscall.h"
38 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 39 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
39 #include "sandbox/linux/seccomp-bpf/trap.h" 40 #include "sandbox/linux/seccomp-bpf/trap.h"
40 #include "sandbox/linux/seccomp-bpf/verifier.h" 41 #include "sandbox/linux/seccomp-bpf/verifier.h"
41 #include "sandbox/linux/services/linux_syscalls.h" 42 #include "sandbox/linux/services/linux_syscalls.h"
42 43
43 using sandbox::bpf_dsl::Allow; 44 using sandbox::bpf_dsl::Allow;
44 using sandbox::bpf_dsl::Error; 45 using sandbox::bpf_dsl::Error;
45 using sandbox::bpf_dsl::ResultExpr; 46 using sandbox::bpf_dsl::ResultExpr;
46 using sandbox::bpf_dsl::SandboxBPFDSLPolicy;
47 47
48 namespace sandbox { 48 namespace sandbox {
49 49
50 namespace { 50 namespace {
51 51
52 const int kExpectedExitCode = 100; 52 const int kExpectedExitCode = 100;
53 53
54 #if !defined(NDEBUG) 54 #if !defined(NDEBUG)
55 void WriteFailedStderrSetupMessage(int out_fd) { 55 void WriteFailedStderrSetupMessage(int out_fd) {
56 const char* error_string = strerror(errno); 56 const char* error_string = strerror(errno);
57 static const char msg[] = 57 static const char msg[] =
58 "You have reproduced a puzzling issue.\n" 58 "You have reproduced a puzzling issue.\n"
59 "Please, report to crbug.com/152530!\n" 59 "Please, report to crbug.com/152530!\n"
60 "Failed to set up stderr: "; 60 "Failed to set up stderr: ";
61 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg) - 1)) > 0 && error_string && 61 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg) - 1)) > 0 && error_string &&
62 HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 && 62 HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 &&
63 HANDLE_EINTR(write(out_fd, "\n", 1))) { 63 HANDLE_EINTR(write(out_fd, "\n", 1))) {
64 } 64 }
65 } 65 }
66 #endif // !defined(NDEBUG) 66 #endif // !defined(NDEBUG)
67 67
68 // We define a really simple sandbox policy. It is just good enough for us 68 // We define a really simple sandbox policy. It is just good enough for us
69 // to tell that the sandbox has actually been activated. 69 // to tell that the sandbox has actually been activated.
70 class ProbePolicy : public SandboxBPFDSLPolicy { 70 class ProbePolicy : public bpf_dsl::Policy {
71 public: 71 public:
72 ProbePolicy() {} 72 ProbePolicy() {}
73 virtual ~ProbePolicy() {} 73 virtual ~ProbePolicy() {}
74 74
75 virtual ResultExpr EvaluateSyscall(int sysnum) const override { 75 virtual ResultExpr EvaluateSyscall(int sysnum) const override {
76 switch (sysnum) { 76 switch (sysnum) {
77 case __NR_getpid: 77 case __NR_getpid:
78 // Return EPERM so that we can check that the filter actually ran. 78 // Return EPERM so that we can check that the filter actually ran.
79 return Error(EPERM); 79 return Error(EPERM);
80 case __NR_exit_group: 80 case __NR_exit_group:
81 // Allow exit() with a non-default return code. 81 // Allow exit() with a non-default return code.
82 return Allow(); 82 return Allow();
83 default: 83 default:
84 // Make everything else fail in an easily recognizable way. 84 // Make everything else fail in an easily recognizable way.
85 return Error(EINVAL); 85 return Error(EINVAL);
86 } 86 }
87 } 87 }
88 88
89 private: 89 private:
90 DISALLOW_COPY_AND_ASSIGN(ProbePolicy); 90 DISALLOW_COPY_AND_ASSIGN(ProbePolicy);
91 }; 91 };
92 92
93 void ProbeProcess(void) { 93 void ProbeProcess(void) {
94 if (syscall(__NR_getpid) < 0 && errno == EPERM) { 94 if (syscall(__NR_getpid) < 0 && errno == EPERM) {
95 syscall(__NR_exit_group, static_cast<intptr_t>(kExpectedExitCode)); 95 syscall(__NR_exit_group, static_cast<intptr_t>(kExpectedExitCode));
96 } 96 }
97 } 97 }
98 98
99 class AllowAllPolicy : public SandboxBPFDSLPolicy { 99 class AllowAllPolicy : public bpf_dsl::Policy {
100 public: 100 public:
101 AllowAllPolicy() {} 101 AllowAllPolicy() {}
102 virtual ~AllowAllPolicy() {} 102 virtual ~AllowAllPolicy() {}
103 103
104 virtual ResultExpr EvaluateSyscall(int sysnum) const override { 104 virtual ResultExpr EvaluateSyscall(int sysnum) const override {
105 DCHECK(SandboxBPF::IsValidSyscallNumber(sysnum)); 105 DCHECK(SandboxBPF::IsValidSyscallNumber(sysnum));
106 return Allow(); 106 return Allow();
107 } 107 }
108 108
109 private: 109 private:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 : quiet_(false), proc_fd_(-1), sandbox_has_started_(false), policy_() { 146 : quiet_(false), proc_fd_(-1), sandbox_has_started_(false), policy_() {
147 } 147 }
148 148
149 SandboxBPF::~SandboxBPF() { 149 SandboxBPF::~SandboxBPF() {
150 } 150 }
151 151
152 bool SandboxBPF::IsValidSyscallNumber(int sysnum) { 152 bool SandboxBPF::IsValidSyscallNumber(int sysnum) {
153 return SyscallSet::IsValid(sysnum); 153 return SyscallSet::IsValid(sysnum);
154 } 154 }
155 155
156 bool SandboxBPF::RunFunctionInPolicy( 156 bool SandboxBPF::RunFunctionInPolicy(void (*code_in_sandbox)(),
157 void (*code_in_sandbox)(), 157 scoped_ptr<bpf_dsl::Policy> policy) {
158 scoped_ptr<bpf_dsl::SandboxBPFDSLPolicy> policy) {
159 // Block all signals before forking a child process. This prevents an 158 // Block all signals before forking a child process. This prevents an
160 // attacker from manipulating our test by sending us an unexpected signal. 159 // attacker from manipulating our test by sending us an unexpected signal.
161 sigset_t old_mask, new_mask; 160 sigset_t old_mask, new_mask;
162 if (sigfillset(&new_mask) || sigprocmask(SIG_BLOCK, &new_mask, &old_mask)) { 161 if (sigfillset(&new_mask) || sigprocmask(SIG_BLOCK, &new_mask, &old_mask)) {
163 SANDBOX_DIE("sigprocmask() failed"); 162 SANDBOX_DIE("sigprocmask() failed");
164 } 163 }
165 int fds[2]; 164 int fds[2];
166 if (pipe2(fds, O_NONBLOCK | O_CLOEXEC)) { 165 if (pipe2(fds, O_NONBLOCK | O_CLOEXEC)) {
167 SANDBOX_DIE("pipe() failed"); 166 SANDBOX_DIE("pipe() failed");
168 } 167 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 266 }
268 } 267 }
269 if (IGNORE_EINTR(close(fds[0]))) { 268 if (IGNORE_EINTR(close(fds[0]))) {
270 SANDBOX_DIE("close() failed"); 269 SANDBOX_DIE("close() failed");
271 } 270 }
272 271
273 return rc; 272 return rc;
274 } 273 }
275 274
276 bool SandboxBPF::KernelSupportSeccompBPF() { 275 bool SandboxBPF::KernelSupportSeccompBPF() {
277 return RunFunctionInPolicy( 276 return RunFunctionInPolicy(ProbeProcess,
278 ProbeProcess, 277 scoped_ptr<bpf_dsl::Policy>(new ProbePolicy())) &&
279 scoped_ptr<bpf_dsl::SandboxBPFDSLPolicy>(new ProbePolicy())) && 278 RunFunctionInPolicy(TryVsyscallProcess,
280 RunFunctionInPolicy( 279 scoped_ptr<bpf_dsl::Policy>(new AllowAllPolicy()));
281 TryVsyscallProcess,
282 scoped_ptr<bpf_dsl::SandboxBPFDSLPolicy>(new AllowAllPolicy()));
283 } 280 }
284 281
285 // static 282 // static
286 SandboxBPF::SandboxStatus SandboxBPF::SupportsSeccompSandbox(int proc_fd) { 283 SandboxBPF::SandboxStatus SandboxBPF::SupportsSeccompSandbox(int proc_fd) {
287 // It the sandbox is currently active, we clearly must have support for 284 // It the sandbox is currently active, we clearly must have support for
288 // sandboxing. 285 // sandboxing.
289 if (status_ == STATUS_ENABLED) { 286 if (status_ == STATUS_ENABLED) {
290 return status_; 287 return status_;
291 } 288 }
292 289
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 // Install the filters. 413 // Install the filters.
417 InstallFilter(supports_tsync || thread_state == PROCESS_MULTI_THREADED); 414 InstallFilter(supports_tsync || thread_state == PROCESS_MULTI_THREADED);
418 415
419 // We are now inside the sandbox. 416 // We are now inside the sandbox.
420 status_ = STATUS_ENABLED; 417 status_ = STATUS_ENABLED;
421 418
422 return true; 419 return true;
423 } 420 }
424 421
425 // Don't take a scoped_ptr here, polymorphism make their use awkward. 422 // Don't take a scoped_ptr here, polymorphism make their use awkward.
426 void SandboxBPF::SetSandboxPolicy(bpf_dsl::SandboxBPFDSLPolicy* policy) { 423 void SandboxBPF::SetSandboxPolicy(bpf_dsl::Policy* policy) {
427 DCHECK(!policy_); 424 DCHECK(!policy_);
428 if (sandbox_has_started_) { 425 if (sandbox_has_started_) {
429 SANDBOX_DIE("Cannot change policy after sandbox has started"); 426 SANDBOX_DIE("Cannot change policy after sandbox has started");
430 } 427 }
431 policy_.reset(policy); 428 policy_.reset(policy);
432 } 429 }
433 430
434 void SandboxBPF::InstallFilter(bool must_sync_threads) { 431 void SandboxBPF::InstallFilter(bool must_sync_threads) {
435 // We want to be very careful in not imposing any requirements on the 432 // We want to be very careful in not imposing any requirements on the
436 // policies that are set with SetSandboxPolicy(). This means, as soon as 433 // policies that are set with SetSandboxPolicy(). This means, as soon as
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 static_cast<intptr_t>(args.args[1]), 513 static_cast<intptr_t>(args.args[1]),
517 static_cast<intptr_t>(args.args[2]), 514 static_cast<intptr_t>(args.args[2]),
518 static_cast<intptr_t>(args.args[3]), 515 static_cast<intptr_t>(args.args[3]),
519 static_cast<intptr_t>(args.args[4]), 516 static_cast<intptr_t>(args.args[4]),
520 static_cast<intptr_t>(args.args[5])); 517 static_cast<intptr_t>(args.args[5]));
521 } 518 }
522 519
523 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; 520 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN;
524 521
525 } // namespace sandbox 522 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698