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

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

Issue 628823003: sandbox_bpf: rework how unsafe traps are compiled/verified (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@policies
Patch Set: Sync 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
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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 return true; 170 return true;
171 } 171 }
172 172
173 bool IsDenied(const ErrorCode& code) { 173 bool IsDenied(const ErrorCode& code) {
174 return (code.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP || 174 return (code.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP ||
175 (code.err() >= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MIN_ERRNO) && 175 (code.err() >= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MIN_ERRNO) &&
176 code.err() <= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MAX_ERRNO)); 176 code.err() <= (SECCOMP_RET_ERRNO + ErrorCode::ERR_MAX_ERRNO));
177 } 177 }
178 178
179 // Function that can be passed as a callback function to CodeGen::Traverse().
180 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
181 // sets the "bool" variable pointed to by "aux".
182 void CheckForUnsafeErrorCodes(Instruction* insn, void* aux) {
183 bool* is_unsafe = static_cast<bool*>(aux);
184 if (!*is_unsafe) {
185 if (BPF_CLASS(insn->code) == BPF_RET && insn->k > SECCOMP_RET_TRAP &&
186 insn->k - SECCOMP_RET_TRAP <= SECCOMP_RET_DATA) {
187 if (!Trap::IsSafeTrapId(insn->k & SECCOMP_RET_DATA)) {
188 *is_unsafe = true;
189 }
190 }
191 }
192 }
193
194 // A Trap() handler that returns an "errno" value. The value is encoded 179 // A Trap() handler that returns an "errno" value. The value is encoded
195 // in the "aux" parameter. 180 // in the "aux" parameter.
196 intptr_t ReturnErrno(const struct arch_seccomp_data&, void* aux) { 181 intptr_t ReturnErrno(const struct arch_seccomp_data&, void* aux) {
197 // TrapFnc functions report error by following the native kernel convention 182 // TrapFnc functions report error by following the native kernel convention
198 // of returning an exit code in the range of -1..-4096. They do not try to 183 // of returning an exit code in the range of -1..-4096. They do not try to
199 // set errno themselves. The glibc wrapper that triggered the SIGSYS will 184 // set errno themselves. The glibc wrapper that triggered the SIGSYS will
200 // ultimately do so for us. 185 // ultimately do so for us.
201 int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA; 186 int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA;
202 return -err; 187 return -err;
203 } 188 }
204 189
205 // Function that can be passed as a callback function to CodeGen::Traverse().
206 // Checks whether the "insn" returns an errno value from a BPF filter. If so,
207 // it rewrites the instruction to instead call a Trap() handler that does
208 // the same thing. "aux" is ignored.
209 void RedirectToUserspace(Instruction* insn, void* aux) {
210 // When inside an UnsafeTrap() callback, we want to allow all system calls.
211 // This means, we must conditionally disable the sandbox -- and that's not
212 // something that kernel-side BPF filters can do, as they cannot inspect
213 // any state other than the syscall arguments.
214 // But if we redirect all error handlers to user-space, then we can easily
215 // make this decision.
216 // The performance penalty for this extra round-trip to user-space is not
217 // actually that bad, as we only ever pay it for denied system calls; and a
218 // typical program has very few of these.
219 SandboxBPF* sandbox = static_cast<SandboxBPF*>(aux);
220 if (BPF_CLASS(insn->code) == BPF_RET &&
221 (insn->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
222 insn->k = sandbox->Trap(ReturnErrno,
223 reinterpret_cast<void*>(insn->k & SECCOMP_RET_DATA)).err();
224 }
225 }
226
227 // This wraps an existing policy and changes its behavior to match the changes
228 // made by RedirectToUserspace(). This is part of the framework that allows BPF
229 // evaluation in userland.
230 // TODO(markus): document the code inside better.
231 class RedirectToUserSpacePolicyWrapper : public SandboxBPFPolicy {
232 public:
233 explicit RedirectToUserSpacePolicyWrapper(
234 const SandboxBPFPolicy* wrapped_policy)
235 : wrapped_policy_(wrapped_policy) {
236 DCHECK(wrapped_policy_);
237 }
238
239 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
240 int system_call_number) const OVERRIDE {
241 ErrorCode err =
242 wrapped_policy_->EvaluateSyscall(sandbox_compiler, system_call_number);
243 ChangeErrnoToTraps(&err, sandbox_compiler);
244 return err;
245 }
246
247 virtual ErrorCode InvalidSyscall(
248 SandboxBPF* sandbox_compiler) const OVERRIDE {
249 return ReturnErrnoViaTrap(sandbox_compiler, ENOSYS);
250 }
251
252 private:
253 ErrorCode ReturnErrnoViaTrap(SandboxBPF* sandbox_compiler, int err) const {
254 return sandbox_compiler->Trap(ReturnErrno, reinterpret_cast<void*>(err));
255 }
256
257 // ChangeErrnoToTraps recursivly iterates through the ErrorCode
258 // converting any ERRNO to a userspace trap
259 void ChangeErrnoToTraps(ErrorCode* err, SandboxBPF* sandbox_compiler) const {
260 if (err->error_type() == ErrorCode::ET_SIMPLE &&
261 (err->err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
262 // Have an errno, need to change this to a trap
263 *err =
264 ReturnErrnoViaTrap(sandbox_compiler, err->err() & SECCOMP_RET_DATA);
265 return;
266 } else if (err->error_type() == ErrorCode::ET_COND) {
267 // Need to explore both paths
268 ChangeErrnoToTraps((ErrorCode*)err->passed(), sandbox_compiler);
269 ChangeErrnoToTraps((ErrorCode*)err->failed(), sandbox_compiler);
270 return;
271 } else if (err->error_type() == ErrorCode::ET_TRAP) {
272 return;
273 } else if (err->error_type() == ErrorCode::ET_SIMPLE &&
274 (err->err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ALLOW) {
275 return;
276 }
277 NOTREACHED();
278 }
279
280 const SandboxBPFPolicy* wrapped_policy_;
281 DISALLOW_COPY_AND_ASSIGN(RedirectToUserSpacePolicyWrapper);
282 };
283
284 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) { 190 intptr_t BPFFailure(const struct arch_seccomp_data&, void* aux) {
285 SANDBOX_DIE(static_cast<char*>(aux)); 191 SANDBOX_DIE(static_cast<char*>(aux));
286 } 192 }
287 193
288 } // namespace 194 } // namespace
289 195
290 SandboxBPF::SandboxBPF() 196 SandboxBPF::SandboxBPF()
291 : quiet_(false), 197 : quiet_(false),
292 proc_fd_(-1), 198 proc_fd_(-1),
293 conds_(new Conds), 199 conds_(new Conds),
294 sandbox_has_started_(false) {} 200 sandbox_has_started_(false),
201 has_unsafe_traps_(false) {
202 }
295 203
296 SandboxBPF::~SandboxBPF() { 204 SandboxBPF::~SandboxBPF() {
297 // It is generally unsafe to call any memory allocator operations or to even 205 // It is generally unsafe to call any memory allocator operations or to even
298 // call arbitrary destructors after having installed a new policy. We just 206 // call arbitrary destructors after having installed a new policy. We just
299 // have no way to tell whether this policy would allow the system calls that 207 // have no way to tell whether this policy would allow the system calls that
300 // the constructors can trigger. 208 // the constructors can trigger.
301 // So, we normally destroy all of our complex state prior to starting the 209 // So, we normally destroy all of our complex state prior to starting the
302 // sandbox. But this won't happen, if the Sandbox object was created and 210 // sandbox. But this won't happen, if the Sandbox object was created and
303 // never actually used to set up a sandbox. So, just in case, we are 211 // never actually used to set up a sandbox. So, just in case, we are
304 // destroying any remaining state. 212 // destroying any remaining state.
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 } 557 }
650 558
651 SandboxBPF::Program* SandboxBPF::AssembleFilter(bool force_verification) { 559 SandboxBPF::Program* SandboxBPF::AssembleFilter(bool force_verification) {
652 #if !defined(NDEBUG) 560 #if !defined(NDEBUG)
653 force_verification = true; 561 force_verification = true;
654 #endif 562 #endif
655 563
656 // Verify that the user pushed a policy. 564 // Verify that the user pushed a policy.
657 DCHECK(policy_); 565 DCHECK(policy_);
658 566
567 // If our BPF program has unsafe traps, enable support for them.
568 has_unsafe_traps_ = policy_->HasUnsafeTraps();
569 if (has_unsafe_traps_) {
570 // As support for unsafe jumps essentially defeats all the security
571 // measures that the sandbox provides, we print a big warning message --
572 // and of course, we make sure to only ever enable this feature if it
573 // is actually requested by the sandbox policy.
574 if (Syscall::Call(-1) == -1 && errno == ENOSYS) {
575 SANDBOX_DIE(
576 "Support for UnsafeTrap() has not yet been ported to this "
577 "architecture");
578 }
579
580 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) {
581 if (!policy_->EvaluateSyscall(this, kSyscallsRequiredForUnsafeTraps[i])
582 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))) {
583 SANDBOX_DIE(
584 "Policies that use UnsafeTrap() must unconditionally allow all "
585 "required system calls");
586 }
587 }
588
589 if (!Trap::EnableUnsafeTrapsInSigSysHandler()) {
590 // We should never be able to get here, as UnsafeTrap() should never
591 // actually return a valid ErrorCode object unless the user set the
592 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore,
593 // "has_unsafe_traps" would always be false. But better double-check
594 // than enabling dangerous code.
595 SANDBOX_DIE("We'd rather die than enable unsafe traps");
596 }
597 }
598
659 // Assemble the BPF filter program. 599 // Assemble the BPF filter program.
660 CodeGen* gen = new CodeGen(); 600 CodeGen* gen = new CodeGen();
661 if (!gen) { 601 if (!gen) {
662 SANDBOX_DIE("Out of memory"); 602 SANDBOX_DIE("Out of memory");
663 } 603 }
664 604 Instruction* head = CompilePolicy(gen);
665 bool has_unsafe_traps;
666 Instruction* head = CompilePolicy(gen, &has_unsafe_traps);
667 605
668 // Turn the DAG into a vector of instructions. 606 // Turn the DAG into a vector of instructions.
669 Program* program = new Program(); 607 Program* program = new Program();
670 gen->Compile(head, program); 608 gen->Compile(head, program);
671 delete gen; 609 delete gen;
672 610
673 // Make sure compilation resulted in BPF program that executes 611 // Make sure compilation resulted in BPF program that executes
674 // correctly. Otherwise, there is an internal error in our BPF compiler. 612 // correctly. Otherwise, there is an internal error in our BPF compiler.
675 // There is really nothing the caller can do until the bug is fixed. 613 // There is really nothing the caller can do until the bug is fixed.
676 if (force_verification) { 614 if (force_verification) {
677 // Verification is expensive. We only perform this step, if we are 615 // Verification is expensive. We only perform this step, if we are
678 // compiled in debug mode, or if the caller explicitly requested 616 // compiled in debug mode, or if the caller explicitly requested
679 // verification. 617 // verification.
680 VerifyProgram(*program, has_unsafe_traps); 618 VerifyProgram(*program);
681 } 619 }
682 620
683 return program; 621 return program;
684 } 622 }
685 623
686 Instruction* SandboxBPF::CompilePolicy(CodeGen* gen, bool* has_unsafe_traps) { 624 Instruction* SandboxBPF::CompilePolicy(CodeGen* gen) {
687 // A compiled policy consists of three logical parts: 625 // A compiled policy consists of three logical parts:
688 // 1. Check that the "arch" field matches the expected architecture. 626 // 1. Check that the "arch" field matches the expected architecture.
689 // 2. If the policy involves unsafe traps, check if the syscall was 627 // 2. If the policy involves unsafe traps, check if the syscall was
690 // invoked by Syscall::Call, and then allow it unconditionally. 628 // invoked by Syscall::Call, and then allow it unconditionally.
691 // 3. Check the system call number and jump to the appropriate compiled 629 // 3. Check the system call number and jump to the appropriate compiled
692 // system call policy number. 630 // system call policy number.
693 return CheckArch( 631 return CheckArch(gen, MaybeAddEscapeHatch(gen, DispatchSyscall(gen)));
694 gen, MaybeAddEscapeHatch(gen, has_unsafe_traps, DispatchSyscall(gen)));
695 } 632 }
696 633
697 Instruction* SandboxBPF::CheckArch(CodeGen* gen, Instruction* passed) { 634 Instruction* SandboxBPF::CheckArch(CodeGen* gen, Instruction* passed) {
698 // If the architecture doesn't match SECCOMP_ARCH, disallow the 635 // If the architecture doesn't match SECCOMP_ARCH, disallow the
699 // system call. 636 // system call.
700 return gen->MakeInstruction( 637 return gen->MakeInstruction(
701 BPF_LD + BPF_W + BPF_ABS, 638 BPF_LD + BPF_W + BPF_ABS,
702 SECCOMP_ARCH_IDX, 639 SECCOMP_ARCH_IDX,
703 gen->MakeInstruction( 640 gen->MakeInstruction(
704 BPF_JMP + BPF_JEQ + BPF_K, 641 BPF_JMP + BPF_JEQ + BPF_K,
705 SECCOMP_ARCH, 642 SECCOMP_ARCH,
706 passed, 643 passed,
707 RetExpression(gen, 644 RetExpression(gen,
708 Kill("Invalid audit architecture in BPF filter")))); 645 Kill("Invalid audit architecture in BPF filter"))));
709 } 646 }
710 647
711 Instruction* SandboxBPF::MaybeAddEscapeHatch(CodeGen* gen, 648 Instruction* SandboxBPF::MaybeAddEscapeHatch(CodeGen* gen,
712 bool* has_unsafe_traps,
713 Instruction* rest) { 649 Instruction* rest) {
714 // If there is at least one UnsafeTrap() in our program, the entire sandbox 650 // If no unsafe traps, then simply return |rest|.
715 // is unsafe. We need to modify the program so that all non- 651 if (!has_unsafe_traps_) {
716 // SECCOMP_RET_ALLOW ErrorCodes are handled in user-space. This will then
717 // allow us to temporarily disable sandboxing rules inside of callbacks to
718 // UnsafeTrap().
719 *has_unsafe_traps = false;
720 gen->Traverse(rest, CheckForUnsafeErrorCodes, has_unsafe_traps);
721 if (!*has_unsafe_traps) {
722 // If no unsafe traps, then simply return |rest|.
723 return rest; 652 return rest;
724 } 653 }
725 654
726 // If our BPF program has unsafe jumps, enable support for them. This
727 // test happens very early in the BPF filter program. Even before we
728 // consider looking at system call numbers.
729 // As support for unsafe jumps essentially defeats all the security
730 // measures that the sandbox provides, we print a big warning message --
731 // and of course, we make sure to only ever enable this feature if it
732 // is actually requested by the sandbox policy.
733 if (Syscall::Call(-1) == -1 && errno == ENOSYS) {
734 SANDBOX_DIE(
735 "Support for UnsafeTrap() has not yet been ported to this "
736 "architecture");
737 }
738
739 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) {
740 if (!policy_->EvaluateSyscall(this, kSyscallsRequiredForUnsafeTraps[i])
741 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))) {
742 SANDBOX_DIE(
743 "Policies that use UnsafeTrap() must unconditionally allow all "
744 "required system calls");
745 }
746 }
747
748 if (!Trap::EnableUnsafeTrapsInSigSysHandler()) {
749 // We should never be able to get here, as UnsafeTrap() should never
750 // actually return a valid ErrorCode object unless the user set the
751 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore,
752 // "has_unsafe_traps" would always be false. But better double-check
753 // than enabling dangerous code.
754 SANDBOX_DIE("We'd rather die than enable unsafe traps");
755 }
756 gen->Traverse(rest, RedirectToUserspace, this);
757
758 // Allow system calls, if they originate from our magic return address 655 // Allow system calls, if they originate from our magic return address
759 // (which we can query by calling Syscall::Call(-1)). 656 // (which we can query by calling Syscall::Call(-1)).
760 uint64_t syscall_entry_point = 657 uint64_t syscall_entry_point =
761 static_cast<uint64_t>(static_cast<uintptr_t>(Syscall::Call(-1))); 658 static_cast<uint64_t>(static_cast<uintptr_t>(Syscall::Call(-1)));
762 uint32_t low = static_cast<uint32_t>(syscall_entry_point); 659 uint32_t low = static_cast<uint32_t>(syscall_entry_point);
763 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32); 660 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32);
764 661
765 // BPF cannot do native 64-bit comparisons, so we have to compare 662 // BPF cannot do native 64-bit comparisons, so we have to compare
766 // both 32-bit halves of the instruction pointer. If they match what 663 // both 32-bit halves of the instruction pointer. If they match what
767 // we expect, we return ERR_ALLOWED. If either or both don't match, 664 // we expect, we return ERR_ALLOWED. If either or both don't match,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 // The older i386 and x86-64 APIs clear bit 30 on all system calls. 713 // The older i386 and x86-64 APIs clear bit 30 on all system calls.
817 return gen->MakeInstruction( 714 return gen->MakeInstruction(
818 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, passed); 715 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, passed);
819 } 716 }
820 } 717 }
821 718
822 // TODO(mdempsky): Similar validation for other architectures? 719 // TODO(mdempsky): Similar validation for other architectures?
823 return passed; 720 return passed;
824 } 721 }
825 722
826 void SandboxBPF::VerifyProgram(const Program& program, bool has_unsafe_traps) { 723 void SandboxBPF::VerifyProgram(const Program& program) {
827 // If we previously rewrote the BPF program so that it calls user-space
828 // whenever we return an "errno" value from the filter, then we have to
829 // wrap our system call evaluator to perform the same operation. Otherwise,
830 // the verifier would also report a mismatch in return codes.
831 scoped_ptr<const RedirectToUserSpacePolicyWrapper> redirected_policy(
832 new RedirectToUserSpacePolicyWrapper(policy_.get()));
833
834 const char* err = NULL; 724 const char* err = NULL;
835 if (!Verifier::VerifyBPF(this, 725 if (!Verifier::VerifyBPF(this, program, *policy_, &err)) {
836 program,
837 has_unsafe_traps ? *redirected_policy : *policy_,
838 &err)) {
839 CodeGen::PrintProgram(program); 726 CodeGen::PrintProgram(program);
840 SANDBOX_DIE(err); 727 SANDBOX_DIE(err);
841 } 728 }
842 } 729 }
843 730
844 void SandboxBPF::FindRanges(Ranges* ranges) { 731 void SandboxBPF::FindRanges(Ranges* ranges) {
845 // Please note that "struct seccomp_data" defines system calls as a signed 732 // Please note that "struct seccomp_data" defines system calls as a signed
846 // int32_t, but BPF instructions always operate on unsigned quantities. We 733 // int32_t, but BPF instructions always operate on unsigned quantities. We
847 // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL, 734 // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL,
848 // and then verifying that the rest of the number range (both positive and 735 // and then verifying that the rest of the number range (both positive and
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 BPF_ALU + BPF_AND + BPF_K, 941 BPF_ALU + BPF_AND + BPF_K,
1055 mask, 942 mask,
1056 gen->MakeInstruction( 943 gen->MakeInstruction(
1057 BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed))); 944 BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
1058 } 945 }
1059 946
1060 ErrorCode SandboxBPF::Unexpected64bitArgument() { 947 ErrorCode SandboxBPF::Unexpected64bitArgument() {
1061 return Kill("Unexpected 64bit argument detected"); 948 return Kill("Unexpected 64bit argument detected");
1062 } 949 }
1063 950
951 ErrorCode SandboxBPF::Error(int err) {
952 if (has_unsafe_traps_) {
953 // When inside an UnsafeTrap() callback, we want to allow all system calls.
954 // This means, we must conditionally disable the sandbox -- and that's not
955 // something that kernel-side BPF filters can do, as they cannot inspect
956 // any state other than the syscall arguments.
957 // But if we redirect all error handlers to user-space, then we can easily
958 // make this decision.
959 // The performance penalty for this extra round-trip to user-space is not
960 // actually that bad, as we only ever pay it for denied system calls; and a
961 // typical program has very few of these.
962 return Trap(ReturnErrno, reinterpret_cast<void*>(err));
963 }
964
965 return ErrorCode(err);
966 }
967
1064 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { 968 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) {
1065 return ErrorCode(fnc, aux, true /* Safe Trap */); 969 return ErrorCode(fnc, aux, true /* Safe Trap */);
1066 } 970 }
1067 971
1068 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { 972 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) {
1069 return ErrorCode(fnc, aux, false /* Unsafe Trap */); 973 return ErrorCode(fnc, aux, false /* Unsafe Trap */);
1070 } 974 }
1071 975
1072 bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) { 976 bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) {
1073 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) { 977 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 } 1047 }
1144 } 1048 }
1145 1049
1146 ErrorCode SandboxBPF::Kill(const char* msg) { 1050 ErrorCode SandboxBPF::Kill(const char* msg) {
1147 return Trap(BPFFailure, const_cast<char*>(msg)); 1051 return Trap(BPFFailure, const_cast<char*>(msg));
1148 } 1052 }
1149 1053
1150 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; 1054 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN;
1151 1055
1152 } // namespace sandbox 1056 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698