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

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

Issue 487143003: sandbox: Add Arm64 support for seccomp-BPF (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Codereview fixes Created 6 years, 4 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 | Annotate | Revision Log
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 <errno.h> 5 #include <errno.h>
6 #include <pthread.h> 6 #include <pthread.h>
7 #include <sched.h> 7 #include <sched.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <sys/prctl.h> 9 #include <sys/prctl.h>
10 #include <sys/ptrace.h> 10 #include <sys/ptrace.h>
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE; 241 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE;
242 242
243 private: 243 private:
244 DISALLOW_COPY_AND_ASSIGN(ErrnoTestPolicy); 244 DISALLOW_COPY_AND_ASSIGN(ErrnoTestPolicy);
245 }; 245 };
246 246
247 ErrorCode ErrnoTestPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { 247 ErrorCode ErrnoTestPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const {
248 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); 248 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
249 switch (sysno) { 249 switch (sysno) {
250 case __NR_dup3: // dup2 is a wrapper of dup3 in android 250 case __NR_dup3: // dup2 is a wrapper of dup3 in android
251 #if defined(__NR_dup2)
251 case __NR_dup2: 252 case __NR_dup2:
253 #endif
252 // Pretend that dup2() worked, but don't actually do anything. 254 // Pretend that dup2() worked, but don't actually do anything.
253 return ErrorCode(0); 255 return ErrorCode(0);
254 case __NR_setuid: 256 case __NR_setuid:
255 #if defined(__NR_setuid32) 257 #if defined(__NR_setuid32)
256 case __NR_setuid32: 258 case __NR_setuid32:
257 #endif 259 #endif
258 // Return errno = 1. 260 // Return errno = 1.
259 return ErrorCode(1); 261 return ErrorCode(1);
260 case __NR_setgid: 262 case __NR_setgid:
261 #if defined(__NR_setgid32) 263 #if defined(__NR_setgid32)
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 757
756 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, 758 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args,
757 void* aux) { 759 void* aux) {
758 BPF_ASSERT(aux); 760 BPF_ASSERT(aux);
759 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); 761 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux);
760 switch (args.nr) { 762 switch (args.nr) {
761 case __NR_faccessat: // access is a wrapper of faccessat in android 763 case __NR_faccessat: // access is a wrapper of faccessat in android
762 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); 764 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
763 return broker_process->Access(reinterpret_cast<const char*>(args.args[1]), 765 return broker_process->Access(reinterpret_cast<const char*>(args.args[1]),
764 static_cast<int>(args.args[2])); 766 static_cast<int>(args.args[2]));
767 #if defined(__NR_access)
765 case __NR_access: 768 case __NR_access:
766 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), 769 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
767 static_cast<int>(args.args[1])); 770 static_cast<int>(args.args[1]));
771 #endif
772 #if defined(__NR_open)
768 case __NR_open: 773 case __NR_open:
769 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), 774 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
770 static_cast<int>(args.args[1])); 775 static_cast<int>(args.args[1]));
776 #endif
771 case __NR_openat: 777 case __NR_openat:
772 // We only call open() so if we arrive here, it's because glibc uses 778 // We only call open() so if we arrive here, it's because glibc uses
773 // the openat() system call. 779 // the openat() system call.
774 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); 780 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
775 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), 781 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
776 static_cast<int>(args.args[2])); 782 static_cast<int>(args.args[2]));
777 default: 783 default:
778 BPF_ASSERT(false); 784 BPF_ASSERT(false);
779 return -ENOSYS; 785 return -ENOSYS;
780 } 786 }
781 } 787 }
782 788
783 ErrorCode DenyOpenPolicy(SandboxBPF* sandbox, 789 ErrorCode DenyOpenPolicy(SandboxBPF* sandbox,
784 int sysno, 790 int sysno,
785 InitializedOpenBroker* iob) { 791 InitializedOpenBroker* iob) {
786 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { 792 if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
787 return ErrorCode(ENOSYS); 793 return ErrorCode(ENOSYS);
788 } 794 }
789 795
790 switch (sysno) { 796 switch (sysno) {
791 case __NR_faccessat: 797 case __NR_faccessat:
798 #if defined(__NR_access)
792 case __NR_access: 799 case __NR_access:
800 #endif
801 #if defined(__NR_open)
793 case __NR_open: 802 case __NR_open:
803 #endif
794 case __NR_openat: 804 case __NR_openat:
795 // We get a InitializedOpenBroker class, but our trap handler wants 805 // We get a InitializedOpenBroker class, but our trap handler wants
796 // the BrokerProcess object. 806 // the BrokerProcess object.
797 return ErrorCode( 807 return ErrorCode(
798 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process())); 808 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process()));
799 default: 809 default:
800 return ErrorCode(ErrorCode::ERR_ALLOWED); 810 return ErrorCode(ErrorCode::ERR_ALLOWED);
801 } 811 }
802 } 812 }
803 813
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 872
863 ErrorCode SimpleCondTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, 873 ErrorCode SimpleCondTestPolicy::EvaluateSyscall(SandboxBPF* sandbox,
864 int sysno) const { 874 int sysno) const {
865 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); 875 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
866 876
867 // We deliberately return unusual errno values upon failure, so that we 877 // We deliberately return unusual errno values upon failure, so that we
868 // can uniquely test for these values. In a "real" policy, you would want 878 // can uniquely test for these values. In a "real" policy, you would want
869 // to return more traditional values. 879 // to return more traditional values.
870 int flags_argument_position = -1; 880 int flags_argument_position = -1;
871 switch (sysno) { 881 switch (sysno) {
882 #if defined(__NR_open)
872 case __NR_open: 883 case __NR_open:
884 flags_argument_position = 1;
885 #endif
873 case __NR_openat: // open can be a wrapper for openat(2). 886 case __NR_openat: // open can be a wrapper for openat(2).
874 if (sysno == __NR_open) { 887 if (sysno == __NR_openat)
875 flags_argument_position = 1;
876 } else if (sysno == __NR_openat) {
877 flags_argument_position = 2; 888 flags_argument_position = 2;
878 } 889
879 // Allow opening files for reading, but don't allow writing. 890 // Allow opening files for reading, but don't allow writing.
880 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); 891 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits);
881 return sandbox->Cond(flags_argument_position, 892 return sandbox->Cond(flags_argument_position,
882 ErrorCode::TP_32BIT, 893 ErrorCode::TP_32BIT,
883 ErrorCode::OP_HAS_ANY_BITS, 894 ErrorCode::OP_HAS_ANY_BITS,
884 O_ACCMODE /* 0x3 */, 895 O_ACCMODE /* 0x3 */,
885 ErrorCode(EROFS), 896 ErrorCode(EROFS),
886 ErrorCode(ErrorCode::ERR_ALLOWED)); 897 ErrorCode(ErrorCode::ERR_ALLOWED));
887 case __NR_prctl: 898 case __NR_prctl:
888 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but 899 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 -err); 1217 -err);
1207 } 1218 }
1208 1219
1209 // Vector of ArgValue trees. These trees define all the possible boolean 1220 // Vector of ArgValue trees. These trees define all the possible boolean
1210 // expressions that we want to turn into a BPF filter program. 1221 // expressions that we want to turn into a BPF filter program.
1211 std::vector<ArgValue*> arg_values_; 1222 std::vector<ArgValue*> arg_values_;
1212 1223
1213 // Don't increase these values. We are pushing the limits of the maximum 1224 // Don't increase these values. We are pushing the limits of the maximum
1214 // BPF program that the kernel will allow us to load. If the values are 1225 // BPF program that the kernel will allow us to load. If the values are
1215 // increased too much, the test will start failing. 1226 // increased too much, the test will start failing.
1227 #if defined(__aarch64__)
1228 static const int kNumTestCases = 30;
jln (very slow on Chromium) 2014/08/22 20:11:30 Did you figure out what was happening btw? CodeGe
leecam 2014/08/24 22:11:58 I'm still looking into this one but I don't think
1229 #else
1216 static const int kNumTestCases = 40; 1230 static const int kNumTestCases = 40;
1231 #endif
1217 static const int kMaxFanOut = 3; 1232 static const int kMaxFanOut = 3;
1218 static const int kMaxArgs = 6; 1233 static const int kMaxArgs = 6;
1219 }; 1234 };
1220 1235
1221 ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox, 1236 ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox,
1222 int sysno, 1237 int sysno,
1223 EqualityStressTest* aux) { 1238 EqualityStressTest* aux) {
1224 DCHECK(aux); 1239 DCHECK(aux);
1225 return aux->Policy(sandbox, sysno); 1240 return aux->Policy(sandbox, sysno);
1226 } 1241 }
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1923 // values here. 1938 // values here.
1924 #define IS_SECCOMP_EVENT(status) ((status >> 16) == 7 || (status >> 16) == 8) 1939 #define IS_SECCOMP_EVENT(status) ((status >> 16) == 7 || (status >> 16) == 8)
1925 #endif 1940 #endif
1926 1941
1927 #if defined(__arm__) 1942 #if defined(__arm__)
1928 #ifndef PTRACE_SET_SYSCALL 1943 #ifndef PTRACE_SET_SYSCALL
1929 #define PTRACE_SET_SYSCALL 23 1944 #define PTRACE_SET_SYSCALL 23
1930 #endif 1945 #endif
1931 #endif 1946 #endif
1932 1947
1948 #if defined(__aarch64__)
1949 #ifndef PTRACE_GETREGS
1950 #define PTRACE_GETREGS 12
1951 #endif
1952 #endif
1953
1954 #if defined(__aarch64__)
1955 #ifndef PTRACE_SETREGS
1956 #define PTRACE_SETREGS 13
1957 #endif
1958 #endif
1959
1933 // Changes the syscall to run for a child being sandboxed using seccomp-bpf with 1960 // Changes the syscall to run for a child being sandboxed using seccomp-bpf with
1934 // PTRACE_O_TRACESECCOMP. Should only be called when the child is stopped on 1961 // PTRACE_O_TRACESECCOMP. Should only be called when the child is stopped on
1935 // PTRACE_EVENT_SECCOMP. 1962 // PTRACE_EVENT_SECCOMP.
1936 // 1963 //
1937 // regs should contain the current set of registers of the child, obtained using 1964 // regs should contain the current set of registers of the child, obtained using
1938 // PTRACE_GETREGS. 1965 // PTRACE_GETREGS.
1939 // 1966 //
1940 // Depending on the architecture, this may modify regs, so the caller is 1967 // Depending on the architecture, this may modify regs, so the caller is
1941 // responsible for committing these changes using PTRACE_SETREGS. 1968 // responsible for committing these changes using PTRACE_SETREGS.
1942 long SetSyscall(pid_t pid, regs_struct* regs, int syscall_number) { 1969 long SetSyscall(pid_t pid, regs_struct* regs, int syscall_number) {
(...skipping 23 matching lines...) Expand all
1966 private: 1993 private:
1967 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); 1994 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy);
1968 }; 1995 };
1969 1996
1970 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { 1997 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) {
1971 if (SandboxBPF::SupportsSeccompSandbox(-1) != 1998 if (SandboxBPF::SupportsSeccompSandbox(-1) !=
1972 sandbox::SandboxBPF::STATUS_AVAILABLE) { 1999 sandbox::SandboxBPF::STATUS_AVAILABLE) {
1973 return; 2000 return;
1974 } 2001 }
1975 2002
2003 // The following tests are disabled due to a kernel bug.
jln (very slow on Chromium) 2014/08/22 20:11:30 You mean "The current test"?
leecam 2014/08/24 22:11:57 Yep ;-)
2004 // See https://code.google.com/p/chromium/issues/detail?id=383977
1976 #if defined(__arm__) 2005 #if defined(__arm__)
jln (very slow on Chromium) 2014/08/22 20:11:30 You could probably just || (__aarch64__) here, wit
leecam 2014/08/24 22:11:58 Done.
1977 printf("This test is currently disabled on ARM due to a kernel bug."); 2006 printf("This test is currently disabled on ARM due to a kernel bug.");
1978 return; 2007 return;
1979 #endif 2008 #endif
1980 2009
2010 #if defined(__aarch64__)
2011 printf("This test is currently disabled on ARM64..");
2012 return;
2013 #endif
2014
1981 #if defined(__mips__) 2015 #if defined(__mips__)
1982 // TODO: Figure out how to support specificity of handling indirect syscalls 2016 // TODO: Figure out how to support specificity of handling indirect syscalls
1983 // in this test and enable it. 2017 // in this test and enable it.
1984 printf("This test is currently disabled on MIPS."); 2018 printf("This test is currently disabled on MIPS.");
1985 return; 2019 return;
1986 #endif 2020 #endif
1987 2021
1988 pid_t pid = fork(); 2022 pid_t pid = fork();
1989 BPF_ASSERT_NE(-1, pid); 2023 BPF_ASSERT_NE(-1, pid);
1990 if (pid == 0) { 2024 if (pid == 0) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 kLargeOffset)); 2175 kLargeOffset));
2142 BPF_ASSERT_EQ(0, memcmp(kTestString, read_test_string, sizeof(kTestString))); 2176 BPF_ASSERT_EQ(0, memcmp(kTestString, read_test_string, sizeof(kTestString)));
2143 BPF_ASSERT(pread_64_was_forwarded); 2177 BPF_ASSERT(pread_64_was_forwarded);
2144 } 2178 }
2145 2179
2146 #endif // !defined(OS_ANDROID) 2180 #endif // !defined(OS_ANDROID)
2147 2181
2148 } // namespace 2182 } // namespace
2149 2183
2150 } // namespace sandbox 2184 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698