summaryrefslogtreecommitdiff
path: root/stream.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-06-01 19:22:06 +0000
committerRoland McGrath <roland@redhat.com>2005-06-01 19:22:06 +0000
commitaa524c88c49814863cb7f19e5c8a8eeca6ce22fe (patch)
treea2990277e60e1f07e3ffee8e7d0fe0ff42944531 /stream.c
parentb422e0d47dd81daa7d7df359f1237c7aaea173cb (diff)
downloadstrace-aa524c88c49814863cb7f19e5c8a8eeca6ce22fe.tar.gz
strace-aa524c88c49814863cb7f19e5c8a8eeca6ce22fe.tar.bz2
strace-aa524c88c49814863cb7f19e5c8a8eeca6ce22fe.tar.xz
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
Deal with memory management issues. * defs.h (tprint_iov): Update prototype. * desc.c (sys_epoll_wait) [HAVE_SYS_EPOLL_H]: Do not allocate epoll_event array of arbitrary size on the stack, to avoid stack overflow. * file.c (print_xattr_val): Check for integer overflow during malloc size calculation, to avoid heap corruption. * io.c (tprint_iov) [HAVE_SYS_UIO_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Change iovec array handling to avoid heap memory allocation. * mem.c (get_nodes) [LINUX]: Check for integer overflow during size calculation and do not allocate array of arbitrary size on the stack, to avoid stack overflow. * net.c (printcmsghdr) [HAVE_SENDMSG]: Do not allocate array of arbitrary size on the stack, to avoid stack overflow. Do not trust cmsg.cmsg_len to avoid read beyond the end of allocated object. (printmsghdr) [HAVE_SENDMSG]: Update tprint_iov() usage. * process.c (sys_setgroups): Check for integer overflow during malloc size calculation, to avoid heap corruption. Change gid_t array handling to avoid heap memory allocation. (sys_getgroups): Likewise. (sys_setgroups32) [LINUX]: Likewise. (sys_getgroups32) [LINUX]: Likewise. * stream.c (sys_poll) [HAVE_SYS_POLL_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Change pollfd array handling to avoid heap memory allocation. * system.c (sys_sysctl) [LINUX]: Check for integer overflow during malloc size calculation, to avoid heap corruption. * util.c (dumpiov) [HAVE_SYS_UIO_H]: Check for integer overflow during malloc size calculation, to avoid heap corruption. Fixes RH#159196.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c96
1 files changed, 52 insertions, 44 deletions
diff --git a/stream.c b/stream.c
index 998fd8a..f01fe99 100644
--- a/stream.c
+++ b/stream.c
@@ -298,61 +298,69 @@ int
sys_poll(tcp)
struct tcb *tcp;
{
- struct pollfd *pollp;
+ struct pollfd fds;
+ unsigned nfds;
+ unsigned long size, start, cur, end, abbrev_end;
+ int failed = 0;
- if (exiting(tcp)) {
- int i;
- int nfds = tcp->u_arg[1];
+ if (entering(tcp))
+ return 0;
- if (nfds <= 0) {
- tprintf("%#lx, %d, %ld\n",
- tcp->u_arg[0], nfds, tcp->u_arg[2]);
- return 0;
+ nfds = tcp->u_arg[1];
+ size = sizeof(fds) * nfds;
+ start = tcp->u_arg[0];
+ end = start + size;
+ if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
+ tprintf("%#lx, %d, %ld",
+ tcp->u_arg[0], nfds, tcp->u_arg[2]);
+ return 0;
+ }
+ if (abbrev(tcp)) {
+ abbrev_end = start + max_strlen * sizeof(fds);
+ if (abbrev_end < start)
+ abbrev_end = end;
+ } else {
+ abbrev_end = end;
+ }
+ tprintf("[");
+ for (cur = start; cur < end; cur += sizeof(fds)) {
+ if (cur > start)
+ tprintf(", ");
+ if (cur >= abbrev_end) {
+ tprintf("...");
+ break;
}
- pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp));
- if (pollp == NULL) {
- fprintf(stderr, "sys_poll: no memory\n");
- tprintf("%#lx, %d, %ld",
- tcp->u_arg[0], nfds, tcp->u_arg[2]);
- return 0;
+ if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+ tprintf("?");
+ failed = 1;
+ break;
}
- if (umoven(tcp, tcp->u_arg[0],
- (nfds * sizeof(*pollp)), (char *) pollp) < 0) {
- tprintf("%#lx", tcp->u_arg[0]);
+ if (fds.fd < 0) {
+ tprintf("{fd=%d}", fds.fd);
+ continue;
}
- else {
- tprintf("[");
- for (i = 0; i < nfds; i++) {
- if (i)
- tprintf(", ");
- if (pollp[i].fd < 0) {
- tprintf("{fd=%d}", pollp[i].fd);
- continue;
- }
- tprintf("{fd=%d, events=", pollp[i].fd);
- printflags(pollflags, pollp[i].events,
- "POLL???");
- if (!syserror(tcp) && pollp[i].revents) {
- tprintf(", revents=");
- printflags(pollflags, pollp[i].revents,
- "POLL???");
- }
- tprintf("}");
- }
- tprintf("]");
+ tprintf("{fd=%d, events=", fds.fd);
+ printflags(pollflags, fds.events, "POLL???");
+ if (!syserror(tcp) && fds.revents) {
+ tprintf(", revents=");
+ printflags(pollflags, fds.revents, "POLL???");
}
- tprintf(", %d, ", nfds);
+ tprintf("}");
+ }
+ tprintf("]");
+ if (failed)
+ tprintf(" %#lx", start);
+ tprintf(", %d, ", nfds);
#ifdef INFTIM
- if (tcp->u_arg[2] == INFTIM)
- tprintf("INFTIM");
- else
+ if (tcp->u_arg[2] == INFTIM)
+ tprintf("INFTIM");
+ else
#endif
- tprintf("%ld", tcp->u_arg[2]);
- free(pollp);
- }
+ tprintf("%ld", tcp->u_arg[2]);
return 0;
}
+
#else /* !HAVE_SYS_POLL_H */
int
sys_poll(tcp)