Module Name: src Committed By: martin Date: Thu Apr 21 15:20:17 UTC 2016
Modified Files: src/sys/compat/netbsd32 [netbsd-6]: netbsd32_socket.c Log Message: Pull up following revision(s) (requested by christos in ticket #1378): sys/compat/netbsd32/netbsd32_socket.c: revision 1.42 Memory leak, triggerable from an unprivileged user. To generate a diff of this commit: cvs rdiff -u -r1.39.2.2 -r1.39.2.3 src/sys/compat/netbsd32/netbsd32_socket.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/compat/netbsd32/netbsd32_socket.c diff -u src/sys/compat/netbsd32/netbsd32_socket.c:1.39.2.2 src/sys/compat/netbsd32/netbsd32_socket.c:1.39.2.3 --- src/sys/compat/netbsd32/netbsd32_socket.c:1.39.2.2 Sat Aug 18 22:01:40 2012 +++ src/sys/compat/netbsd32/netbsd32_socket.c Thu Apr 21 15:20:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_socket.c,v 1.39.2.2 2012/08/18 22:01:40 riz Exp $ */ +/* $NetBSD: netbsd32_socket.c,v 1.39.2.3 2016/04/21 15:20:17 martin Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.39.2.2 2012/08/18 22:01:40 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.39.2.3 2016/04/21 15:20:17 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -331,7 +331,7 @@ netbsd32_sendmsg(struct lwp *l, const st } */ struct msghdr msg; struct netbsd32_msghdr msg32; - struct iovec aiov[UIO_SMALLIOV], *iov; + struct iovec aiov[UIO_SMALLIOV], *iov = aiov; struct netbsd32_iovec *iov32; size_t iovsz; int error; @@ -346,6 +346,7 @@ netbsd32_sendmsg(struct lwp *l, const st error = copyin32_msg_control(l, &msg); if (error) return (error); + /* From here on, msg.msg_control is allocated */ } else { msg.msg_control = NULL; msg.msg_controllen = 0; @@ -353,23 +354,32 @@ netbsd32_sendmsg(struct lwp *l, const st iovsz = msg.msg_iovlen * sizeof(struct iovec); if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) { - if ((u_int)msg.msg_iovlen > IOV_MAX) - return (EMSGSIZE); + if ((u_int)msg.msg_iovlen > IOV_MAX) { + error = EMSGSIZE; + goto out; + } iov = kmem_alloc(iovsz, KM_SLEEP); - } else - iov = aiov; + } iov32 = NETBSD32PTR64(msg32.msg_iov); error = netbsd32_to_iovecin(iov32, iov, msg.msg_iovlen); if (error) - goto done; + goto out; msg.msg_iov = iov; error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval); -done: + /* msg.msg_control freed by do_sys_sendmsg() */ + if (iov != aiov) kmem_free(iov, iovsz); return (error); + +out: + if (iov != aiov) + kmem_free(iov, iovsz); + if (msg.msg_control) + m_free(msg.msg_control); + return error; } int