Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern If an untraced process sleeps in recvmsg/sendmsg, t...



details:   https://anonhg.NetBSD.org/src/rev/37095a7822c1
branches:  trunk
changeset: 783560:37095a7822c1
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Dec 29 10:22:40 2012 +0000

description:
If an untraced process sleeps in recvmsg/sendmsg, the syscall does not
allocate an iov structure for ktrace. When tracing is then enabled
and the process wakes up, it crashes the kernel.

Undo the last commit which introduced this error path.

Avoid the mentioned kmem_alloc assertion by adding a sanity check analog
to similar code in sys_generic.c for I/O on file handles instead of
sockets.

This also causes the syscall to return EMSGSIZE if the msg_iovlen member
of the msg structure is less than or equal to 0, as defined in
recvmsg(2)/sendmsg(2).

diffstat:

 sys/kern/uipc_syscalls.c |  28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diffs (86 lines):

diff -r b1e6bb442e7e -r 37095a7822c1 sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c  Sat Dec 29 08:28:20 2012 +0000
+++ b/sys/kern/uipc_syscalls.c  Sat Dec 29 10:22:40 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_syscalls.c,v 1.156 2012/07/17 14:22:42 njoly Exp $        */
+/*     $NetBSD: uipc_syscalls.c,v 1.157 2012/12/29 10:22:40 mlelstv Exp $      */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.156 2012/07/17 14:22:42 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.157 2012/12/29 10:22:40 mlelstv Exp $");
 
 #include "opt_pipe.h"
 
@@ -547,6 +547,11 @@
        control = (mp->msg_flags & MSG_CONTROLMBUF) ? mp->msg_control : NULL;
        iovsz = mp->msg_iovlen * sizeof(struct iovec);
 
+       if (iovsz <= 0) {
+               error = EMSGSIZE;
+               goto bad;
+       }
+
        if (mp->msg_flags & MSG_IOVUSRSPACE) {
                if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
                        if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
@@ -604,7 +609,7 @@
                }
        }
 
-       if (ktrpoint(KTR_GENIO) && iovsz > 0) {
+       if (ktrpoint(KTR_GENIO)) {
                ktriov = kmem_alloc(iovsz, KM_SLEEP);
                memcpy(ktriov, auio.uio_iov, iovsz);
        }
@@ -634,10 +639,9 @@
                *retsize = len - auio.uio_resid;
 
 bad:
-       if (ktrpoint(KTR_GENIO)) {
+       if (ktriov != NULL) {
                ktrgeniov(s, UIO_WRITE, ktriov, *retsize, error);
-               if (ktriov != NULL)
-                       kmem_free(ktriov, iovsz);
+               kmem_free(ktriov, iovsz);
        }
 
        if (iov != aiov)
@@ -911,6 +915,11 @@
 
        iovsz = mp->msg_iovlen * sizeof(struct iovec);
 
+       if (iovsz <= 0) {
+               error = EMSGSIZE;
+               goto out;
+       }
+
        if (mp->msg_flags & MSG_IOVUSRSPACE) {
                if ((unsigned int)mp->msg_iovlen > UIO_SMALLIOV) {
                        if ((unsigned int)mp->msg_iovlen > IOV_MAX) {
@@ -948,7 +957,7 @@
                }
        }
 
-       if (ktrpoint(KTR_GENIO) && iovsz > 0) {
+       if (ktrpoint(KTR_GENIO)) {
                ktriov = kmem_alloc(iovsz, KM_SLEEP);
                memcpy(ktriov, auio.uio_iov, iovsz);
        }
@@ -964,10 +973,9 @@
                /* Some data transferred */
                error = 0;
 
-       if (ktrpoint(KTR_GENIO)) {
+       if (ktriov != NULL) {
                ktrgeniov(s, UIO_READ, ktriov, len, error);
-               if (ktriov != NULL)
-                       kmem_free(ktriov, iovsz);
+               kmem_free(ktriov, iovsz);
        }
 
        if (error != 0) {



Home | Main Index | Thread Index | Old Index