mirror of
https://github.com/python/cpython.git
synced 2025-07-12 05:45:15 +00:00
[3.14] gh-134876: Add fallback for when process_vm_readv fails with ENOSYS (GH-134878) (#135240)
gh-134876: Add fallback for when process_vm_readv fails with ENOSYS (GH-134878)
(cherry picked from commit ac9c3431cc
)
Co-authored-by: Daniel Golding <goldingd89@gmail.com>
This commit is contained in:
parent
3faf00e003
commit
ef539654e6
4 changed files with 112 additions and 0 deletions
|
@ -24,6 +24,39 @@ read_memory(proc_handle_t *handle, uint64_t remote_address, size_t len, void* ds
|
|||
return _Py_RemoteDebug_ReadRemoteMemory(handle, remote_address, len, dst);
|
||||
}
|
||||
|
||||
// Why is pwritev not guarded? Except on Android API level 23 (no longer
|
||||
// supported), HAVE_PROCESS_VM_READV is sufficient.
|
||||
#if defined(__linux__) && HAVE_PROCESS_VM_READV
|
||||
static int
|
||||
write_memory_fallback(proc_handle_t *handle, uintptr_t remote_address, size_t len, const void* src)
|
||||
{
|
||||
if (handle->memfd == -1) {
|
||||
if (open_proc_mem_fd(handle) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
struct iovec local[1];
|
||||
Py_ssize_t result = 0;
|
||||
Py_ssize_t written = 0;
|
||||
|
||||
do {
|
||||
local[0].iov_base = (char*)src + result;
|
||||
local[0].iov_len = len - result;
|
||||
off_t offset = remote_address + result;
|
||||
|
||||
written = pwritev(handle->memfd, local, 1, offset);
|
||||
if (written < 0) {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result += written;
|
||||
} while ((size_t)written != local[0].iov_len);
|
||||
return 0;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
static int
|
||||
write_memory(proc_handle_t *handle, uintptr_t remote_address, size_t len, const void* src)
|
||||
{
|
||||
|
@ -39,6 +72,9 @@ write_memory(proc_handle_t *handle, uintptr_t remote_address, size_t len, const
|
|||
} while (result < len);
|
||||
return 0;
|
||||
#elif defined(__linux__) && HAVE_PROCESS_VM_READV
|
||||
if (handle->memfd != -1) {
|
||||
return write_memory_fallback(handle, remote_address, len, src);
|
||||
}
|
||||
struct iovec local[1];
|
||||
struct iovec remote[1];
|
||||
Py_ssize_t result = 0;
|
||||
|
@ -52,6 +88,9 @@ write_memory(proc_handle_t *handle, uintptr_t remote_address, size_t len, const
|
|||
|
||||
written = process_vm_writev(handle->pid, local, 1, remote, 1, 0);
|
||||
if (written < 0) {
|
||||
if (errno == ENOSYS) {
|
||||
return write_memory_fallback(handle, remote_address, len, src);
|
||||
}
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue