Skip to content

Commit 2e93eab

Browse files
committed
ptrace_readv_string: properly handle reads of more than one page
When the "intercept" and "intercept_verify" options are enabled and either argv[] or envp[] contains a string larger than the page size (usually 4096), ptrace_readv_string() would fill the buffer with mutiple copies of the same string. Fixes GitHub issue #453.
1 parent fb208d3 commit 2e93eab

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/exec_ptrace.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ ptrace_readv_string(pid_t pid, unsigned long addr, char *buf, size_t bufsize)
387387
(unsigned long)remote.iov_base, remote.iov_len);
388388
debug_return_ssize_t(-1);
389389
case 0:
390-
sudo_debug_printf(
391-
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
390+
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
392391
"process_vm_readv(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0): %s",
393392
(int)pid, (unsigned long)local.iov_base, local.iov_len,
394393
(unsigned long)remote.iov_base, remote.iov_len, "premature EOF");
@@ -398,9 +397,17 @@ ptrace_readv_string(pid_t pid, unsigned long addr, char *buf, size_t bufsize)
398397
cp = memchr(buf, '\0', (size_t)nread);
399398
if (cp != NULL)
400399
debug_return_ssize_t((cp - buf0) + 1); /* includes NUL */
400+
/* No NUL terminator, we should have a full page. */
401+
if (nread != page_size) {
402+
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
403+
"process_vm_readv(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0)"
404+
" -> %zd",
405+
(int)pid, (unsigned long)local.iov_base, local.iov_len,
406+
(unsigned long)remote.iov_base, remote.iov_len, nread);
407+
}
401408
buf += nread;
402409
bufsize -= (size_t)nread;
403-
addr += sizeof(unsigned long);
410+
addr += (size_t)nread;
404411
break;
405412
}
406413
}

0 commit comments

Comments
 (0)