From louie@whizzo.transsys.com  Tue May  7 21:54:33 1996
Received: from whizzo.transsys.com (whizzo.TransSys.COM [144.202.42.10])
          by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id VAA22798
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 7 May 1996 21:54:31 -0700 (PDT)
Received: (from louie@localhost) by whizzo.transsys.com (8.7.5/8.7.3) id AAA06859; Wed, 8 May 1996 00:54:29 -0400 (EDT)
Message-Id: <199605080454.AAA06859@whizzo.transsys.com>
Date: Wed, 8 May 1996 00:54:29 -0400 (EDT)
From: Louis Mamakos <louie@TransSys.COM>
Reply-To: louie@TransSys.COM
To: FreeBSD-gnats-submit@freebsd.org
Subject: Broken support in recvmsg(2) for more than one item of	control information
X-Send-Pr-Version: 3.2

>Number:         1178
>Category:       kern
>Synopsis:       Broken support in recvmsg(2) for more than one item of	control information
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    wollman
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May  7 22:00:01 PDT 1996
>Closed-Date:    Thu May 9 13:47:15 PDT 1996
>Last-Modified:  Thu May  9 13:47:43 PDT 1996
>Originator:     Louis Mamakos
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
>Environment:

	When using a the recvmsg(2) system call, it is possible to
return `control' information which is structured as a self-describing
unit of data.  The interface accomodates returning more than one
instance of control information at a time (descriptor access rights,
destination interface address, etc).

>Description:

	Though more than one instance of control information can be
carried in the socket abstraction, the implementation of the recvmsg()
system call will return only the first instance, discarding the
remainder.

>How-To-Repeat:

	Inspection.

>Fix:
	Diffs applied to recent -current kernels.  I've been running
this code for two weeks now.  An updated xntpd is using this code
regularlly.

Index: kern/uipc_syscalls.c
===================================================================
RCS file: /usr/local/FreeBSD/cvs/CVSROOT/../src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.16
diff -u -r1.16 uipc_syscalls.c
--- uipc_syscalls.c	1996/03/11 15:37:33	1.16
+++ uipc_syscalls.c	1996/04/10 05:29:08
@@ -636,7 +636,8 @@
 	register struct iovec *iov;
 	register int i;
 	int len, error;
-	struct mbuf *from = 0, *control = 0;
+	struct mbuf *m, *from = 0, *control = 0;
+	caddr_t ctlbuf;
 #ifdef KTRACE
 	struct iovec *ktriov = NULL;
 #endif
@@ -735,17 +736,29 @@
 		}
 #endif
 		len = mp->msg_controllen;
-		if (len <= 0 || control == 0)
-			len = 0;
-		else {
-			if (len >= control->m_len)
-				len = control->m_len;
-			else
+		m = control;
+		mp->msg_controllen = 0;
+		ctlbuf = (caddr_t) mp->msg_control;
+
+		while (m && len > 0) {
+			unsigned int tocopy;
+
+			if (len >= m->m_len) 
+				tocopy = m->m_len;
+			else {
 				mp->msg_flags |= MSG_CTRUNC;
-			error = copyout((caddr_t)mtod(control, caddr_t),
-			    (caddr_t)mp->msg_control, (unsigned)len);
+				tocopy = len;
+			}
+		
+			if (error = copyout((caddr_t)mtod(m, caddr_t),
+					ctlbuf, tocopy))
+				goto out;
+
+			ctlbuf += tocopy;
+			len -= tocopy;
+			m = m->m_next;
 		}
-		mp->msg_controllen = len;
+		mp->msg_controllen = ctlbuf - mp->msg_control;
 	}
 out:
 	if (from)



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->wollman 
Responsible-Changed-By: wollman 
Responsible-Changed-When: Wed May 8 08:38:45 PDT 1996 
Responsible-Changed-Why:  
my area 
State-Changed-From-To: open->closed 
State-Changed-By: wollman 
State-Changed-When: Thu May 9 13:47:15 PDT 1996 
State-Changed-Why:  
Patch accepted. 
>Unformatted:
