diff options
author | rickyz@google.com <rickyz@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-13 21:41:54 +0000 |
---|---|---|
committer | rickyz@google.com <rickyz@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-13 21:41:54 +0000 |
commit | 003b2a2daa2e3deb7f9dff57a464838a4d22e96f (patch) | |
tree | 3a73906ee598f444e98c6f312d80ffe62207a6eb /sandbox | |
parent | c1e05801d3942d07cc5639b553cf5125418ff5db (diff) | |
download | chromium_src-003b2a2daa2e3deb7f9dff57a464838a4d22e96f.zip chromium_src-003b2a2daa2e3deb7f9dff57a464838a4d22e96f.tar.gz chromium_src-003b2a2daa2e3deb7f9dff57a464838a4d22e96f.tar.bz2 |
Use PTRACE_SET_SYSCALL to override syscalls on ARM.
Unfortunately, this change also disables the test on ARM due to a bug
which prevents syscalls from being overriden on ARM (see
crbug.com/383977 for details). This should fix ARM chrome tests, which
were broken in r276595.
BUG=383977
Review URL: https://codereview.chromium.org/331833002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277089 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc index 9f02602..06ba209 100644 --- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc @@ -1927,6 +1927,33 @@ BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { #define IS_SECCOMP_EVENT(status) ((status >> 16) == 7 || (status >> 16) == 8) #endif +#if defined(__arm__) +#ifndef PTRACE_SET_SYSCALL +#define PTRACE_SET_SYSCALL 23 +#endif +#endif + +// Changes the syscall to run for a child being sandboxed using seccomp-bpf with +// PTRACE_O_TRACESECCOMP. Should only be called when the child is stopped on +// PTRACE_EVENT_SECCOMP. +// +// regs should contain the current set of registers of the child, obtained using +// PTRACE_GETREGS. +// +// Depending on the architecture, this may modify regs, so the caller is +// responsible for committing these changes using PTRACE_SETREGS. +long SetSyscall(pid_t pid, regs_struct* regs, int syscall_number) { +#if defined(__arm__) + // On ARM, the syscall is changed using PTRACE_SET_SYSCALL. We cannot use the + // libc ptrace call as the request parameter is an enum, and + // PTRACE_SET_SYSCALL may not be in the enum. + return syscall(__NR_ptrace, PTRACE_SET_SYSCALL, pid, NULL, syscall_number); +#endif + + SECCOMP_PT_SYSCALL(*regs) = syscall_number; + return 0; +} + const uint16_t kTraceData = 0xcc; class TraceAllPolicy : public SandboxBPFPolicy { @@ -1949,6 +1976,11 @@ SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { return; } +#if defined(__arm__) + printf("This test is currently disabled on ARM due to a kernel bug."); + return; +#endif + pid_t pid = fork(); BPF_ASSERT_NE(-1, pid); if (pid == 0) { @@ -2005,7 +2037,7 @@ SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { // Skip writes to stdout, make it return kExpectedReturnValue. Allow // writes to stderr so that BPF_ASSERT messages show up. if (SECCOMP_PT_PARM1(regs) == STDOUT_FILENO) { - SECCOMP_PT_SYSCALL(regs) = -1; + BPF_ASSERT_NE(-1, SetSyscall(pid, ®s, -1)); SECCOMP_PT_RESULT(regs) = kExpectedReturnValue; BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, ®s)); } @@ -2013,7 +2045,7 @@ SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { case __NR_kill: // Rewrite to exit(kExpectedReturnValue). - SECCOMP_PT_SYSCALL(regs) = __NR_exit; + BPF_ASSERT_NE(-1, SetSyscall(pid, ®s, __NR_exit)); SECCOMP_PT_PARM1(regs) = kExpectedReturnValue; BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, ®s)); break; |