]> granicus.if.org Git - strace/commitdiff
When process_vm_readv fails with EPERM, try PTRACE_PEEKDATA
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 30 Mar 2015 15:21:55 +0000 (15:21 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 31 Mar 2015 15:06:01 +0000 (15:06 +0000)
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 <lists@dolphinling.net>
util.c

diff --git a/util.c b/util.c
index fd9053a529c5cd1d03b458b621692e30d18961a2..1bec3c23cda1064ceeb8d63ea6e86c13c1fa9f4e 100644 (file)
--- 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",