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