Date: Thu, 18 Feb 2016 21:05:04 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295771 - head/sys/netinet6 Message-ID: <201602182105.u1IL54o2009728@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Thu Feb 18 21:05:04 2016 New Revision: 295771 URL: https://svnweb.freebsd.org/changeset/base/295771 Log: Fix reporting of mapped addressed in getpeername() and getsockname() for IPv6 SCTP sockets. This bugs were found because of an issue reported by PVS / D5245. Modified: head/sys/netinet6/sctp6_usrreq.c Modified: head/sys/netinet6/sctp6_usrreq.c ============================================================================== --- head/sys/netinet6/sctp6_usrreq.c Thu Feb 18 20:37:12 2016 (r295770) +++ head/sys/netinet6/sctp6_usrreq.c Thu Feb 18 21:05:04 2016 (r295771) @@ -1008,7 +1008,9 @@ sctp6_getaddr(struct socket *so, struct stcb = LIST_FIRST(&inp->sctp_asoc_list); if (stcb == NULL) { - goto notConn6; + SCTP_INP_RUNLOCK(inp); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); + return (ENOENT); } fnd = 0; sin_a6 = NULL; @@ -1025,7 +1027,9 @@ sctp6_getaddr(struct socket *so, struct } if ((!fnd) || (sin_a6 == NULL)) { /* punt */ - goto notConn6; + SCTP_INP_RUNLOCK(inp); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); + return (ENOENT); } vrf_id = inp->def_vrf_id; sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *) & net->ro, net, 0, vrf_id); @@ -1034,7 +1038,6 @@ sctp6_getaddr(struct socket *so, struct } } else { /* For the bound all case you get back 0 */ - notConn6: memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr)); } } else { @@ -1135,10 +1138,6 @@ sctp6_peeraddr(struct socket *so, struct static int sctp6_in6getaddr(struct socket *so, struct sockaddr **nam) { -#ifdef INET - struct sockaddr *addr; - -#endif struct in6pcb *inp6 = sotoin6pcb(so); int error; @@ -1150,19 +1149,21 @@ sctp6_in6getaddr(struct socket *so, stru error = sctp6_getaddr(so, nam); #ifdef INET if (error) { + struct sockaddr_in6 *sin6; + /* try v4 next if v6 failed */ error = sctp_ingetaddr(so, nam); if (error) { return (error); } - addr = *nam; - /* if I'm V6ONLY, convert it to v4-mapped */ - if (SCTP_IPV6_V6ONLY(inp6)) { - struct sockaddr_in6 sin6; - - in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6); - memcpy(addr, &sin6, sizeof(struct sockaddr_in6)); - } + SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); + if (sin6 == NULL) { + SCTP_FREE_SONAME(*nam); + return (ENOMEM); + } + in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6); + SCTP_FREE_SONAME(*nam); + *nam = (struct sockaddr *)sin6; } #endif return (error); @@ -1172,10 +1173,6 @@ sctp6_in6getaddr(struct socket *so, stru static int sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam) { -#ifdef INET - struct sockaddr *addr; - -#endif struct in6pcb *inp6 = sotoin6pcb(so); int error; @@ -1187,19 +1184,21 @@ sctp6_getpeeraddr(struct socket *so, str error = sctp6_peeraddr(so, nam); #ifdef INET if (error) { + struct sockaddr_in6 *sin6; + /* try v4 next if v6 failed */ error = sctp_peeraddr(so, nam); if (error) { return (error); } - addr = *nam; - /* if I'm V6ONLY, convert it to v4-mapped */ - if (SCTP_IPV6_V6ONLY(inp6)) { - struct sockaddr_in6 sin6; - - in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6); - memcpy(addr, &sin6, sizeof(struct sockaddr_in6)); - } + SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); + if (sin6 == NULL) { + SCTP_FREE_SONAME(*nam); + return (ENOMEM); + } + in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6); + SCTP_FREE_SONAME(*nam); + *nam = (struct sockaddr *)sin6; } #endif return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602182105.u1IL54o2009728>