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

Side by Side Diff: sandbox/linux/bpf_dsl/policy_compiler.cc

Issue 660153002: bpf_dsl: move more implementation details out of bpf_dsl.h (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git/+/master
Patch Set: IWYU Created 6 years, 2 months 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
« no previous file with comments | « sandbox/linux/bpf_dsl/bpf_dsl_impl.h ('k') | sandbox/linux/seccomp-bpf/verifier.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/bpf_dsl/policy_compiler.h" 5 #include "sandbox/linux/bpf_dsl/policy_compiler.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/filter.h> 8 #include <linux/filter.h>
9 #include <sys/syscall.h> 9 #include <sys/syscall.h>
10 10
11 #include <limits> 11 #include <limits>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" 15 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
16 #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
16 #include "sandbox/linux/seccomp-bpf/codegen.h" 17 #include "sandbox/linux/seccomp-bpf/codegen.h"
17 #include "sandbox/linux/seccomp-bpf/die.h" 18 #include "sandbox/linux/seccomp-bpf/die.h"
18 #include "sandbox/linux/seccomp-bpf/errorcode.h" 19 #include "sandbox/linux/seccomp-bpf/errorcode.h"
19 #include "sandbox/linux/seccomp-bpf/instruction.h" 20 #include "sandbox/linux/seccomp-bpf/instruction.h"
20 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 21 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
21 #include "sandbox/linux/seccomp-bpf/syscall.h" 22 #include "sandbox/linux/seccomp-bpf/syscall.h"
22 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 23 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
23 24
24 namespace sandbox { 25 namespace sandbox {
25 namespace bpf_dsl { 26 namespace bpf_dsl {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // set errno themselves. The glibc wrapper that triggered the SIGSYS will 68 // set errno themselves. The glibc wrapper that triggered the SIGSYS will
68 // ultimately do so for us. 69 // ultimately do so for us.
69 int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA; 70 int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA;
70 return -err; 71 return -err;
71 } 72 }
72 73
73 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) { 74 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) {
74 SANDBOX_DIE(static_cast<char*>(aux)); 75 SANDBOX_DIE(static_cast<char*>(aux));
75 } 76 }
76 77
78 bool HasUnsafeTraps(const SandboxBPFDSLPolicy* policy) {
79 for (SyscallIterator iter(false); !iter.Done();) {
80 uint32_t sysnum = iter.Next();
81 if (SyscallIterator::IsValid(sysnum) &&
82 policy->EvaluateSyscall(sysnum)->HasUnsafeTraps()) {
83 return true;
84 }
85 }
86 return policy->InvalidSyscall()->HasUnsafeTraps();
87 }
88
77 } // namespace 89 } // namespace
78 90
79 struct PolicyCompiler::Range { 91 struct PolicyCompiler::Range {
80 Range(uint32_t f, uint32_t t, const ErrorCode& e) : from(f), to(t), err(e) {} 92 Range(uint32_t f, uint32_t t, const ErrorCode& e) : from(f), to(t), err(e) {}
81 uint32_t from, to; 93 uint32_t from, to;
82 ErrorCode err; 94 ErrorCode err;
83 }; 95 };
84 96
85 PolicyCompiler::PolicyCompiler(const SandboxBPFDSLPolicy* policy, 97 PolicyCompiler::PolicyCompiler(const SandboxBPFDSLPolicy* policy,
86 TrapRegistry* registry) 98 TrapRegistry* registry)
87 : policy_(policy), 99 : policy_(policy),
88 registry_(registry), 100 registry_(registry),
89 conds_(), 101 conds_(),
90 gen_(), 102 gen_(),
91 has_unsafe_traps_(policy_->HasUnsafeTraps()) { 103 has_unsafe_traps_(HasUnsafeTraps(policy_)) {
92 } 104 }
93 105
94 PolicyCompiler::~PolicyCompiler() { 106 PolicyCompiler::~PolicyCompiler() {
95 } 107 }
96 108
97 scoped_ptr<CodeGen::Program> PolicyCompiler::Compile() { 109 scoped_ptr<CodeGen::Program> PolicyCompiler::Compile() {
98 if (!IsDenied(policy_->InvalidSyscall(this))) { 110 if (!IsDenied(policy_->InvalidSyscall()->Compile(this))) {
99 SANDBOX_DIE("Policies should deny invalid system calls."); 111 SANDBOX_DIE("Policies should deny invalid system calls.");
100 } 112 }
101 113
102 // If our BPF program has unsafe traps, enable support for them. 114 // If our BPF program has unsafe traps, enable support for them.
103 if (has_unsafe_traps_) { 115 if (has_unsafe_traps_) {
104 // As support for unsafe jumps essentially defeats all the security 116 // As support for unsafe jumps essentially defeats all the security
105 // measures that the sandbox provides, we print a big warning message -- 117 // measures that the sandbox provides, we print a big warning message --
106 // and of course, we make sure to only ever enable this feature if it 118 // and of course, we make sure to only ever enable this feature if it
107 // is actually requested by the sandbox policy. 119 // is actually requested by the sandbox policy.
108 if (Syscall::Call(-1) == -1 && errno == ENOSYS) { 120 if (Syscall::Call(-1) == -1 && errno == ENOSYS) {
109 SANDBOX_DIE( 121 SANDBOX_DIE(
110 "Support for UnsafeTrap() has not yet been ported to this " 122 "Support for UnsafeTrap() has not yet been ported to this "
111 "architecture"); 123 "architecture");
112 } 124 }
113 125
114 for (int sysnum : kSyscallsRequiredForUnsafeTraps) { 126 for (int sysnum : kSyscallsRequiredForUnsafeTraps) {
115 if (!policy_->EvaluateSyscall(this, sysnum) 127 if (!policy_->EvaluateSyscall(sysnum)->Compile(this)
116 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))) { 128 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))) {
117 SANDBOX_DIE( 129 SANDBOX_DIE(
118 "Policies that use UnsafeTrap() must unconditionally allow all " 130 "Policies that use UnsafeTrap() must unconditionally allow all "
119 "required system calls"); 131 "required system calls");
120 } 132 }
121 } 133 }
122 134
123 if (!registry_->EnableUnsafeTraps()) { 135 if (!registry_->EnableUnsafeTraps()) {
124 // We should never be able to get here, as UnsafeTrap() should never 136 // We should never be able to get here, as UnsafeTrap() should never
125 // actually return a valid ErrorCode object unless the user set the 137 // actually return a valid ErrorCode object unless the user set the
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 // TODO(mdempsky): Similar validation for other architectures? 243 // TODO(mdempsky): Similar validation for other architectures?
232 return passed; 244 return passed;
233 } 245 }
234 246
235 void PolicyCompiler::FindRanges(Ranges* ranges) { 247 void PolicyCompiler::FindRanges(Ranges* ranges) {
236 // Please note that "struct seccomp_data" defines system calls as a signed 248 // Please note that "struct seccomp_data" defines system calls as a signed
237 // int32_t, but BPF instructions always operate on unsigned quantities. We 249 // int32_t, but BPF instructions always operate on unsigned quantities. We
238 // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL, 250 // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL,
239 // and then verifying that the rest of the number range (both positive and 251 // and then verifying that the rest of the number range (both positive and
240 // negative) all return the same ErrorCode. 252 // negative) all return the same ErrorCode.
241 const ErrorCode invalid_err = policy_->InvalidSyscall(this); 253 const ErrorCode invalid_err = policy_->InvalidSyscall()->Compile(this);
242 uint32_t old_sysnum = 0; 254 uint32_t old_sysnum = 0;
243 ErrorCode old_err = SyscallIterator::IsValid(old_sysnum) 255 ErrorCode old_err = SyscallIterator::IsValid(old_sysnum)
244 ? policy_->EvaluateSyscall(this, old_sysnum) 256 ? policy_->EvaluateSyscall(old_sysnum)->Compile(this)
245 : invalid_err; 257 : invalid_err;
246 258
247 for (SyscallIterator iter(false); !iter.Done();) { 259 for (SyscallIterator iter(false); !iter.Done();) {
248 uint32_t sysnum = iter.Next(); 260 uint32_t sysnum = iter.Next();
249 ErrorCode err = 261 ErrorCode err =
250 SyscallIterator::IsValid(sysnum) 262 SyscallIterator::IsValid(sysnum)
251 ? policy_->EvaluateSyscall(this, static_cast<int>(sysnum)) 263 ? policy_->EvaluateSyscall(static_cast<int>(sysnum))->Compile(this)
252 : invalid_err; 264 : invalid_err;
253 if (!err.Equals(old_err) || iter.Done()) { 265 if (!err.Equals(old_err) || iter.Done()) {
254 ranges->push_back(Range(old_sysnum, sysnum - 1, old_err)); 266 ranges->push_back(Range(old_sysnum, sysnum - 1, old_err));
255 old_sysnum = sysnum; 267 old_sysnum = sysnum;
256 old_err = err; 268 old_err = err;
257 } 269 }
258 } 270 }
259 } 271 }
260 272
261 Instruction* PolicyCompiler::AssembleJumpTable(Ranges::const_iterator start, 273 Instruction* PolicyCompiler::AssembleJumpTable(Ranges::const_iterator start,
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 &*conds_.insert(passed).first, 515 &*conds_.insert(passed).first,
504 &*conds_.insert(failed).first); 516 &*conds_.insert(failed).first);
505 } 517 }
506 518
507 ErrorCode PolicyCompiler::Kill(const char* msg) { 519 ErrorCode PolicyCompiler::Kill(const char* msg) {
508 return Trap(BPFFailure, const_cast<char*>(msg)); 520 return Trap(BPFFailure, const_cast<char*>(msg));
509 } 521 }
510 522
511 } // namespace bpf_dsl 523 } // namespace bpf_dsl
512 } // namespace sandbox 524 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/bpf_dsl/bpf_dsl_impl.h ('k') | sandbox/linux/seccomp-bpf/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698