From b2893c9e9e84e51d6e11ddae7c6908bb707ddbb2 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 30 Mar 2015 15:21:55 +0000 Subject: [PATCH] When process_vm_readv fails with EPERM, try PTRACE_PEEKDATA process_vm_readv() and ptrace(PTRACE_PEEKDATA) have inconsistent access control rules wrt traced processes: process_vm_readv() is more likely to fail with EPERM than ptrace(PTRACE_PEEKDATA) when tracing a process that has execve'd a privileged executable. * util.c (umoven, umovestr): If process_vm_readv returned EPERM, fall back to ptrace(PTRACE_PEEKDATA). Reported-by: Andrew Guertin --- util.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/util.c b/util.c index fd9053a5..1bec3c23 100644 --- a/util.c +++ b/util.c @@ -1003,10 +1003,13 @@ umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr) case ENOSYS: process_vm_readv_not_supported = 1; break; + case EPERM: + /* operation not permitted, try PTRACE_PEEKDATA */ + break; case ESRCH: /* the process is gone */ return -1; - case EFAULT: case EIO: case EPERM: + case EFAULT: case EIO: /* address space is inaccessible */ return -1; default: @@ -1158,7 +1161,12 @@ umovestr(struct tcb *tcp, long addr, unsigned int len, char *laddr) case ESRCH: /* the process is gone */ return -1; - case EFAULT: case EIO: case EPERM: + case EPERM: + /* operation not permitted, try PTRACE_PEEKDATA */ + if (!nread) + goto vm_readv_didnt_work; + /* fall through */ + case EFAULT: case EIO: /* address space is inaccessible */ if (nread) { perror_msg("umovestr: short read (%d < %d) @0x%lx", -- 2.40.0