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>