diff options
author | Dmitry V. Levin <ldv@strace.io> | 2021-12-01 00:08:00 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2021-12-01 00:08:00 +0000 |
commit | e01665f3df44d8a77f26333b5ed67c40db9e1126 (patch) | |
tree | e3e0cae2b8c2348637934d36b9daff7e9d733867 | |
parent | ec1cfe685f86f14fbb3bd62954bd31f2d1b3aabf (diff) | |
download | strace-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.c | 7 |
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); |