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 <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 <sys/prctl.h> | 9 #include <sys/prctl.h> |
| 10 #include <sys/ptrace.h> |
9 #include <sys/syscall.h> | 11 #include <sys/syscall.h> |
10 #include <sys/time.h> | 12 #include <sys/time.h> |
11 #include <sys/types.h> | 13 #include <sys/types.h> |
12 #include <sys/utsname.h> | 14 #include <sys/utsname.h> |
13 #include <unistd.h> | 15 #include <unistd.h> |
14 | 16 |
15 #if defined(ANDROID) | 17 #if defined(ANDROID) |
16 // Work-around for buggy headers in Android's NDK | 18 // Work-around for buggy headers in Android's NDK |
17 #define __user | 19 #define __user |
18 #endif | 20 #endif |
19 #include <linux/futex.h> | 21 #include <linux/futex.h> |
20 | 22 |
21 #include <ostream> | 23 #include <ostream> |
22 | 24 |
23 #include "base/bind.h" | 25 #include "base/bind.h" |
24 #include "base/logging.h" | 26 #include "base/logging.h" |
25 #include "base/macros.h" | 27 #include "base/macros.h" |
26 #include "base/memory/scoped_ptr.h" | 28 #include "base/memory/scoped_ptr.h" |
| 29 #include "base/posix/eintr_wrapper.h" |
27 #include "build/build_config.h" | 30 #include "build/build_config.h" |
28 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 31 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
29 #include "sandbox/linux/seccomp-bpf/syscall.h" | 32 #include "sandbox/linux/seccomp-bpf/syscall.h" |
30 #include "sandbox/linux/seccomp-bpf/trap.h" | 33 #include "sandbox/linux/seccomp-bpf/trap.h" |
31 #include "sandbox/linux/seccomp-bpf/verifier.h" | 34 #include "sandbox/linux/seccomp-bpf/verifier.h" |
32 #include "sandbox/linux/services/broker_process.h" | 35 #include "sandbox/linux/services/broker_process.h" |
33 #include "sandbox/linux/services/linux_syscalls.h" | 36 #include "sandbox/linux/services/linux_syscalls.h" |
34 #include "sandbox/linux/tests/unit_tests.h" | 37 #include "sandbox/linux/tests/unit_tests.h" |
35 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
36 | 39 |
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 } | 1904 } |
1902 | 1905 |
1903 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { | 1906 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { |
1904 PthreadTest(); | 1907 PthreadTest(); |
1905 } | 1908 } |
1906 | 1909 |
1907 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { | 1910 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { |
1908 PthreadTest(); | 1911 PthreadTest(); |
1909 } | 1912 } |
1910 | 1913 |
| 1914 // libc might not define these even though the kernel supports it. |
| 1915 #ifndef PTRACE_O_TRACESECCOMP |
| 1916 #define PTRACE_O_TRACESECCOMP 0x00000080 |
| 1917 #endif |
| 1918 |
| 1919 #ifdef PTRACE_EVENT_SECCOMP |
| 1920 #define IS_SECCOMP_EVENT(status) ((status >> 16) == PTRACE_EVENT_SECCOMP) |
| 1921 #else |
| 1922 // When Debian/Ubuntu backported seccomp-bpf support into earlier kernels, they |
| 1923 // changed the value of PTRACE_EVENT_SECCOMP from 7 to 8, since 7 was taken by |
| 1924 // PTRACE_EVENT_STOP (upstream chose to renumber PTRACE_EVENT_STOP to 128). If |
| 1925 // PTRACE_EVENT_SECCOMP isn't defined, we have no choice but to consider both |
| 1926 // values here. |
| 1927 #define IS_SECCOMP_EVENT(status) ((status >> 16) == 7 || (status >> 16) == 8) |
| 1928 #endif |
| 1929 |
| 1930 const uint16_t kTraceData = 0xcc; |
| 1931 |
| 1932 class TraceAllPolicy : public SandboxBPFPolicy { |
| 1933 public: |
| 1934 TraceAllPolicy() {} |
| 1935 virtual ~TraceAllPolicy() {} |
| 1936 |
| 1937 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler, |
| 1938 int system_call_number) const OVERRIDE { |
| 1939 return ErrorCode(ErrorCode::ERR_TRACE + kTraceData); |
| 1940 } |
| 1941 |
| 1942 private: |
| 1943 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); |
| 1944 }; |
| 1945 |
| 1946 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { |
| 1947 if (SandboxBPF::SupportsSeccompSandbox(-1) != |
| 1948 sandbox::SandboxBPF::STATUS_AVAILABLE) { |
| 1949 return; |
| 1950 } |
| 1951 |
| 1952 pid_t pid = fork(); |
| 1953 BPF_ASSERT_NE(-1, pid); |
| 1954 if (pid == 0) { |
| 1955 pid_t my_pid = getpid(); |
| 1956 BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); |
| 1957 BPF_ASSERT_EQ(0, raise(SIGSTOP)); |
| 1958 SandboxBPF sandbox; |
| 1959 sandbox.SetSandboxPolicy(new TraceAllPolicy); |
| 1960 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
| 1961 |
| 1962 // getpid is allowed. |
| 1963 BPF_ASSERT_EQ(my_pid, syscall(__NR_getpid)); |
| 1964 |
| 1965 // write to stdout is skipped and returns a fake value. |
| 1966 BPF_ASSERT_EQ(kExpectedReturnValue, |
| 1967 syscall(__NR_write, STDOUT_FILENO, "A", 1)); |
| 1968 |
| 1969 // kill is rewritten to exit(kExpectedReturnValue). |
| 1970 syscall(__NR_kill, my_pid, SIGKILL); |
| 1971 |
| 1972 // Should not be reached. |
| 1973 BPF_ASSERT(false); |
| 1974 } |
| 1975 |
| 1976 int status; |
| 1977 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, WUNTRACED)) != -1); |
| 1978 BPF_ASSERT(WIFSTOPPED(status)); |
| 1979 |
| 1980 BPF_ASSERT_NE(-1, ptrace(PTRACE_SETOPTIONS, pid, NULL, |
| 1981 reinterpret_cast<void*>(PTRACE_O_TRACESECCOMP))); |
| 1982 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); |
| 1983 while (true) { |
| 1984 BPF_ASSERT(HANDLE_EINTR(waitpid(pid, &status, 0)) != -1); |
| 1985 if (WIFEXITED(status) || WIFSIGNALED(status)) { |
| 1986 BPF_ASSERT(WIFEXITED(status)); |
| 1987 BPF_ASSERT_EQ(kExpectedReturnValue, WEXITSTATUS(status)); |
| 1988 break; |
| 1989 } |
| 1990 |
| 1991 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP || |
| 1992 !IS_SECCOMP_EVENT(status)) { |
| 1993 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); |
| 1994 continue; |
| 1995 } |
| 1996 |
| 1997 unsigned long data; |
| 1998 BPF_ASSERT_NE(-1, ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data)); |
| 1999 BPF_ASSERT_EQ(kTraceData, data); |
| 2000 |
| 2001 regs_struct regs; |
| 2002 BPF_ASSERT_NE(-1, ptrace(PTRACE_GETREGS, pid, NULL, ®s)); |
| 2003 switch (SECCOMP_PT_SYSCALL(regs)) { |
| 2004 case __NR_write: |
| 2005 // Skip writes to stdout, make it return kExpectedReturnValue. Allow |
| 2006 // writes to stderr so that BPF_ASSERT messages show up. |
| 2007 if (SECCOMP_PT_PARM1(regs) == STDOUT_FILENO) { |
| 2008 SECCOMP_PT_SYSCALL(regs) = -1; |
| 2009 SECCOMP_PT_RESULT(regs) = kExpectedReturnValue; |
| 2010 BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, ®s)); |
| 2011 } |
| 2012 break; |
| 2013 |
| 2014 case __NR_kill: |
| 2015 // Rewrite to exit(kExpectedReturnValue). |
| 2016 SECCOMP_PT_SYSCALL(regs) = __NR_exit; |
| 2017 SECCOMP_PT_PARM1(regs) = kExpectedReturnValue; |
| 2018 BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, ®s)); |
| 2019 break; |
| 2020 |
| 2021 default: |
| 2022 // Allow all other syscalls. |
| 2023 break; |
| 2024 } |
| 2025 |
| 2026 BPF_ASSERT_NE(-1, ptrace(PTRACE_CONT, pid, NULL, NULL)); |
| 2027 } |
| 2028 } |
| 2029 |
1911 } // namespace | 2030 } // namespace |
1912 | 2031 |
1913 } // namespace sandbox | 2032 } // namespace sandbox |
OLD | NEW |