summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2021-12-01 00:08:00 +0000
committerDmitry V. Levin <ldv@strace.io>2021-12-01 00:08:00 +0000
commite01665f3df44d8a77f26333b5ed67c40db9e1126 (patch)
treee3e0cae2b8c2348637934d36b9daff7e9d733867
parentec1cfe685f86f14fbb3bd62954bd31f2d1b3aabf (diff)
downloadstrace-e01665f3df44d8a77f26333b5ed67c40db9e1126.tar.gz
upoken: workaround buggy process_vm_writev
The upoken implementation assumed that process_vm_writev could perform partial writes, but in older Linux kernel versions (my guess is in Linux before v3.15) process_vm_writev could not do partial writes properly. * src/ucopy.c (upoken): Fall back to upoken_pokedata when process_vm_writev fails with EFAULT or EIO.
-rw-r--r--src/ucopy.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/src/ucopy.c b/src/ucopy.c
index 072d299a0..c769a1916 100644
--- a/src/ucopy.c
+++ b/src/ucopy.c
@@ -575,16 +575,13 @@ upoken(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
return (unsigned int) r;
}
switch (errno) {
- case ENOSYS:
- case EPERM:
+ case ENOSYS: case EPERM: /* could not use process_vm_writev */
+ case EFAULT: case EIO: /* address space is inaccessible */
/* try PTRACE_POKEDATA */
return upoken_pokedata(pid, addr, len, our_addr);
case ESRCH:
/* the process is gone */
return 0;
- case EFAULT: case EIO:
- /* address space is inaccessible */
- return 0;
default:
/* all the rest is strange and should be reported */
perror_func_msg("pid:%d @0x%" PRI_klx, pid, addr);