From: John Hughes Date: Tue, 15 May 2001 14:53:43 +0000 (+0000) Subject: Don\'t run off end of memory in umovestr when USE_PROCFS X-Git-Tag: v4.5.18~1036 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa09c6b01ee425d419cdae4389fad0a06da489ef;p=strace Don\'t run off end of memory in umovestr when USE_PROCFS --- diff --git a/ChangeLog b/ChangeLog index 2d44a465..86c65dac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-05-15 John Hughes + + * 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 * configure.in: test for sys/nscsys.h, the non-stop clusters includes. diff --git a/util.c b/util.c index 19a24e48..52911424 100644 --- 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