summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorrickyz@google.com <rickyz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 21:41:54 +0000
committerrickyz@google.com <rickyz@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 21:41:54 +0000
commit003b2a2daa2e3deb7f9dff57a464838a4d22e96f (patch)
tree3a73906ee598f444e98c6f312d80ffe62207a6eb /sandbox
parentc1e05801d3942d07cc5639b553cf5125418ff5db (diff)
downloadchromium_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.cc36
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, &regs, -1));
SECCOMP_PT_RESULT(regs) = kExpectedReturnValue;
BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, &regs));
}
@@ -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, &regs, __NR_exit));
SECCOMP_PT_PARM1(regs) = kExpectedReturnValue;
BPF_ASSERT_NE(-1, ptrace(PTRACE_SETREGS, pid, NULL, &regs));
break;