mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-18 15:53:37 +00:00
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.
This commit is contained in:
parent
873e155c03
commit
6df7c000d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=295771
|
@ -1008,7 +1008,9 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
|
||||
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 sockaddr **addr)
|
|||
}
|
||||
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 sockaddr **addr)
|
|||
}
|
||||
} 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 sockaddr **addr)
|
|||
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, struct sockaddr **nam)
|
|||
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, struct sockaddr **nam)
|
|||
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, struct sockaddr **nam)
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue