summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-29 17:59:45 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-29 17:59:45 +0000
commit3ee98e37856935ac1d79d51364df73ce00d8218e (patch)
tree57cdceafc052991ccc984efdba067503fe3f8759
parent3f8ce73999c1ef82a8a835e9e87b0d4ce8c5810b (diff)
downloadcompiler-rt-3ee98e37856935ac1d79d51364df73ce00d8218e.tar.gz
compiler-rt-3ee98e37856935ac1d79d51364df73ce00d8218e.tar.bz2
compiler-rt-3ee98e37856935ac1d79d51364df73ce00d8218e.tar.xz
[sanitizer] Ptrace syscall handler.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193633 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/lit_tests/Linux/syscalls.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_common_syscalls.inc40
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc3
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h3
4 files changed, 49 insertions, 2 deletions
diff --git a/lib/msan/lit_tests/Linux/syscalls.cc b/lib/msan/lit_tests/Linux/syscalls.cc
index 962fba3e..797832d8 100644
--- a/lib/msan/lit_tests/Linux/syscalls.cc
+++ b/lib/msan/lit_tests/Linux/syscalls.cc
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <string.h>
+#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sanitizer/linux_syscall_hooks.h>
@@ -76,6 +77,10 @@ int main(int argc, char *argv[]) {
__sanitizer_syscall_post_mq_timedreceive(kFortyTwo, 5, buf, sizeof(buf), &prio, 0);
assert(__msan_test_shadow(buf, sizeof(buf)) == kFortyTwo);
assert(__msan_test_shadow(&prio, sizeof(prio)) == -1);
+
+ __msan_poison(buf, sizeof(buf));
+ __sanitizer_syscall_post_ptrace(0, PTRACE_PEEKUSER, kFortyTwo, 0xABCD, buf);
+ assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(void *));
return 0;
}
diff --git a/lib/sanitizer_common/sanitizer_common_syscalls.inc b/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 0f500d63..baa1d5be 100644
--- a/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2218,9 +2218,45 @@ PRE_SYSCALL(ni_syscall)() {}
POST_SYSCALL(ni_syscall)(long res) {}
-PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {}
+PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
+ if (data) {
+ if (request == ptrace_setregs) {
+ PRE_READ((void *)data, struct_user_regs_struct_sz);
+ } else if (request == ptrace_setfpregs) {
+ PRE_READ((void *)data, struct_user_fpregs_struct_sz);
+ } else if (request == ptrace_setfpxregs) {
+ PRE_READ((void *)data, struct_user_fpxregs_struct_sz);
+ } else if (request == ptrace_setsiginfo) {
+ PRE_READ((void *)data, siginfo_t_sz);
+ } else if (request == ptrace_setregset) {
+ __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
+ PRE_READ(iov->iov_base, iov->iov_len);
+ }
+ }
+}
-POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {}
+POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
+ if (res >= 0 && data) {
+ // Note that this is different from the interceptor in
+ // sanitizer_common_interceptors.inc.
+ // PEEK* requests return resulting values through data pointer.
+ if (request == ptrace_getregs) {
+ POST_WRITE((void *)data, struct_user_regs_struct_sz);
+ } else if (request == ptrace_getfpregs) {
+ POST_WRITE((void *)data, struct_user_fpregs_struct_sz);
+ } else if (request == ptrace_getfpxregs) {
+ POST_WRITE((void *)data, struct_user_fpxregs_struct_sz);
+ } else if (request == ptrace_getsiginfo) {
+ POST_WRITE((void *)data, siginfo_t_sz);
+ } else if (request == ptrace_getregset) {
+ __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
+ POST_WRITE(iov->iov_base, iov->iov_len);
+ } else if (request == ptrace_peekdata || request == ptrace_peektext ||
+ request == ptrace_peekuser) {
+ POST_WRITE((void *)data, sizeof(void *));
+ }
+ }
+}
PRE_SYSCALL(add_key)(const void *_type, const void *_description,
const void *_payload, long plen, long destringid) {
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index fb932bc1..8276a969 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -218,6 +218,9 @@ namespace __sanitizer {
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
#endif
+ int ptrace_peektext = PTRACE_PEEKTEXT;
+ int ptrace_peekdata = PTRACE_PEEKDATA;
+ int ptrace_peekuser = PTRACE_PEEKUSER;
int ptrace_getregs = PTRACE_GETREGS;
int ptrace_setregs = PTRACE_SETREGS;
int ptrace_getfpregs = PTRACE_GETFPREGS;
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 0b38d158..6f27ba44 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -379,6 +379,9 @@ namespace __sanitizer {
extern unsigned struct_user_fpregs_struct_sz;
extern unsigned struct_user_fpxregs_struct_sz;
+ extern int ptrace_peektext;
+ extern int ptrace_peekdata;
+ extern int ptrace_peekuser;
extern int ptrace_getregs;
extern int ptrace_setregs;
extern int ptrace_getfpregs;