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/system.c b/system.c
index 7bbcdcd..a1c057e 100644
--- a/system.c
+++ b/system.c
@@ -1813,23 +1813,25 @@
 {
 	struct __sysctl_args info;
 	int *name;
+	unsigned long size;
+
 	if (umove (tcp, tcp->u_arg[0], &info) < 0)
 		return printargs(tcp);
 
-	name = malloc (sizeof (int) * info.nlen);
+	size = sizeof (int) * (unsigned long) info.nlen;
+	name = (size / sizeof (int) != info.nlen) ? NULL : malloc (size);
 	if (name == NULL ||
-	    umoven(tcp, (unsigned long) info.name,
-		   sizeof (int) * info.nlen, (char *) name) < 0) {
-		if (name != NULL)
-			free(name);
-		tprintf("{%p, %d, %p, %p, %p, %Zu}",
-			info.name, info.nlen, info.oldval, info.oldlenp,
-			info.newval, info.newlen);
+	    umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
+		free(name);
+		if (entering(tcp))
+			tprintf("{%p, %d, %p, %p, %p, %Zu}",
+				info.name, info.nlen, info.oldval,
+				info.oldlenp, info.newval, info.newlen);
 		return 0;
 	}
 
 	if (entering(tcp)) {
-		int cnt = 0;
+		int cnt = 0, max_cnt;
 
 		tprintf("{{");
 
@@ -1919,13 +1921,16 @@
 			goto out;
 		}
 	out:
-		while (cnt < info.nlen)
+		max_cnt = abbrev(tcp) ? max_strlen : info.nlen;
+		while (cnt < max_cnt)
 			tprintf(", %x", name[cnt++]);
+		if (cnt < info.nlen)
+			tprintf(", ...");
 		tprintf("}, %d, ", info.nlen);
 	} else {
 		size_t oldlen;
-		umove(tcp, (size_t)info.oldlenp, &oldlen);
-		if (info.nlen >= 2
+		if (umove(tcp, (size_t)info.oldlenp, &oldlen) >= 0
+		    && info.nlen >= 2
 		    && ((name[0] == CTL_KERN
 			 && (name[1] == KERN_OSRELEASE
 			     || name[1] == KERN_OSTYPE