Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 May 1996 00:54:29 -0400 (EDT)
From:      Louis Mamakos <louie@TransSys.COM>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/1178: Broken support in recvmsg(2) for more than one item of	control information
Message-ID:  <199605080454.AAA06859@whizzo.transsys.com>
Resent-Message-ID: <199605080500.WAA23180@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May  7 22:00:01 PDT 1996
>Last-Modified:
>Originator:     Louis Mamakos
>Organization:
>Release:        FreeBSD 2.2-CURRENT i386
>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)



>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605080454.AAA06859>