aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libsandbox')
-rw-r--r--libsandbox/trace.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 47d2bdf..99ef8cd 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -93,10 +93,14 @@ static char *do_peekstr(unsigned long lptr)
#ifdef HAVE_PROCESS_VM_READV
struct iovec liov, riov;
- /* We can't cross remote page boundaries when using this :( */
+ /* We can't cross remote page boundaries when using this :(.
+ * The first call reads up to the edge of the page boundary since we
+ * have no (easy) way of knowing if the next page is valid. This is
+ * less effort than reading in the /proc/.../maps file and walking it.
+ */
l = 0x1000;
riov.iov_base = (void *)lptr;
- len = lptr % l;
+ len = l - (lptr % l);
if (!len)
len = l;
liov.iov_base = ret = xmalloc(len);
@@ -105,27 +109,23 @@ static char *do_peekstr(unsigned long lptr)
while (1) {
if (process_vm_readv(trace_pid, &liov, 1, &riov, 1, 0) == -1) {
int e = errno;
- if (e == ENOSYS)
+ if (e == ENOSYS) {
+ /* This can happen if run on older kernels but built with newer ones. */
+ break;
+ } else if (e == EFAULT) {
+ /* This can happen if the target process uses a bad pointer. #560396 */
break;
- sb_eqawarn("process_vm_readv(%i, %p{%p, %zu}, 1, %p{%p, %zu}, 1, 0) failed: %s\n",
+ }
+ sb_ebort("ISE:do_peekstr:process_vm_readv(%i, %p{%p, %#zx}, 1, %p{%p, %#zx}, 1, 0) failed: %s\n",
trace_pid,
&liov, liov.iov_base, liov.iov_len,
&riov, riov.iov_base, riov.iov_len,
strerror(e));
- if (e == EFAULT) {
- /* This sometimes happens, but it's not clear why.
- * Throw some extended debugging info before falling
- * back to the ptrace code. #560396
- */
- break;
- }
- sb_ebort("ISE:do_peekstr: process_vm_readv() hates us: %s\n",
- strerror(e));
}
if (memchr(liov.iov_base, '\0', liov.iov_len) != NULL)
return ret;
- riov.iov_base += l;
+ riov.iov_base += riov.iov_len;
riov.iov_len = liov.iov_len = l;
len += l;
ret = xrealloc(ret, len);