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

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

Issue 278583005: Linux Sandbox: Add support for SECCOMP_RET_TRACE. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix LOG(FATAL) behavior on Android. Created 6 years, 6 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/seccomp-bpf/linux_seccomp.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 <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
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, &regs));
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, &regs));
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, &regs));
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
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/linux_seccomp.h ('k') | sandbox/linux/seccomp-bpf/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698