]> granicus.if.org Git - strace/commitdiff
Don\'t run off end of memory in umovestr when USE_PROCFS
authorJohn Hughes <john@Calva.COM>
Tue, 15 May 2001 14:53:43 +0000 (14:53 +0000)
committerJohn Hughes <john@Calva.COM>
Tue, 15 May 2001 14:53:43 +0000 (14:53 +0000)
ChangeLog
util.c

index 2d44a465120c148badd4db642b067ab68a68dde6..86c65dacc88000caa13d2a2a3ee97b60fd622447 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2001-05-15  John Hughes <john@Calva.COM>
+
+  * util.c: Don't run off the end of valid memory in umovestr when
+    USE_PROCFS.  Important for FREEBSD systems (which seem to have an
+    unmapped page just after the args/env area).
+
 2001-04-18  John Hughes <john@Calva.COM>
 
   * configure.in: test for sys/nscsys.h, the non-stop clusters includes.
diff --git a/util.c b/util.c
index 19a24e48139583d062a33757bdcfbeec7c25ee68..529114241e5ca09a2c06cda4ad946b26b0ea9e39 100644 (file)
--- a/util.c
+++ b/util.c
@@ -632,25 +632,13 @@ char *laddr;
 
 #ifdef USE_PROCFS
 #ifdef HAVE_MP_PROCFS
-       if (pread(tcp->pfd_as, laddr, len, addr) == -1)
-               return -1;
+       int fd = tcp->pfd_as;
 #else
-/*
- * We would like to use pread preferentially for speed
- * but even though SGI has it in their library, it no longer works.
- */
-#ifdef MIPS
-#undef HAVE_PREAD
+       int fd = tcp->pfd;
 #endif
-#ifdef HAVE_PREAD
-       if (pread(tcp->pfd, laddr, len, addr) == -1)
+       lseek(fd, addr, SEEK_SET);
+       if (read(fd, laddr, len) == -1)
                return -1;
-#else /* !HAVE_PREAD */
-       lseek(tcp->pfd, addr, SEEK_SET);
-       if (read(tcp->pfd, laddr, len) == -1)
-               return -1;
-#endif /* !HAVE_PREAD */
-#endif /* HAVE_MP_PROCFS */
 #endif /* USE_PROCFS */
 
        return 0;
@@ -668,7 +656,34 @@ int len;
 char *laddr;
 {
 #ifdef USE_PROCFS
-       return umoven(tcp, addr, len, laddr);
+#ifdef HAVE_MP_PROCFS
+       int fd = tcp->pfd_as;
+#else
+       int fd = tcp->pfd;
+#endif
+       /* Some systems (e.g. FreeBSD) can be upset if we read off the
+          end of valid memory,  avoid this by trying to read up
+          to page boundaries.  But we don't know what a page is (and
+          getpagesize(2) (if it exists) doesn't necessarily return
+          hardware page size).  Assume all pages >= 1024 (a-historical
+          I know) */
+
+       int page = 1024;        /* How to find this? */
+       int move = page - (addr & (page - 1));
+       int left = len;
+
+       lseek(fd, addr, SEEK_SET);
+
+       while (left) {
+               if (move > left) move = left;
+               if ((move = read(fd, laddr, move)) == -1)
+                       return left != len ? 0 : -1;
+               if (memchr (laddr, 0, move)) break;
+               left -= move;
+               laddr += move;
+               addr += move;
+               move = page;
+       }
 #else /* !USE_PROCFS */
        int started = 0;
        int pid = tcp->pid;
@@ -718,8 +733,8 @@ char *laddr;
 
                addr += sizeof(long), laddr += m, len -= m;
        }
-       return 0;
 #endif /* !USE_PROCFS */
+       return 0;
 }
 
 #ifdef LINUX