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.
diff --git a/stream.c b/stream.c
index 998fd8a..f01fe99 100644
--- a/stream.c
+++ b/stream.c
@@ -298,61 +298,69 @@
 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;
-		}
-		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, tcp->u_arg[0],
-			   (nfds * sizeof(*pollp)), (char *) pollp) < 0) {
-			tprintf("%#lx", tcp->u_arg[0]);
-		}
-		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(", %d, ", nfds);
-#ifdef INFTIM
-		if (tcp->u_arg[2] == INFTIM)
-			tprintf("INFTIM");
-		else
-#endif
-			tprintf("%ld", tcp->u_arg[2]);
-		free(pollp);
+	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;
+		}
+		if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+			tprintf("?");
+			failed = 1;
+			break;
+		}
+		if (fds.fd < 0) {
+			tprintf("{fd=%d}", fds.fd);
+			continue;
+		}
+		tprintf("{fd=%d, events=", fds.fd);
+		printflags(pollflags, fds.events, "POLL???");
+		if (!syserror(tcp) && fds.revents) {
+			tprintf(", revents=");
+			printflags(pollflags, fds.revents, "POLL???");
+		}
+		tprintf("}");
+	}
+	tprintf("]");
+	if (failed)
+		tprintf(" %#lx", start);
+	tprintf(", %d, ", nfds);
+#ifdef INFTIM
+	if (tcp->u_arg[2] == INFTIM)
+		tprintf("INFTIM");
+	else
+#endif
+		tprintf("%ld", tcp->u_arg[2]);
 	return 0;
 }
 
+
 #else /* !HAVE_SYS_POLL_H */
 int
 sys_poll(tcp)