svn commit: r295771 - head/sys/netinet6
Michael Tuexen
tuexen at FreeBSD.org
Thu Feb 18 21:05:06 UTC 2016
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);
More information about the svn-src-all
mailing list