Date: Fri, 7 Jul 2006 16:16:15 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100894 for review Message-ID: <200607071616.k67GGFAT035347@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100894 Change 100894 by jhb@jhb_mutex on 2006/07/07 16:15:44 accept1() had a bug in that tried to free 'name' in the uap->name == NULL case which resulted in garbage. Fix that and clean up accept1/kern_accept some more via the following: - Handle the uap->name == NULL case right up front in accept1() with a single call to kern_accept(). This also gets rid of the slight obfuscation of the 'sap' variable. - Move the COMPAT_OLDSOCK handling up into accept1() and out of kern_accept(). Affected files ... .. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#31 edit .. //depot/projects/smpng/sys/kern/uipc_syscalls.c#82 edit .. //depot/projects/smpng/sys/sys/syscallsubr.h#42 edit Differences ... ==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#31 (text+ko) ==== @@ -1783,7 +1783,7 @@ * We are after a listen, so we try to accept... */ - error = kern_accept(td, uap->fd, &sa, &sasize, 0); + error = kern_accept(td, uap->fd, &sa, &sasize); if (error) { DPRINTF(("getmsg: accept failed %d\n", error)); return error; ==== //depot/projects/smpng/sys/kern/uipc_syscalls.c#82 (text+ko) ==== @@ -296,46 +296,46 @@ } */ *uap; int compat; { - struct sockaddr *name, **sap; + struct sockaddr *name; socklen_t namelen; int error; - if (uap->name) { - error = copyin(uap->anamelen, &namelen, sizeof (namelen)); - if (error) - return (error); - sap = &name; - } else - sap = NULL; + if (uap->name == NULL) + return (kern_accept(td, uap->s, NULL, NULL)); + + error = copyin(uap->anamelen, &namelen, sizeof (namelen)); + if (error) + return (error); - error = kern_accept(td, uap->s, sap, &namelen, compat); + error = kern_accept(td, uap->s, &name, &namelen, compat); - if (uap->name) { - /* - * return a namelen of zero for older code which might - * ignore the return value from accept. - */ - if (error && name == NULL) { - (void) copyout(&namelen, - uap->anamelen, sizeof(*uap->anamelen)); - return (error); - } - if (error == 0) { - KASSERT(name != NULL, - ("%s: success but no sockaddr", __func__)); - error = copyout(name, uap->name, namelen); - } - if (error == 0) - error = copyout(&namelen, uap->anamelen, - sizeof(namelen)); - free(name, M_SONAME); + /* + * return a namelen of zero for older code which might + * ignore the return value from accept. + */ + if (error && name == NULL) { + (void) copyout(&namelen, + uap->anamelen, sizeof(*uap->anamelen)); + return (error); + } + if (error == 0 && name != NULL) { +#ifdef COMPAT_OLDSOCK + if (compat) + ((struct osockaddr *)name)->sa_family = + name->sa_family; +#endif + error = copyout(name, uap->name, namelen); } + if (error == 0) + error = copyout(&namelen, uap->anamelen, + sizeof(namelen)); + free(name, M_SONAME); return (error); } int kern_accept(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, int compat) + socklen_t *namelen) { struct filedesc *fdp; struct file *headfp, *nfp = NULL; @@ -459,11 +459,6 @@ /* check sa_len before it is destroyed */ if (*namelen > sa->sa_len) *namelen = sa->sa_len; -#ifdef COMPAT_OLDSOCK - if (compat) - ((struct osockaddr *)sa)->sa_family = - sa->sa_family; -#endif *name = sa; sa = NULL; } ==== //depot/projects/smpng/sys/sys/syscallsubr.h#42 (text+ko) ==== @@ -51,7 +51,7 @@ int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); int kern_accept(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, int compat); + socklen_t *namelen); int kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags); int kern_adjtime(struct thread *td, struct timeval *delta,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607071616.k67GGFAT035347>