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 "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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX); | 606 gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX); |
607 | 607 |
608 // If our BPF program has unsafe jumps, enable support for them. This | 608 // If our BPF program has unsafe jumps, enable support for them. This |
609 // test happens very early in the BPF filter program. Even before we | 609 // test happens very early in the BPF filter program. Even before we |
610 // consider looking at system call numbers. | 610 // consider looking at system call numbers. |
611 // As support for unsafe jumps essentially defeats all the security | 611 // As support for unsafe jumps essentially defeats all the security |
612 // measures that the sandbox provides, we print a big warning message -- | 612 // measures that the sandbox provides, we print a big warning message -- |
613 // and of course, we make sure to only ever enable this feature if it | 613 // and of course, we make sure to only ever enable this feature if it |
614 // is actually requested by the sandbox policy. | 614 // is actually requested by the sandbox policy. |
615 if (has_unsafe_traps) { | 615 if (has_unsafe_traps) { |
616 if (SandboxSyscall(-1) == -1 && errno == ENOSYS) { | 616 if (Syscall::Call(-1) == -1 && errno == ENOSYS) { |
617 SANDBOX_DIE( | 617 SANDBOX_DIE( |
618 "Support for UnsafeTrap() has not yet been ported to this " | 618 "Support for UnsafeTrap() has not yet been ported to this " |
619 "architecture"); | 619 "architecture"); |
620 } | 620 } |
621 | 621 |
622 if (!policy_->EvaluateSyscall(this, __NR_rt_sigprocmask) | 622 if (!policy_->EvaluateSyscall(this, __NR_rt_sigprocmask) |
623 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) || | 623 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) || |
624 !policy_->EvaluateSyscall(this, __NR_rt_sigreturn) | 624 !policy_->EvaluateSyscall(this, __NR_rt_sigreturn) |
625 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) | 625 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) |
626 #if defined(__NR_sigprocmask) | 626 #if defined(__NR_sigprocmask) |
(...skipping 16 matching lines...) Expand all Loading... |
643 // We should never be able to get here, as UnsafeTrap() should never | 643 // We should never be able to get here, as UnsafeTrap() should never |
644 // actually return a valid ErrorCode object unless the user set the | 644 // actually return a valid ErrorCode object unless the user set the |
645 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore, | 645 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore, |
646 // "has_unsafe_traps" would always be false. But better double-check | 646 // "has_unsafe_traps" would always be false. But better double-check |
647 // than enabling dangerous code. | 647 // than enabling dangerous code. |
648 SANDBOX_DIE("We'd rather die than enable unsafe traps"); | 648 SANDBOX_DIE("We'd rather die than enable unsafe traps"); |
649 } | 649 } |
650 gen->Traverse(jumptable, RedirectToUserspace, this); | 650 gen->Traverse(jumptable, RedirectToUserspace, this); |
651 | 651 |
652 // Allow system calls, if they originate from our magic return address | 652 // Allow system calls, if they originate from our magic return address |
653 // (which we can query by calling SandboxSyscall(-1)). | 653 // (which we can query by calling Syscall::Call(-1)). |
654 uintptr_t syscall_entry_point = | 654 uintptr_t syscall_entry_point = static_cast<uintptr_t>(Syscall::Call(-1)); |
655 static_cast<uintptr_t>(SandboxSyscall(-1)); | |
656 uint32_t low = static_cast<uint32_t>(syscall_entry_point); | 655 uint32_t low = static_cast<uint32_t>(syscall_entry_point); |
657 #if __SIZEOF_POINTER__ > 4 | 656 #if __SIZEOF_POINTER__ > 4 |
658 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32); | 657 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32); |
659 #endif | 658 #endif |
660 | 659 |
661 // BPF cannot do native 64bit comparisons. On 64bit architectures, we | 660 // BPF cannot do native 64bit comparisons. On 64bit architectures, we |
662 // have to compare both 32bit halves of the instruction pointer. If they | 661 // have to compare both 32bit halves of the instruction pointer. If they |
663 // match what we expect, we return ERR_ALLOWED. If either or both don't | 662 // match what we expect, we return ERR_ALLOWED. If either or both don't |
664 // match, we continue evalutating the rest of the sandbox policy. | 663 // match, we continue evalutating the rest of the sandbox policy. |
665 Instruction* escape_hatch = gen->MakeInstruction( | 664 Instruction* escape_hatch = gen->MakeInstruction( |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 | 995 |
997 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { | 996 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { |
998 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); | 997 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); |
999 } | 998 } |
1000 | 999 |
1001 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { | 1000 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { |
1002 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); | 1001 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); |
1003 } | 1002 } |
1004 | 1003 |
1005 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { | 1004 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { |
1006 return SandboxSyscall(args.nr, | 1005 return Syscall::Call(args.nr, |
1007 static_cast<intptr_t>(args.args[0]), | 1006 static_cast<intptr_t>(args.args[0]), |
1008 static_cast<intptr_t>(args.args[1]), | 1007 static_cast<intptr_t>(args.args[1]), |
1009 static_cast<intptr_t>(args.args[2]), | 1008 static_cast<intptr_t>(args.args[2]), |
1010 static_cast<intptr_t>(args.args[3]), | 1009 static_cast<intptr_t>(args.args[3]), |
1011 static_cast<intptr_t>(args.args[4]), | 1010 static_cast<intptr_t>(args.args[4]), |
1012 static_cast<intptr_t>(args.args[5])); | 1011 static_cast<intptr_t>(args.args[5])); |
1013 } | 1012 } |
1014 | 1013 |
1015 ErrorCode SandboxBPF::Cond(int argno, | 1014 ErrorCode SandboxBPF::Cond(int argno, |
1016 ErrorCode::ArgType width, | 1015 ErrorCode::ArgType width, |
1017 ErrorCode::Operation op, | 1016 ErrorCode::Operation op, |
1018 uint64_t value, | 1017 uint64_t value, |
1019 const ErrorCode& passed, | 1018 const ErrorCode& passed, |
1020 const ErrorCode& failed) { | 1019 const ErrorCode& failed) { |
1021 return ErrorCode(argno, | 1020 return ErrorCode(argno, |
1022 width, | 1021 width, |
1023 op, | 1022 op, |
1024 value, | 1023 value, |
1025 &*conds_->insert(passed).first, | 1024 &*conds_->insert(passed).first, |
1026 &*conds_->insert(failed).first); | 1025 &*conds_->insert(failed).first); |
1027 } | 1026 } |
1028 | 1027 |
1029 ErrorCode SandboxBPF::Kill(const char* msg) { | 1028 ErrorCode SandboxBPF::Kill(const char* msg) { |
1030 return Trap(BPFFailure, const_cast<char*>(msg)); | 1029 return Trap(BPFFailure, const_cast<char*>(msg)); |
1031 } | 1030 } |
1032 | 1031 |
1033 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; | 1032 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; |
1034 | 1033 |
1035 } // namespace sandbox | 1034 } // namespace sandbox |
OLD | NEW |