From 299ff91b1458bc75885b085ba66a8d6e7fc8dc6a Mon Sep 17 00:00:00 2001 From: cgd Date: Tue, 26 Oct 1993 22:36:25 +0000 Subject: [PATCH] BSDI official patch #14: SUMMARY: Here is a patch for a kernel hang that can be provoked with a write or send of a negative amount. The talk program is capable of exercising this bug. This patch also includes a fix for a bug that caused data to be delivered to TCP in smaller chunks than desired, and which caused TCP to send a short packet when starting up. Finally, there is a bug fix for MSG_PEEK with an oobmark pending. --- sys/kern/uipc_socket.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 49f40659dfe3..9b4fb0c3cdaa 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)uipc_socket.c 7.28 (Berkeley) 5/4/91 - * $Id: uipc_socket.c,v 1.6 1993/09/08 21:12:49 mycroft Exp $ + * $Id: uipc_socket.c,v 1.7 1993/10/26 22:36:25 cgd Exp $ */ #include "param.h" @@ -332,6 +332,15 @@ sosend(so, addr, uio, top, control, flags) resid = uio->uio_resid; else resid = top->m_pkthdr.len; + /* + * In theory resid should be unsigned. + * However, space must be signed, as it might be less than 0 + * if we over-committed, and we must use a signed comparison + * of space and resid. On the other hand, a negative resid + * causes us to loop sending 0-length segments to the protocol. + */ + if (resid < 0) + return (EINVAL); dontroute = (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && (so->so_proto->pr_flags & PR_ATOMIC); @@ -403,7 +412,7 @@ restart: #ifdef MAPPED_MBUFS len = min(MCLBYTES, resid); #else - if (top == 0) { + if (atomic && top == 0) { len = min(MCLBYTES - max_hdr, resid); m->m_data += max_hdr; } else @@ -719,8 +728,11 @@ dontblock: so->so_state |= SS_RCVATMARK; break; } - } else + } else { offset += len; + if (offset == so->so_oobmark) + break; + } } if (flags & MSG_EOR) break;