Date: Wed, 28 Jun 2006 15:17:00 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100207 for review Message-ID: <200606281517.k5SFH01v015337@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=100207 Change 100207 by jhb@jhb_mutex on 2006/06/28 15:16:02 - Add kern_getsockname() and kern_getpeername() and use them to eliminate some stackgap usage in svr4. Affected files ... .. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#29 edit .. //depot/projects/smpng/sys/kern/uipc_syscalls.c#78 edit .. //depot/projects/smpng/sys/sys/syscallsubr.h#33 edit Differences ... ==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#29 (text+ko) ==== @@ -992,7 +992,6 @@ struct sockaddr *skp; int sasize; struct svr4_strmcmd bnd; - struct bind_args ba; if (st == NULL) { DPRINTF(("ti_bind: bad file descriptor\n")); @@ -1012,7 +1011,7 @@ switch (st->s_family) { case AF_INET: - skp = &sain; + skp = (struct sockaddr *)&sain; sasize = sizeof(sain); if (bnd.offs == 0) @@ -1026,7 +1025,7 @@ break; case AF_LOCAL: - skp = &saun; + skp = (struct sockaddr *)&saun; sasize = sizeof(saun); if (bnd.offs == 0) goto error; @@ -1117,13 +1116,9 @@ struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat; struct svr4_strm *st = svr4_stream_get(fp); int error; - void *skp, *sup; - struct sockaddr_in sain; - struct sockaddr_un saun; + struct sockaddr *sa; + socklen_t sasize, oldsasize; struct svr4_strmcmd sc; - int sasize, oldsasize; - caddr_t sg; - int *lenp; DPRINTF(("svr4_stream_ti_ioctl\n")); @@ -1139,13 +1134,11 @@ switch (st->s_family) { case AF_INET: - skp = &sain; - sasize = sizeof(sain); + sasize = sizeof(struct sockaddr_in); break; case AF_LOCAL: - skp = &saun; - sasize = sizeof(saun); + sasize = sizeof(struct sockaddr_un); break; default: @@ -1153,25 +1146,14 @@ st->s_family)); return ENOSYS; } - - sg = stackgap_init(); - sup = stackgap_alloc(&sg, sasize); - lenp = stackgap_alloc(&sg, sizeof(*lenp)); - - if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) { - DPRINTF(("ti_ioctl: error copying out lenp\n")); - return error; - } + oldsasize = sasize; switch (cmd) { case SVR4_TI_GETMYNAME: DPRINTF(("TI_GETMYNAME\n")); { - struct getsockname_args ap; - ap.fdes = fd; - ap.asa = sup; - ap.alen = lenp; - if ((error = getsockname(td, &ap)) != 0) { + error = kern_getsockname(td, fd, &sa, &sasize); + if (error) { DPRINTF(("ti_ioctl: getsockname error\n")); return error; } @@ -1181,11 +1163,8 @@ case SVR4_TI_GETPEERNAME: DPRINTF(("TI_GETPEERNAME\n")); { - struct getpeername_args ap; - ap.fdes = fd; - ap.asa = sup; - ap.alen = lenp; - if ((error = getpeername(td, &ap)) != 0) { + error = kern_getpeername(td, fd, &sa, &sasize); + if (error) { DPRINTF(("ti_ioctl: getpeername error\n")); return error; } @@ -1204,36 +1183,27 @@ return ENOSYS; } - if ((error = copyin(sup, skp, sasize)) != 0) { - DPRINTF(("ti_ioctl: error copying in socket data\n")); - return error; + if (sasize < 0 || sasize > oldsasize) { + free(sa, M_SONAME); + return EINVAL; } - oldsasize = sasize; - - if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) { - DPRINTF(("ti_ioctl: error copying in socket size\n")); - return error; - } - - if (sasize < 0 || sasize > oldsasize) - return EINVAL; - switch (st->s_family) { case AF_INET: - sockaddr_to_netaddr_in(&sc, &sain); + sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa); skb.len = sasize; break; case AF_LOCAL: - sockaddr_to_netaddr_un(&sc, &saun); + sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa); skb.len = sasize + 4; break; default: + free(sa, M_SONAME); return ENOSYS; } - + free(sa, M_SONAME); if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) { DPRINTF(("ti_ioctl: error copying out socket data\n")); ==== //depot/projects/smpng/sys/kern/uipc_syscalls.c#78 (text+ko) ==== @@ -1459,48 +1459,64 @@ } */ *uap; int compat; { + struct sockaddr *sa; + socklen_t len; + int error; + + error = copyin(uap->alen, &len, sizeof(len)); + if (error) + return (error); + + error = kern_getsockname(td, uap->fdes, &sa, &len); + if (error) + return (error); + + if (len != 0) { +#ifdef COMPAT_OLDSOCK + if (compat) + ((struct osockaddr *)sa)->sa_family = sa->sa_family; +#endif + error = copyout(sa, uap->asa, (u_int)len); + } + free(sa, M_SONAME); + if (error == 0) + error = copyout(&len, uap->alen, sizeof(len)); + return (error); +} + +int +kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, + socklen_t *alen) +{ struct socket *so; - struct sockaddr *sa; struct file *fp; socklen_t len; int error; + if (*alen < 0) + return (EINVAL); + NET_LOCK_GIANT(); - error = getsock(td->td_proc->p_fd, uap->fdes, &fp, NULL); + error = getsock(td->td_proc->p_fd, fd, &fp, NULL); if (error) - goto done2; + goto done; so = fp->f_data; - error = copyin(uap->alen, &len, sizeof (len)); - if (error) - goto done1; - if (len < 0) { - error = EINVAL; - goto done1; - } - sa = 0; - error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa); + *sa = NULL; + error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa); if (error) goto bad; - if (sa == 0) { + if (*sa == NULL) len = 0; - goto gotnothing; - } - - len = MIN(len, sa->sa_len); -#ifdef COMPAT_OLDSOCK - if (compat) - ((struct osockaddr *)sa)->sa_family = sa->sa_family; -#endif - error = copyout(sa, uap->asa, (u_int)len); - if (error == 0) -gotnothing: - error = copyout(&len, uap->alen, sizeof (len)); + else + len = MIN(*alen, (*sa)->sa_len); + *alen = len; bad: - if (sa) - FREE(sa, M_SONAME); -done1: fdrop(fp, td); -done2: + if (error && *sa) { + free(*sa, M_SONAME); + *sa = NULL; + } +done: NET_UNLOCK_GIANT(); return (error); } @@ -1547,14 +1563,45 @@ } */ *uap; int compat; { + struct sockaddr *sa; + socklen_t len; + int error; + + error = copyin(uap->alen, &len, sizeof (len)); + if (error) + return (error); + + error = kern_getpeername(td, uap->fdes, &sa, &len); + if (error) + return (error); + + if (len != 0) { +#ifdef COMPAT_OLDSOCK + if (compat) + ((struct osockaddr *)sa)->sa_family = sa->sa_family; +#endif + error = copyout(sa, uap->asa, (u_int)len); + } + free(sa, M_SONAME); + if (error == 0) + error = copyout(&len, uap->alen, sizeof(len)); + return (error); +} + +int +kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, + socklen_t *alen) +{ struct socket *so; - struct sockaddr *sa; struct file *fp; socklen_t len; int error; + if (*alen < 0) + return (EINVAL); + NET_LOCK_GIANT(); - error = getsock(td->td_proc->p_fd, uap->fdes, &fp, NULL); + error = getsock(td->td_proc->p_fd, fd, &fp, NULL); if (error) goto done2; so = fp->f_data; @@ -1562,35 +1609,20 @@ error = ENOTCONN; goto done1; } - error = copyin(uap->alen, &len, sizeof (len)); - if (error) - goto done1; - if (len < 0) { - error = EINVAL; - goto done1; - } - sa = 0; - error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); + *sa = NULL; + error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa); if (error) goto bad; - if (sa == 0) { + if (*sa == NULL) len = 0; - goto gotnothing; + else + len = MIN(*alen, (*sa)->sa_len); + *alen = len; +bad: + if (error && *sa) { + free(*sa, M_SONAME); + *sa = NULL; } - len = MIN(len, sa->sa_len); -#ifdef COMPAT_OLDSOCK - if (compat) - ((struct osockaddr *)sa)->sa_family = - sa->sa_family; -#endif - error = copyout(sa, uap->asa, (u_int)len); - if (error) - goto bad; -gotnothing: - error = copyout(&len, uap->alen, sizeof (len)); -bad: - if (sa) - FREE(sa, M_SONAME); done1: fdrop(fp, td); done2: ==== //depot/projects/smpng/sys/sys/syscallsubr.h#33 (text+ko) ==== @@ -82,7 +82,11 @@ int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, enum uio_seg bufseg, int flags); int kern_getitimer(struct thread *, u_int, struct itimerval *); +int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, + socklen_t *alen); int kern_getrusage(struct thread *td, int who, struct rusage *rup); +int kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, + socklen_t *alen); int kern_getsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t *valsize); int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606281517.k5SFH01v015337>
