Date: Wed, 28 Jun 2006 19:30:25 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100226 for review Message-ID: <200606281930.k5SJUPGF042287@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100226 Change 100226 by jhb@jhb_mutex on 2006/06/28 19:30:07 - Use kern_connect(), kern_getpeername(), and kern_accept(). - Replace svr4_sendit() and svr4_recvit() with calls to kern_sendit() and kern_recvit() eliminating some more stackgap along the way. Affected files ... .. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#30 edit Differences ... ==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#30 (text+ko) ==== @@ -133,245 +133,6 @@ struct thread *); static int ti_bind(struct file *, int, struct svr4_strioctl *, struct thread *); -/* infrastructure */ -static int svr4_sendit(struct thread *td, int s, struct msghdr *mp, int flags); - -static int svr4_recvit(struct thread *td, int s, struct msghdr *mp, - caddr_t namelenp); - -/* <sigh> Ok, so we shouldn't use sendit() in uipc_syscalls.c because - * it isn't part of a "public" interface; We're supposed to use - * pru_sosend instead. Same goes for recvit()/pru_soreceive() for - * that matter. Solution: Suck sendit()/recvit() into here where we - * can do what we like. - * - * I hate code duplication. - * - * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though. - */ -static int -svr4_sendit(td, s, mp, flags) - register struct thread *td; - int s; - register struct msghdr *mp; - int flags; -{ - struct uio auio; - register struct iovec *iov; - register int i; - struct mbuf *control; - struct sockaddr *to; - int len, error; - struct socket *so; -#ifdef KTRACE - struct uio *ktruio = NULL; -#endif - - /* - * XXXRW: Instead of using fgetsock(), just rely on the file - * descriptor reference. - */ - if ((error = fgetsock(td, s, &so, NULL)) != 0) - return (error); - -#ifdef MAC - SOCK_LOCK(so); - error = mac_check_socket_send(td->td_ucred, so); - SOCK_UNLOCK(so); - if (error) - goto done1; -#endif - - auio.uio_iov = mp->msg_iov; - auio.uio_iovcnt = mp->msg_iovlen; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_rw = UIO_WRITE; - auio.uio_td = td; - auio.uio_offset = 0; /* XXX */ - auio.uio_resid = 0; - iov = mp->msg_iov; - for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if ((auio.uio_resid += iov->iov_len) < 0) { - error = EINVAL; - goto done1; - } - } - if (mp->msg_name) { - error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); - if (error) - goto done1; - } else { - to = 0; - } - if (mp->msg_control) { - if (mp->msg_controllen < sizeof(struct cmsghdr)) { - error = EINVAL; - goto bad; - } - error = sockargs(&control, mp->msg_control, - mp->msg_controllen, MT_CONTROL); - if (error) - goto bad; - } else { - control = 0; - } -#ifdef KTRACE - if (KTRPOINT(td, KTR_GENIO)) - ktruio = cloneuio(&auio); -#endif - len = auio.uio_resid; - error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, - flags, td); - if (error) { - if (auio.uio_resid != len && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - if (error == EPIPE) { - PROC_LOCK(td->td_proc); - psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); - } - } - if (error == 0) - td->td_retval[0] = len - auio.uio_resid; -#ifdef KTRACE - if (ktruio != NULL) { - ktruio->uio_resid = td->td_retval[0]; - ktrgenio(s, UIO_WRITE, ktruio, error); - } -#endif -bad: - if (to) - FREE(to, M_SONAME); -done1: - fputsock(so); - return (error); -} - -static int -svr4_recvit(td, s, mp, namelenp) - register struct thread *td; - int s; - register struct msghdr *mp; - caddr_t namelenp; -{ - struct uio auio; - register struct iovec *iov; - register int i; - int len, error; - struct mbuf *m, *control = 0; - caddr_t ctlbuf; - struct socket *so; - struct sockaddr *fromsa = 0; -#ifdef KTRACE - struct uio *ktruio = NULL; -#endif - - /* - * XXXRW: Instead of using fgetsock(), just rely on the file - * descriptor reference. - */ - if ((error = fgetsock(td, s, &so, NULL)) != 0) - return (error); - -#ifdef MAC - SOCK_LOCK(so); - error = mac_check_socket_receive(td->td_ucred, so); - SOCK_UNLOCK(so); - if (error) - goto done1; -#endif - - auio.uio_iov = mp->msg_iov; - auio.uio_iovcnt = mp->msg_iovlen; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_rw = UIO_READ; - auio.uio_td = td; - auio.uio_offset = 0; /* XXX */ - auio.uio_resid = 0; - iov = mp->msg_iov; - for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if ((auio.uio_resid += iov->iov_len) < 0) { - error = EINVAL; - goto done1; - } - } -#ifdef KTRACE - if (KTRPOINT(td, KTR_GENIO)) - ktruio = cloneuio(&auio); -#endif - len = auio.uio_resid; - error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, - (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, - &mp->msg_flags); - if (error) { - if (auio.uio_resid != len && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; - } -#ifdef KTRACE - if (ktruio != NULL) { - ktruio->uio_resid = len - auio.uio_resid; - ktrgenio(s, UIO_READ, ktruio, error); - } -#endif - if (error) - goto out; - td->td_retval[0] = len - auio.uio_resid; - if (mp->msg_name) { - len = mp->msg_namelen; - if (len <= 0 || fromsa == 0) - len = 0; - else { - /* save sa_len before it is destroyed by MSG_COMPAT */ - len = MIN(len, fromsa->sa_len); - error = copyout(fromsa, - (caddr_t)mp->msg_name, (unsigned)len); - if (error) - goto out; - } - mp->msg_namelen = len; - if (namelenp && - (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { - goto out; - } - } - if (mp->msg_control) { - len = mp->msg_controllen; - 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; - tocopy = len; - } - - if ((error = copyout((caddr_t)mtod(m, caddr_t), - ctlbuf, tocopy)) != 0) - goto out; - - ctlbuf += tocopy; - len -= tocopy; - m = m->m_next; - } - mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; - } -out: - if (fromsa) - FREE(fromsa, M_SONAME); - if (control) - m_freem(control); -done1: - fputsock(so); - return (error); -} - #ifdef DEBUG_SVR4 static void bufprint(u_char *, size_t); static int show_ioc(const char *, struct svr4_strioctl *); @@ -1702,11 +1463,10 @@ struct svr4_strmcmd sc; struct sockaddr_in sain; struct sockaddr_un saun; - void *skp, *sup; + struct sockaddr *sa; int sasize, *retval; struct svr4_strm *st; int error; - caddr_t sg; retval = td->td_retval; @@ -1780,9 +1540,10 @@ return EINVAL; } netaddr_to_sockaddr_in(&sain, &sc); - skp = &sain; + sa = (struct sockaddr *)&sain; sasize = sizeof(sain); - error = sain.sin_family != st->s_family; + if (sain.sin_family != st->s_family) + error = EINVAL; break; case AF_LOCAL: @@ -1796,11 +1557,12 @@ /* Maybe we've been given a device/inode pair */ dev_t *dev = SVR4_ADDROF(&sc); ino_t *ino = (ino_t *) &dev[1]; - skp = svr4_find_socket(td, fp, *dev, *ino); - if (skp == NULL) { - skp = &saun; + sa = (struct sockaddr *) + svr4_find_socket(td, fp, *dev, *ino); + if (sa == NULL) { + sa = (struct sockaddr *)&saun; /* I guess we have it by name */ - netaddr_to_sockaddr_un(skp, &sc); + netaddr_to_sockaddr_un(&saun, &sc); } sasize = sizeof(saun); } @@ -1812,22 +1574,11 @@ return ENOSYS; } - sg = stackgap_init(); - sup = stackgap_alloc(&sg, sasize); - - if ((error = copyout(skp, sup, sasize)) != 0) - return error; - switch (st->s_cmd = sc.cmd) { case SVR4_TI_CONNECT_REQUEST: /* connect */ { - struct connect_args co; - co.s = uap->fd; - co.name = (void *) sup; - co.namelen = (int) sasize; - - return connect(td, &co); + return (kern_connect(td, uap->fd, sa)); } case SVR4_TI_SENDTO_REQUEST: /* sendto */ @@ -1835,7 +1586,7 @@ struct msghdr msg; struct iovec aiov; - msg.msg_name = (caddr_t) sup; + msg.msg_name = sa; msg.msg_namelen = sasize; msg.msg_iov = &aiov; msg.msg_iovlen = 1; @@ -1843,12 +1594,8 @@ msg.msg_flags = 0; aiov.iov_base = dat.buf; aiov.iov_len = dat.len; -#if 0 - error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, - uio, 0, 0, 0, uio->uio_td); -#endif - error = svr4_sendit(td, uap->fd, &msg, - uap->flags); + error = kern_sendit(td, uap->fd, &msg, uap->flags, + NULL, UIO_USERSPACE); DPRINTF(("sendto_request error: %d\n", error)); *retval = 0; return error; @@ -1885,8 +1632,6 @@ struct svr4_sys_getmsg_args *uap; struct file *fp; { - struct getpeername_args ga; - struct accept_args aa; struct svr4_strbuf dat, ctl; struct svr4_strmcmd sc; int error, *retval; @@ -1894,14 +1639,13 @@ struct iovec aiov; struct sockaddr_in sain; struct sockaddr_un saun; - void *skp, *sup; - int sasize; + struct sockaddr *sa; + socklen_t sasize; struct svr4_strm *st; - int *flen; int fl; - caddr_t sg; retval = td->td_retval; + error = 0; FILE_LOCK_ASSERT(fp, MA_NOTOWNED); @@ -1947,12 +1691,10 @@ switch (st->s_family) { case AF_INET: - skp = &sain; sasize = sizeof(sain); break; case AF_LOCAL: - skp = &saun; sasize = sizeof(saun); break; @@ -1962,14 +1704,6 @@ return ENOSYS; } - sg = stackgap_init(); - sup = stackgap_alloc(&sg, sasize); - flen = (int *) stackgap_alloc(&sg, sizeof(*flen)); - - fl = sasize; - if ((error = copyout(&fl, flen, sizeof(fl))) != 0) - return error; - switch (st->s_cmd) { case SVR4_TI_CONNECT_REQUEST: DPRINTF(("getmsg: TI_CONNECT_REQUEST\n")); @@ -1993,18 +1727,12 @@ * a connect verification. */ - ga.fdes = uap->fd; - ga.asa = (void *) sup; - ga.alen = flen; - - if ((error = getpeername(td, &ga)) != 0) { + error = kern_getpeername(td, uap->fd, &sa, &sasize); + if (error) { DPRINTF(("getmsg: getpeername failed %d\n", error)); return error; } - if ((error = copyin(sup, skp, sasize)) != 0) - return error; - sc.cmd = SVR4_TI_CONNECT_REPLY; sc.pad[0] = 0x4; sc.offs = 0x18; @@ -2014,17 +1742,19 @@ switch (st->s_family) { case AF_INET: sc.len = sasize; - sockaddr_to_netaddr_in(&sc, &sain); + sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa); break; case AF_LOCAL: sc.len = sasize + 4; - sockaddr_to_netaddr_un(&sc, &saun); + sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa); break; default: + free(sa, M_SONAME); return ENOSYS; } + free(sa, M_SONAME); ctl.len = 40; dat.len = -1; @@ -2052,11 +1782,9 @@ /* * We are after a listen, so we try to accept... */ - aa.s = uap->fd; - aa.name = (void *) sup; - aa.anamelen = flen; - - if ((error = accept(td, &aa)) != 0) { + + error = kern_accept(td, uap->fd, &sa, &sasize, 0); + if (error) { DPRINTF(("getmsg: accept failed %d\n", error)); return error; } @@ -2065,9 +1793,6 @@ DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd)); - if ((error = copyin(sup, skp, sasize)) != 0) - return error; - sc.cmd = SVR4_TI_ACCEPT_REPLY; sc.offs = 0x18; sc.pad[0] = 0x0; @@ -2075,7 +1800,7 @@ switch (st->s_family) { case AF_INET: sc.pad[1] = 0x28; - sockaddr_to_netaddr_in(&sc, &sain); + sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)&sa); ctl.len = 40; sc.len = sasize; break; @@ -2089,8 +1814,10 @@ break; default: + free(sa, M_SONAME); return ENOSYS; } + free(sa, M_SONAME); dat.len = -1; fl = 0; @@ -2110,10 +1837,12 @@ switch (st->s_family) { case AF_INET: + sa = (struct sockaddr *)&sain; sockaddr_to_netaddr_in(&sc, &sain); break; case AF_LOCAL: + sa = (struct sockaddr *)&saun; sockaddr_to_netaddr_un(&sc, &saun); break; @@ -2121,7 +1850,7 @@ return ENOSYS; } - msg.msg_name = (caddr_t) sup; + msg.msg_name = sa; msg.msg_namelen = sasize; msg.msg_iov = &aiov; msg.msg_iovlen = 1; @@ -2130,16 +1859,14 @@ aiov.iov_len = dat.maxlen; msg.msg_flags = 0; - error = svr4_recvit(td, uap->fd, &msg, (caddr_t) flen); + error = kern_recvit(td, uap->fd, &msg, NULL, UIO_USERSPACE, + UIO_SYSSPACE, NULL); if (error) { DPRINTF(("getmsg: recvit failed %d\n", error)); return error; } - if ((error = copyin(msg.msg_name, skp, sasize)) != 0) - return error; - sc.cmd = SVR4_TI_RECVFROM_IND; switch (st->s_family) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606281930.k5SJUPGF042287>